aboutsummaryrefslogtreecommitdiff
path: root/lib/libzfs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzfs')
-rw-r--r--lib/libzfs/.gitignore1
-rw-r--r--lib/libzfs/Makefile.am78
-rw-r--r--lib/libzfs/THIRDPARTYLICENSE.openssl127
-rw-r--r--lib/libzfs/THIRDPARTYLICENSE.openssl.descrip1
-rw-r--r--lib/libzfs/libzfs.abi10281
-rw-r--r--lib/libzfs/libzfs.pc.in14
-rw-r--r--lib/libzfs/libzfs.suppr13
-rw-r--r--lib/libzfs/libzfs_changelist.c805
-rw-r--r--lib/libzfs/libzfs_config.c455
-rw-r--r--lib/libzfs/libzfs_crypto.c1831
-rw-r--r--lib/libzfs/libzfs_dataset.c5675
-rw-r--r--lib/libzfs/libzfs_diff.c830
-rw-r--r--lib/libzfs/libzfs_impl.h242
-rw-r--r--lib/libzfs/libzfs_import.c438
-rw-r--r--lib/libzfs/libzfs_iter.c655
-rw-r--r--lib/libzfs/libzfs_mount.c1468
-rw-r--r--lib/libzfs/libzfs_pool.c5763
-rw-r--r--lib/libzfs/libzfs_sendrecv.c5647
-rw-r--r--lib/libzfs/libzfs_status.c537
-rw-r--r--lib/libzfs/libzfs_util.c2462
-rw-r--r--lib/libzfs/os/freebsd/libzfs_compat.c369
-rw-r--r--lib/libzfs/os/freebsd/libzfs_zmount.c137
-rw-r--r--lib/libzfs/os/linux/libzfs_mount_os.c431
-rw-r--r--lib/libzfs/os/linux/libzfs_pool_os.c352
-rw-r--r--lib/libzfs/os/linux/libzfs_util_os.c275
25 files changed, 0 insertions, 38887 deletions
diff --git a/lib/libzfs/.gitignore b/lib/libzfs/.gitignore
deleted file mode 100644
index 9336a5c00b46..000000000000
--- a/lib/libzfs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/libzfs.pc
diff --git a/lib/libzfs/Makefile.am b/lib/libzfs/Makefile.am
deleted file mode 100644
index 5f8963dccd1a..000000000000
--- a/lib/libzfs/Makefile.am
+++ /dev/null
@@ -1,78 +0,0 @@
-libzfs_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS)
-libzfs_la_CFLAGS += $(LIBCRYPTO_CFLAGS) $(ZLIB_CFLAGS)
-libzfs_la_CFLAGS += -fvisibility=hidden
-
-lib_LTLIBRARIES += libzfs.la
-CPPCHECKTARGETS += libzfs.la
-
-dist_libzfs_la_SOURCES = \
- %D%/libzfs_impl.h \
- %D%/libzfs_changelist.c \
- %D%/libzfs_config.c \
- %D%/libzfs_crypto.c \
- %D%/libzfs_dataset.c \
- %D%/libzfs_diff.c \
- %D%/libzfs_import.c \
- %D%/libzfs_iter.c \
- %D%/libzfs_mount.c \
- %D%/libzfs_pool.c \
- %D%/libzfs_sendrecv.c \
- %D%/libzfs_status.c \
- %D%/libzfs_util.c
-
-if BUILD_FREEBSD
-dist_libzfs_la_SOURCES += \
- %D%/os/freebsd/libzfs_compat.c \
- %D%/os/freebsd/libzfs_zmount.c
-endif
-
-if BUILD_LINUX
-dist_libzfs_la_SOURCES += \
- %D%/os/linux/libzfs_mount_os.c \
- %D%/os/linux/libzfs_pool_os.c \
- %D%/os/linux/libzfs_util_os.c
-endif
-
-nodist_libzfs_la_SOURCES = \
- module/zcommon/cityhash.c \
- module/zcommon/zfeature_common.c \
- module/zcommon/zfs_comutil.c \
- module/zcommon/zfs_deleg.c \
- module/zcommon/zfs_fletcher.c \
- module/zcommon/zfs_fletcher_aarch64_neon.c \
- module/zcommon/zfs_fletcher_avx512.c \
- module/zcommon/zfs_fletcher_intel.c \
- module/zcommon/zfs_fletcher_sse.c \
- module/zcommon/zfs_fletcher_superscalar.c \
- module/zcommon/zfs_fletcher_superscalar4.c \
- module/zcommon/zfs_namecheck.c \
- module/zcommon/zfs_prop.c \
- module/zcommon/zfs_valstr.c \
- module/zcommon/zpool_prop.c \
- module/zcommon/zprop_common.c
-
-libzfs_la_LIBADD = \
- libshare.la \
- libzfs_core.la \
- libnvpair.la \
- libzutil.la \
- libuutil.la
-
-libzfs_la_LIBADD += -lrt -lm $(LIBCRYPTO_LIBS) $(ZLIB_LIBS) $(LIBFETCH_LIBS) $(LTLIBINTL)
-
-libzfs_la_LDFLAGS = -pthread
-
-if !ASAN_ENABLED
-libzfs_la_LDFLAGS += -Wl,-z,defs
-endif
-
-if BUILD_FREEBSD
-libzfs_la_LIBADD += -lutil -lgeom
-endif
-
-libzfs_la_LDFLAGS += -version-info 6:0:0
-
-pkgconfig_DATA += %D%/libzfs.pc
-
-dist_noinst_DATA += %D%/libzfs.abi %D%/libzfs.suppr
-dist_noinst_DATA += %D%/THIRDPARTYLICENSE.openssl %D%/THIRDPARTYLICENSE.openssl.descrip
diff --git a/lib/libzfs/THIRDPARTYLICENSE.openssl b/lib/libzfs/THIRDPARTYLICENSE.openssl
deleted file mode 100644
index 92c9e196a318..000000000000
--- a/lib/libzfs/THIRDPARTYLICENSE.openssl
+++ /dev/null
@@ -1,127 +0,0 @@
-
- LICENSE ISSUES
- ==============
-
- The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
- the OpenSSL License and the original SSLeay license apply to the toolkit.
- See below for the actual license texts. Actually both licenses are BSD-style
- Open Source licenses. In case of any license issues related to OpenSSL
- please contact openssl-core@openssl.org.
-
- OpenSSL License
- ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2008 The OpenSSL Project. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * 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 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the routines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
diff --git a/lib/libzfs/THIRDPARTYLICENSE.openssl.descrip b/lib/libzfs/THIRDPARTYLICENSE.openssl.descrip
deleted file mode 100644
index a9125ea21122..000000000000
--- a/lib/libzfs/THIRDPARTYLICENSE.openssl.descrip
+++ /dev/null
@@ -1 +0,0 @@
-PBKDF2 IMPLEMENTATION
diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi
deleted file mode 100644
index f988d27a286a..000000000000
--- a/lib/libzfs/libzfs.abi
+++ /dev/null
@@ -1,10281 +0,0 @@
-<abi-corpus version='2.0' architecture='elf-amd-x86_64' soname='libzfs.so.6'>
- <elf-needed>
- <dependency name='libzfs_core.so.3'/>
- <dependency name='libnvpair.so.3'/>
- <dependency name='libunwind.so.8'/>
- <dependency name='libuuid.so.1'/>
- <dependency name='libblkid.so.1'/>
- <dependency name='libudev.so.1'/>
- <dependency name='libuutil.so.3'/>
- <dependency name='libm.so.6'/>
- <dependency name='libcrypto.so.3'/>
- <dependency name='libz.so.1'/>
- <dependency name='libc.so.6'/>
- <dependency name='ld-linux-x86-64.so.2'/>
- </elf-needed>
- <elf-function-symbols>
- <elf-symbol name='_sol_getmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_char' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_char_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_int_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_long' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_long_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_ptr_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_short' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_add_short_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_uchar_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_uint_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_ulong_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_and_ushort_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_cas_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_clear_long_excl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_uchar_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_uint_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_ulong_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_dec_ushort_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_uchar_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_uint_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_ulong_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_inc_ushort_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_uchar_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_uint_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_ulong_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_or_ushort_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_set_long_excl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_16_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_32_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_64_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_8_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_char' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_char_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_int_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_long' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_long_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_ptr_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_short' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_sub_short_nv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_uchar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='atomic_swap_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_destroy_nodes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_first' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_insert_here' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_is_empty' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_last' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_nearest' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_numnodes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_swap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_update_gt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_update_lt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='avl_walk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='bookmark_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='cityhash1' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='cityhash2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='cityhash3' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='cityhash4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='color_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='color_start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='dataset_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='dataset_nestcheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_alloc_and_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_alloc_and_read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_err_check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_rescan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_use_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='efi_write' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='entity_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_2_byteswap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_2_incremental_byteswap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_2_incremental_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_2_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_byteswap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_impl_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_incremental_byteswap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_incremental_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_native_varsize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fsleep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='get_dataset_depth' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='getprop_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='getzoneid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='is_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='is_mpath_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libpc_error_description' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libspl_assertf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libspl_backtrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libspl_set_assert_ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_add_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_envvar_is_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_errno' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_error_action' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_error_description' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_error_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_free_str_array' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_cache' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_mnttab_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_print_on_error' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_run_process' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_run_process_get_stdout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_run_process_get_stdout_nopath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_insert_after' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_insert_before' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_insert_head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_insert_tail' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_is_empty' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_link_active' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_link_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_link_replace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_move_tail' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_prev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_remove_head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_remove_tail' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='list_tail' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='membar_consumer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='membar_enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='membar_exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='membar_producer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='membar_sync' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='mkdirp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='mountpoint_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='permset_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='pool_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='print_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='printf_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_commit_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_disable_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_enable_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_errorstr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_is_shared' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_validate_shareopts' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='snapshot_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='spl_pagesize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='strlcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='strlcpy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_abandon' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_dispatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_member' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_resume' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_suspend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_suspended' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='tpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='update_vdev_config_dev_strs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='update_vdev_config_dev_sysfs_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='use_color' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_expand_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_default_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_get_table' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_get_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_readonly' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_string_to_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_user' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='vdev_prop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zcmd_print_json' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_depends_on' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_is_supported' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_is_valid_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_lookup_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_lookup_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_adjust_mount_options' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_allocatable_devs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_append_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_basename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_bookmark_exists' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_clone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_close' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_commit_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_component_namecheck' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_create_ancestors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_attempt_load_keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_clone_check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_get_encryption_root' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_load_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_rewrap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_crypto_unload_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dataset_exists' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dataset_name_hidden' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_deleg_canonicalize_perm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_deleg_verify_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_deleg_whokey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_destroy_snaps' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_destroy_snaps_nvl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_destroy_snaps_nvl_os' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dev_flush' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dev_is_dm' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dev_is_whole_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_device_get_devid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_device_get_physical' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_dirnamelen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_expand_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_foreach_mountpoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_all_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_clones_nvl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_enclosure_sysfs_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_fsacl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_holds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_pool_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_pool_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_recvd_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_underlying_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_underlying_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_get_user_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_handle_dup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_hold' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_hold_nvl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_ioctl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_is_encrypted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_is_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_is_shared' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_isnumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_bookmarks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_bookmarks_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_children' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_children_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_dependents' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_dependents_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_filesystems' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_filesystems_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_mounted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_root' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapshots' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapshots_sorted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapshots_sorted_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapshots_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapspec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_iter_snapspec_v2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_mod_supported' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_mount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_mount_at' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_mount_delegation_check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_name_valid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_nicebytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_nicenum' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_nicenum_format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_niceraw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_nicestrtonum' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_nicetime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_open' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_parent_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_parse_mount_options' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_path_to_zhandle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_promote' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_default_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_delegatable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_encryption_key_param' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_recvd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_table' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_userquota' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_userquota_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_written' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_get_written_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_inherit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_inheritable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_is_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_readonly' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_set_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_set_list_flags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_setonce' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_string_to_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_user' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_userquota' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_valid_for_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_valid_keylocation' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_visible' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prop_written' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_prune_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_receive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_refresh_properties' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_rename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_resolve_shortname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_rollback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_save_arguments' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send_progress' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send_resume' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send_resume_token_to_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_send_saved' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_set_fsacl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_setproctitle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_setproctitle_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_show_diffs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_smb_acl_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_smb_acl_purge' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_smb_acl_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_smb_acl_rename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_snapshot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_snapshot_nvl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_spa_version' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_spa_version_map' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_special_devs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_standard_error' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_strcmp_pathname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_strip_partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_strip_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_truncate_shares' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_tunable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_type_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_unmount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_unmountall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_unshare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_unshareall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_userns' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_userspace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valid_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_flag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_flag_bits' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_flag_pairs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_priority' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_stage' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_stage_bits' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_stage_pairs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_valstr_zio_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_version_kernel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_version_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_version_print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_version_userland' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_zpl_version_map' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_add_propname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_checkpoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_clear_label' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_close' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_collect_leaves' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_collect_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_ddt_prune' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_default_search_paths' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_disable_datasets' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_disable_datasets_os' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_disable_volume_os' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_discard_checkpoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_disk_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_dump_ddt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_enable_datasets' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_events_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_events_next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_events_seek' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_expand_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_explain_recover' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_export' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_export_force' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_feature_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_find_config' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_find_parent_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_find_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_find_vdev_by_physpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_free_handles' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_all_vdev_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_config' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_errlog' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_features' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_history' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_load_policy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_prop_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_state_str' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_userprop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_get_vdev_prop_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_getenv_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_history_unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_import_props' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_import_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_in_use' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_initialize_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_initialize_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_is_draid_spare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_label_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_label_disk_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_load_compat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_log_history' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_obj_to_path' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_obj_to_path_ds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_open' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_open_canfail' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_pool_state_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prefetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prepare_and_label_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prepare_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_default_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_feature' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_get_feature' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_get_table' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_get_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_readonly' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_setonce' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_string_to_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_unsupported' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_prop_vdev' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_props_refresh' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_read_label' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_refresh_stats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_refresh_stats_from_handle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_reguid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_reopen_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_scan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_scan_range' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_search_import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_set_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_set_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_set_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_set_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_skip_pool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_state_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_sync_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_trim' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_trim_one' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_upgrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_attach' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_degrade' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_detach' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_fault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_indirect_size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_offline' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_online' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_path_to_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_remove' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_remove_cancel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_remove_wanted' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_script_alloc_env' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_script_free_env' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_set_removed_state' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_collect_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_free_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_get_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_iter_common' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_nvlist_one_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_print_one_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_register_hidden' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_register_impl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_register_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_register_number' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_register_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_string_to_index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_valid_char' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_valid_for_type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zprop_width' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zvol_volsize_to_reservation' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- </elf-function-symbols>
- <elf-variable-symbols>
- <elf-symbol name='efi_debug' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_abd_ops' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_avx2_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_avx512bw_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_avx512f_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_sse2_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_ssse3_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_superscalar4_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='spa_feature_table' size='2632' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_deleg_perm_tab' size='544' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_max_dataset_nesting' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- <elf-symbol name='zfs_userquota_prop_prefixes' size='96' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
- </elf-variable-symbols>
- <abi-instr address-size='64' path='lib/libefi/rdwr_efi.c' language='LANG_C99'>
- <typedef-decl name='uInt' type-id='f0981eeb' id='09110a74'/>
- <var-decl name='efi_debug' type-id='95e97e5e' mangled-name='efi_debug' visibility='default' elf-symbol-id='efi_debug'/>
- <function-decl name='uuid_generate' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='cf536864'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uuid_is_null' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='354f7eb9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='crc32' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5bbcce85'/>
- <parameter type-id='e8cb3e0e'/>
- <parameter type-id='09110a74'/>
- <return type-id='5bbcce85'/>
- </function-decl>
- <function-decl name='efi_err_check' mangled-name='efi_err_check' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_err_check'>
- <parameter type-id='0d8119a8' name='vtoc'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libshare/libshare.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='b99c00c9' size-in-bits='128' id='2d6895a3'>
- <subrange length='2' type-id='7359adad' id='52efc4ef'/>
- </array-type-def>
- <var-decl name='sa_protocol_names' type-id='2d6895a3' mangled-name='sa_protocol_names' visibility='default' elf-symbol-id='sa_protocol_names'/>
- <type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libshare/nfs.c' language='LANG_C99'>
- <function-decl name='rename' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='memchr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='flock' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fchmod' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='e1c52942'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='mkdir' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='e1c52942'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libshare/os/linux/nfs.c' language='LANG_C99'>
- <class-decl name='sa_share_impl' size-in-bits='192' is-struct='yes' visibility='default' id='72b09bf8'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='sa_zfsname' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='sa_mountpoint' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='sa_shareopts' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='sa_share_impl_t' type-id='946a2c6b' id='a48b47d0'/>
- <class-decl name='sa_fstype_t' size-in-bits='384' is-struct='yes' naming-typedef-id='639af739' visibility='default' id='944afa86'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='enable_share' type-id='2f78a9c1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='disable_share' type-id='2f78a9c1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='is_shared' type-id='81020bc2' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='validate_shareopts' type-id='f194a8fb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='commit_shares' type-id='797ee7da' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='truncate_shares' type-id='5d51038b' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='sa_fstype_t' type-id='944afa86' id='639af739'/>
- <qualified-type-def type-id='639af739' const='yes' id='d19dbca9'/>
- <qualified-type-def type-id='72b09bf8' const='yes' id='484950e3'/>
- <pointer-type-def type-id='484950e3' size-in-bits='64' id='946a2c6b'/>
- <pointer-type-def type-id='276427e1' size-in-bits='64' id='1db260e5'/>
- <qualified-type-def type-id='1db260e5' const='yes' id='797ee7da'/>
- <pointer-type-def type-id='5113b296' size-in-bits='64' id='70487b28'/>
- <qualified-type-def type-id='70487b28' const='yes' id='f194a8fb'/>
- <pointer-type-def type-id='c13578bc' size-in-bits='64' id='fa1f29ce'/>
- <qualified-type-def type-id='fa1f29ce' const='yes' id='2f78a9c1'/>
- <pointer-type-def type-id='723e6cf2' size-in-bits='64' id='1d99e49c'/>
- <pointer-type-def type-id='86373eb1' size-in-bits='64' id='f337456d'/>
- <qualified-type-def type-id='f337456d' const='yes' id='81020bc2'/>
- <qualified-type-def type-id='953b12f8' const='yes' id='5d51038b'/>
- <var-decl name='libshare_nfs_type' type-id='d19dbca9' visibility='default'/>
- <function-decl name='nfs_escape_mountpoint' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9b23c9ad'/>
- <parameter type-id='37e3bd22'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nfs_is_shared_impl' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='a48b47d0'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='nfs_toggle_share' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='a48b47d0'/>
- <parameter type-id='1d99e49c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nfs_reset_shares' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-type size-in-bits='64' id='276427e1'>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='5113b296'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='c13578bc'>
- <parameter type-id='a48b47d0'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='723e6cf2'>
- <parameter type-id='a48b47d0'/>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='86373eb1'>
- <parameter type-id='a48b47d0'/>
- <return type-id='c19b74c3'/>
- </function-type>
- <function-type size-in-bits='64' id='ee076206'>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libshare/os/linux/smb.c' language='LANG_C99'>
- <var-decl name='libshare_smb_type' type-id='d19dbca9' visibility='default'/>
- <function-decl name='__fgets_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='e75a27e9'/>
- <return type-id='26a90f95'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/assert.c' language='LANG_C99'>
- <function-decl name='libspl_backtrace' mangled-name='libspl_backtrace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_backtrace'>
- <parameter type-id='95e97e5e'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='gettid' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='3629bad8'/>
- </function-decl>
- <function-decl name='prctl' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
- <parameter type-id='c19b74c3' name='val'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/atomic.c' language='LANG_C99'>
- <typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
- <typedef-decl name='__int8_t' type-id='28577a57' id='2171a512'/>
- <qualified-type-def type-id='149c6638' volatile='yes' id='5120c5f7'/>
- <pointer-type-def type-id='5120c5f7' size-in-bits='64' id='93977ae7'/>
- <qualified-type-def type-id='b96825af' volatile='yes' id='84ff7d66'/>
- <pointer-type-def type-id='84ff7d66' size-in-bits='64' id='aa323ea4'/>
- <qualified-type-def type-id='ee1f298e' volatile='yes' id='6f7e09cb'/>
- <pointer-type-def type-id='6f7e09cb' size-in-bits='64' id='64698d33'/>
- <function-decl name='atomic_inc_8' mangled-name='atomic_inc_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_inc_16' mangled-name='atomic_inc_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_16'>
- <parameter type-id='93977ae7' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_inc_32' mangled-name='atomic_inc_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_32'>
- <parameter type-id='3a147f31' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_inc_ulong' mangled-name='atomic_inc_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_dec_8' mangled-name='atomic_dec_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_dec_16' mangled-name='atomic_dec_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_16'>
- <parameter type-id='93977ae7' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_dec_32' mangled-name='atomic_dec_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_32'>
- <parameter type-id='3a147f31' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_dec_ulong' mangled-name='atomic_dec_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_add_ptr' mangled-name='atomic_add_ptr' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_ptr'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='79a0948f' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_add_8' mangled-name='atomic_add_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='ee31ee44' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_add_16' mangled-name='atomic_add_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='23bd8cb5' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_add_32' mangled-name='atomic_add_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_32'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='3ff5601b' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_sub_ptr' mangled-name='atomic_sub_ptr' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_ptr'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='79a0948f' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_sub_8' mangled-name='atomic_sub_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='ee31ee44' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_sub_16' mangled-name='atomic_sub_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='23bd8cb5' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_sub_32' mangled-name='atomic_sub_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_32'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='3ff5601b' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_or_8' mangled-name='atomic_or_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_or_16' mangled-name='atomic_or_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_or_32' mangled-name='atomic_or_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_32'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='8f92235e' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_or_ulong' mangled-name='atomic_or_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_and_8' mangled-name='atomic_and_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_and_16' mangled-name='atomic_and_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_and_32' mangled-name='atomic_and_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_32'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='8f92235e' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_and_ulong' mangled-name='atomic_and_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='bits'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='atomic_inc_8_nv' mangled-name='atomic_inc_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_inc_16_nv' mangled-name='atomic_inc_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_inc_32_nv' mangled-name='atomic_inc_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_inc_ulong_nv' mangled-name='atomic_inc_ulong_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_inc_ulong_nv'>
- <parameter type-id='64698d33' name='target'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_dec_8_nv' mangled-name='atomic_dec_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_dec_16_nv' mangled-name='atomic_dec_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_dec_32_nv' mangled-name='atomic_dec_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_dec_ulong_nv' mangled-name='atomic_dec_ulong_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_dec_ulong_nv'>
- <parameter type-id='64698d33' name='target'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_add_ptr_nv' mangled-name='atomic_add_ptr_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_ptr_nv'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='79a0948f' name='bits'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='atomic_add_8_nv' mangled-name='atomic_add_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='ee31ee44' name='bits'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_add_16_nv' mangled-name='atomic_add_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='23bd8cb5' name='bits'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_add_32_nv' mangled-name='atomic_add_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='3ff5601b' name='bits'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_add_long_nv' mangled-name='atomic_add_long_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_add_long_nv'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='bd54fe1a' name='bits'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_sub_ptr_nv' mangled-name='atomic_sub_ptr_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_ptr_nv'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='79a0948f' name='bits'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='atomic_sub_8_nv' mangled-name='atomic_sub_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='ee31ee44' name='bits'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_sub_16_nv' mangled-name='atomic_sub_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='23bd8cb5' name='bits'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_sub_32_nv' mangled-name='atomic_sub_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='3ff5601b' name='bits'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_sub_long_nv' mangled-name='atomic_sub_long_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_sub_long_nv'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='bd54fe1a' name='bits'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_or_8_nv' mangled-name='atomic_or_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='bits'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_or_16_nv' mangled-name='atomic_or_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='bits'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_or_32_nv' mangled-name='atomic_or_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='8f92235e' name='bits'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_or_ulong_nv' mangled-name='atomic_or_ulong_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_or_ulong_nv'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='bits'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_and_8_nv' mangled-name='atomic_and_8_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_8_nv'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='bits'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_and_16_nv' mangled-name='atomic_and_16_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_16_nv'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='bits'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_and_32_nv' mangled-name='atomic_and_32_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_32_nv'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='8f92235e' name='bits'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_and_ulong_nv' mangled-name='atomic_and_ulong_nv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_and_ulong_nv'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='bits'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_cas_ptr' mangled-name='atomic_cas_ptr' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_cas_ptr'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='eaa32e2f' name='exp'/>
- <parameter type-id='eaa32e2f' name='des'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='atomic_cas_8' mangled-name='atomic_cas_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_cas_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='exp'/>
- <parameter type-id='b96825af' name='des'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_cas_16' mangled-name='atomic_cas_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_cas_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='exp'/>
- <parameter type-id='149c6638' name='des'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_cas_32' mangled-name='atomic_cas_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_cas_32'>
- <parameter type-id='3a147f31' name='target'/>
- <parameter type-id='8f92235e' name='exp'/>
- <parameter type-id='8f92235e' name='des'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='atomic_cas_ulong' mangled-name='atomic_cas_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_cas_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='exp'/>
- <parameter type-id='ee1f298e' name='des'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_swap_8' mangled-name='atomic_swap_8' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_swap_8'>
- <parameter type-id='aa323ea4' name='target'/>
- <parameter type-id='b96825af' name='bits'/>
- <return type-id='b96825af'/>
- </function-decl>
- <function-decl name='atomic_swap_16' mangled-name='atomic_swap_16' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_swap_16'>
- <parameter type-id='93977ae7' name='target'/>
- <parameter type-id='149c6638' name='bits'/>
- <return type-id='149c6638'/>
- </function-decl>
- <function-decl name='atomic_swap_ulong' mangled-name='atomic_swap_ulong' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_swap_ulong'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='ee1f298e' name='bits'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='atomic_swap_ptr' mangled-name='atomic_swap_ptr' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_swap_ptr'>
- <parameter type-id='fe09dd29' name='target'/>
- <parameter type-id='eaa32e2f' name='bits'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='atomic_set_long_excl' mangled-name='atomic_set_long_excl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_set_long_excl'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='3502e3ff' name='value'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='atomic_clear_long_excl' mangled-name='atomic_clear_long_excl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_clear_long_excl'>
- <parameter type-id='64698d33' name='target'/>
- <parameter type-id='3502e3ff' name='value'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='membar_enter' mangled-name='membar_enter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='membar_enter'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='membar_consumer' mangled-name='membar_consumer' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='membar_consumer'>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/backtrace.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='62f1140c' size-in-bits='768' id='b80f3d9b'>
- <subrange length='24' type-id='7359adad' id='fdd3342b'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='62f1140c' size-in-bits='128' id='bc19e735'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='22c546af' size-in-bits='1024' id='498c040b'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='4ea07cdb' size-in-bits='2048' id='4811c35e'>
- <subrange length='16' type-id='7359adad' id='848d0938'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='de572c22' size-in-bits='1472' id='6d3c2f42'>
- <subrange length='23' type-id='7359adad' id='fdd0f594'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='256' id='a133ec23'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='3a47d82b' size-in-bits='512' id='a13e797f'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='8efea9e5' size-in-bits='48' id='ff2536e2'>
- <subrange length='3' type-id='7359adad' id='56f209d2'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='8efea9e5' size-in-bits='64' id='3f30d495'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='73d941c6' size-in-bits='8128' id='dc70ec0b'>
- <subrange length='127' type-id='7359adad' id='5ed08de5'/>
- </array-type-def>
- <class-decl name='stack_t' size-in-bits='192' is-struct='yes' naming-typedef-id='ac5e685f' visibility='default' id='380f9954'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='ss_sp' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='ss_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='ss_size' type-id='b59d7dce' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='stack_t' type-id='380f9954' id='ac5e685f'/>
- <typedef-decl name='unw_regnum_t' type-id='95e97e5e' id='c53620f0'/>
- <class-decl name='unw_cursor' size-in-bits='8128' is-struct='yes' visibility='default' id='384a1f22'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='opaque' type-id='dc70ec0b' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='unw_cursor_t' type-id='384a1f22' id='1203d35c'/>
- <typedef-decl name='unw_context_t' type-id='190d09ef' id='8f527367'/>
- <typedef-decl name='unw_word_t' type-id='9c313c2d' id='73d941c6'/>
- <typedef-decl name='unw_tdep_context_t' type-id='c4daa689' id='190d09ef'/>
- <typedef-decl name='greg_t' type-id='1eb56b1e' id='de572c22'/>
- <typedef-decl name='gregset_t' type-id='6d3c2f42' id='a66f139c'/>
- <class-decl name='_libc_fpxreg' size-in-bits='128' is-struct='yes' visibility='default' id='22c546af'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='significand' type-id='3f30d495' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='exponent' type-id='8efea9e5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='80'>
- <var-decl name='__glibc_reserved1' type-id='ff2536e2' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='_libc_xmmreg' size-in-bits='128' is-struct='yes' visibility='default' id='4ea07cdb'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='element' type-id='bc19e735' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='_libc_fpstate' size-in-bits='4096' is-struct='yes' visibility='default' id='81cbe5ca'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='cwd' type-id='253c2d2a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='16'>
- <var-decl name='swd' type-id='253c2d2a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='ftw' type-id='253c2d2a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='48'>
- <var-decl name='fop' type-id='253c2d2a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='rip' type-id='8910171f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='rdp' type-id='8910171f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='mxcsr' type-id='62f1140c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='mxcr_mask' type-id='62f1140c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='_st' type-id='498c040b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1280'>
- <var-decl name='_xmm' type-id='4811c35e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='3328'>
- <var-decl name='__glibc_reserved1' type-id='b80f3d9b' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='fpregset_t' type-id='5b1ab9a8' id='6e5851bb'/>
- <class-decl name='mcontext_t' size-in-bits='2048' is-struct='yes' naming-typedef-id='bacab071' visibility='default' id='76fab990'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='gregs' type-id='a66f139c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1472'>
- <var-decl name='fpregs' type-id='6e5851bb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1536'>
- <var-decl name='__reserved1' type-id='a13e797f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='mcontext_t' type-id='76fab990' id='bacab071'/>
- <class-decl name='ucontext_t' size-in-bits='7744' is-struct='yes' visibility='default' id='1ba65dc8'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='uc_flags' type-id='7359adad' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='uc_link' type-id='4ed508de' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='uc_stack' type-id='ac5e685f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='uc_mcontext' type-id='bacab071' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2368'>
- <var-decl name='uc_sigmask' type-id='daf33c64' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='3392'>
- <var-decl name='__fpregs_mem' type-id='81cbe5ca' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='7488'>
- <var-decl name='__ssp' type-id='a133ec23' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='ucontext_t' type-id='1ba65dc8' id='c4daa689'/>
- <pointer-type-def type-id='81cbe5ca' size-in-bits='64' id='5b1ab9a8'/>
- <pointer-type-def type-id='1ba65dc8' size-in-bits='64' id='4ed508de'/>
- <pointer-type-def type-id='8f527367' size-in-bits='64' id='2e408b96'/>
- <pointer-type-def type-id='1203d35c' size-in-bits='64' id='3946e4d1'/>
- <pointer-type-def type-id='190d09ef' size-in-bits='64' id='3e0601f0'/>
- <pointer-type-def type-id='73d941c6' size-in-bits='64' id='42f5faab'/>
- <function-decl name='_Ux86_64_regname' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='c53620f0'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='_ULx86_64_init_local' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3946e4d1'/>
- <parameter type-id='2e408b96'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_ULx86_64_step' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3946e4d1'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_ULx86_64_get_reg' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3946e4d1'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='42f5faab'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_ULx86_64_get_proc_name' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3946e4d1'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='42f5faab'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_Ux86_64_getcontext' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3e0601f0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/getexecname.c' language='LANG_C99'>
- <function-decl name='getexecname' mangled-name='getexecname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getexecname'>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='getexecname_impl' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='26a90f95'/>
- <return type-id='79a0948f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/list.c' language='LANG_C99'>
- <typedef-decl name='list_node_t' type-id='b0b5e45e' id='b21843b2'/>
- <typedef-decl name='list_t' type-id='e824dae9' id='0899125f'/>
- <class-decl name='list_node' size-in-bits='128' is-struct='yes' visibility='default' id='b0b5e45e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='next' type-id='b03eadb4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='prev' type-id='b03eadb4' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='list' size-in-bits='192' is-struct='yes' visibility='default' id='e824dae9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='list_offset' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='list_head' type-id='b0b5e45e' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='b0b5e45e' size-in-bits='64' id='b03eadb4'/>
- <pointer-type-def type-id='b21843b2' size-in-bits='64' id='ccc38265'/>
- <pointer-type-def type-id='0899125f' size-in-bits='64' id='352ec160'/>
- <function-decl name='list_create' mangled-name='list_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_create'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='b59d7dce' name='size'/>
- <parameter type-id='b59d7dce' name='offset'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_destroy' mangled-name='list_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_destroy'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_insert_after' mangled-name='list_insert_after' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_insert_after'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <parameter type-id='eaa32e2f' name='nobject'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_insert_before' mangled-name='list_insert_before' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_insert_before'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <parameter type-id='eaa32e2f' name='nobject'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_insert_head' mangled-name='list_insert_head' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_insert_head'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_insert_tail' mangled-name='list_insert_tail' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_insert_tail'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_remove' mangled-name='list_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_remove'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_remove_head' mangled-name='list_remove_head' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_remove_head'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_remove_tail' mangled-name='list_remove_tail' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_remove_tail'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_head' mangled-name='list_head' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_head'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_tail' mangled-name='list_tail' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_tail'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_next' mangled-name='list_next' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_next'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_prev' mangled-name='list_prev' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_prev'>
- <parameter type-id='352ec160' name='list'/>
- <parameter type-id='eaa32e2f' name='object'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='list_move_tail' mangled-name='list_move_tail' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_move_tail'>
- <parameter type-id='352ec160' name='dst'/>
- <parameter type-id='352ec160' name='src'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_link_replace' mangled-name='list_link_replace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_link_replace'>
- <parameter type-id='ccc38265' name='lold'/>
- <parameter type-id='ccc38265' name='lnew'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_link_init' mangled-name='list_link_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_link_init'>
- <parameter type-id='ccc38265' name='ln'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='list_link_active' mangled-name='list_link_active' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_link_active'>
- <parameter type-id='ccc38265' name='ln'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='list_is_empty' mangled-name='list_is_empty' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='list_is_empty'>
- <parameter type-id='352ec160' name='list'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/mkdirp.c' language='LANG_C99'>
- <typedef-decl name='wchar_t' type-id='95e97e5e' id='928221d2'/>
- <qualified-type-def type-id='928221d2' const='yes' id='effb3702'/>
- <pointer-type-def type-id='effb3702' size-in-bits='64' id='f077d3f8'/>
- <qualified-type-def type-id='f077d3f8' restrict='yes' id='598aab80'/>
- <pointer-type-def type-id='928221d2' size-in-bits='64' id='323d93c1'/>
- <qualified-type-def type-id='323d93c1' restrict='yes' id='f1358bc3'/>
- <function-decl name='__mbstowcs_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f1358bc3'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='__wcstombs_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='266fe297'/>
- <parameter type-id='598aab80'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
- <pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
- <qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
- <function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e75a27e9'/>
- <parameter type-id='3cad23cd'/>
- <parameter type-id='266fe297'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='b6b61d2f'/>
- </function-decl>
- <function-decl name='feof' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/timestamp.c' language='LANG_C99'>
- <typedef-decl name='nl_item' type-id='95e97e5e' id='03b79a94'/>
- <function-decl name='nl_langinfo' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='03b79a94'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='print_timestamp' mangled-name='print_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='print_timestamp'>
- <parameter type-id='3502e3ff' name='timestamp_fmt'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='get_timestamp' mangled-name='get_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_timestamp'>
- <parameter type-id='3502e3ff' name='timestamp_fmt'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='95e97e5e' name='len'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='format_timestamp' mangled-name='format_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='format_timestamp'>
- <parameter type-id='c9d12d66' name='t'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='95e97e5e' name='len'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libspl/tunables.c' language='LANG_C99'>
- <enum-decl name='zfs_tunable_type_t' naming-typedef-id='f50b1525' id='56905369'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_TYPE_INT' value='0'/>
- <enumerator name='ZFS_TUNABLE_TYPE_UINT' value='1'/>
- <enumerator name='ZFS_TUNABLE_TYPE_ULONG' value='2'/>
- <enumerator name='ZFS_TUNABLE_TYPE_U64' value='3'/>
- <enumerator name='ZFS_TUNABLE_TYPE_STRING' value='4'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_type_t' type-id='56905369' id='f50b1525'/>
- <enum-decl name='zfs_tunable_perm_t' naming-typedef-id='ada7336b' id='e80e6ebf'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RW' value='0'/>
- <enumerator name='ZFS_TUNABLE_PERM_ZMOD_RD' value='1'/>
- </enum-decl>
- <typedef-decl name='zfs_tunable_perm_t' type-id='e80e6ebf' id='ada7336b'/>
- <class-decl name='zfs_tunable' size-in-bits='320' is-struct='yes' visibility='default' id='1a97ee0e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zt_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zt_varp' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zt_varsz' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zt_type' type-id='f50b1525' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='zt_perm' type-id='ada7336b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='zt_desc' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_tunable_t' type-id='1a97ee0e' id='12bf5c5e'/>
- <typedef-decl name='zfs_tunable_iter_t' type-id='7ef33f92' id='d8d5f4ab'/>
- <typedef-decl name='intmax_t' type-id='5b475db0' id='e104d842'/>
- <typedef-decl name='uintmax_t' type-id='04d82f4b' id='f8b828c9'/>
- <typedef-decl name='__intmax_t' type-id='bd54fe1a' id='5b475db0'/>
- <typedef-decl name='__uintmax_t' type-id='7359adad' id='04d82f4b'/>
- <qualified-type-def type-id='12bf5c5e' const='yes' id='180e47ee'/>
- <pointer-type-def type-id='180e47ee' size-in-bits='64' id='a27af98c'/>
- <pointer-type-def type-id='92f86508' size-in-bits='64' id='7ef33f92'/>
- <function-decl name='strtoimax' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='e104d842'/>
- </function-decl>
- <function-decl name='strtoumax' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='f8b828c9'/>
- </function-decl>
- <function-decl name='zfs_tunable_lookup' mangled-name='zfs_tunable_lookup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_lookup'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='a27af98c'/>
- </function-decl>
- <function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
- <parameter type-id='d8d5f4ab' name='cb'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='80f4b756' name='val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_tunable_get' mangled-name='zfs_tunable_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_get'>
- <parameter type-id='a27af98c' name='zt'/>
- <parameter type-id='26a90f95' name='val'/>
- <parameter type-id='b59d7dce' name='valsz'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='92f86508'>
- <parameter type-id='a27af98c'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'>
- <subrange length='16' type-id='7359adad' id='848d0938'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='384' id='36d7f119'>
- <subrange length='48' type-id='7359adad' id='8f6d2a81'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='f0981eeb' size-in-bits='64' id='0d532ec1'>
- <subrange length='2' type-id='7359adad' id='52efc4ef'/>
- </array-type-def>
- <union-decl name='__atomic_wide_counter' size-in-bits='64' naming-typedef-id='f3b40860' visibility='default' id='613ce450'>
- <data-member access='public'>
- <var-decl name='__value64' type-id='3a47d82b' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__value32' type-id='e7f43f72' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f72'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__low' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='__high' type-id='f0981eeb' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__atomic_wide_counter' type-id='613ce450' id='f3b40860'/>
- <typedef-decl name='__cpu_mask' type-id='7359adad' id='49ef3ffd'/>
- <class-decl name='cpu_set_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='8037c762' visibility='default' id='1f20d231'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__bits' type-id='a14403f5' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='cpu_set_t' type-id='1f20d231' id='8037c762'/>
- <union-decl name='pthread_condattr_t' size-in-bits='32' naming-typedef-id='836265dd' visibility='default' id='33dd3aad'>
- <data-member access='public'>
- <var-decl name='__size' type-id='8e0573fd' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__align' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='pthread_condattr_t' type-id='33dd3aad' id='836265dd'/>
- <union-decl name='pthread_cond_t' size-in-bits='384' naming-typedef-id='62fab762' visibility='default' id='cbb12c12'>
- <data-member access='public'>
- <var-decl name='__data' type-id='c987b47c' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__size' type-id='36d7f119' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__align' type-id='1eb56b1e' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='pthread_cond_t' type-id='cbb12c12' id='62fab762'/>
- <class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' id='c987b47c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__wseq' type-id='f3b40860' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='__g1_start' type-id='f3b40860' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='__g_refs' type-id='0d532ec1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='__g_size' type-id='0d532ec1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='__g1_orig_size' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='__wrefs' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='__g_signals' type-id='0d532ec1' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='sched_param' size-in-bits='32' is-struct='yes' visibility='default' id='0897719a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='sched_priority' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='tpool_job_t' type-id='3b8579e5' id='66a0afc9'/>
- <class-decl name='tpool_job' size-in-bits='192' is-struct='yes' visibility='default' id='3b8579e5'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tpj_next' type-id='f32b30e4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tpj_func' type-id='b7f9d8e6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='tpj_arg' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='tpool_active_t' type-id='c8d086f4' id='6fcda10e'/>
- <class-decl name='tpool_active' size-in-bits='128' is-struct='yes' visibility='default' id='c8d086f4'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tpa_next' type-id='ad33e5e7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tpa_tid' type-id='4051f5e7' visibility='default'/>
- </data-member>
- </class-decl>
- <qualified-type-def type-id='8037c762' const='yes' id='f50ea9b2'/>
- <pointer-type-def type-id='f50ea9b2' size-in-bits='64' id='5e14fa48'/>
- <qualified-type-def type-id='836265dd' const='yes' id='7d24c58d'/>
- <pointer-type-def type-id='7d24c58d' size-in-bits='64' id='a7e325e5'/>
- <qualified-type-def type-id='a7e325e5' restrict='yes' id='4c428e67'/>
- <qualified-type-def type-id='0897719a' const='yes' id='c4a7b189'/>
- <pointer-type-def type-id='c4a7b189' size-in-bits='64' id='36fca399'/>
- <qualified-type-def type-id='36fca399' restrict='yes' id='37e4897b'/>
- <qualified-type-def type-id='e05e8614' restrict='yes' id='0be2e71c'/>
- <pointer-type-def type-id='8037c762' size-in-bits='64' id='d74a6869'/>
- <qualified-type-def type-id='7292109c' restrict='yes' id='6942f6a4'/>
- <qualified-type-def type-id='7347a39e' restrict='yes' id='578ba182'/>
- <pointer-type-def type-id='62fab762' size-in-bits='64' id='db285b03'/>
- <qualified-type-def type-id='db285b03' restrict='yes' id='2a468b41'/>
- <qualified-type-def type-id='18c91f9e' restrict='yes' id='6e745582'/>
- <pointer-type-def type-id='0897719a' size-in-bits='64' id='23cbcb08'/>
- <qualified-type-def type-id='23cbcb08' restrict='yes' id='b09b2050'/>
- <pointer-type-def type-id='6fcda10e' size-in-bits='64' id='ad33e5e7'/>
- <pointer-type-def type-id='66a0afc9' size-in-bits='64' id='f32b30e4'/>
- <qualified-type-def type-id='63e171df' restrict='yes' id='9e7a3a7d'/>
- <function-decl name='pthread_self' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='4051f5e7'/>
- </function-decl>
- <function-decl name='pthread_attr_init' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_destroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getdetachstate' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='540db505'/>
- <parameter type-id='7292109c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setdetachstate' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getguardsize' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='540db505'/>
- <parameter type-id='78c01427'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setguardsize' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getschedparam' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e1815e87'/>
- <parameter type-id='b09b2050'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setschedparam' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='578ba182'/>
- <parameter type-id='37e4897b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getschedpolicy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e1815e87'/>
- <parameter type-id='6942f6a4'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setschedpolicy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getinheritsched' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e1815e87'/>
- <parameter type-id='6942f6a4'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setinheritsched' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getscope' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e1815e87'/>
- <parameter type-id='6942f6a4'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setscope' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getstack' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e1815e87'/>
- <parameter type-id='9e7a3a7d'/>
- <parameter type-id='d19b2c25'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setstack' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_setaffinity_np' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7347a39e'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='5e14fa48'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_attr_getaffinity_np' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='540db505'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='d74a6869'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_setcancelstate' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='7292109c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_setcanceltype' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='7292109c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__pthread_unregister_cancel' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='ba7c727c'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='pthread_cond_init' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='2a468b41'/>
- <parameter type-id='4c428e67'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_cond_signal' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='db285b03'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_cond_broadcast' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='db285b03'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_cond_wait' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='2a468b41'/>
- <parameter type-id='6e745582'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_cond_timedwait' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='2a468b41'/>
- <parameter type-id='6e745582'/>
- <parameter type-id='0be2e71c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__sysconf' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='bd54fe1a'/>
- </function-decl>
- <function-decl name='tpool_abandon' mangled-name='tpool_abandon' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_abandon'>
- <parameter type-id='9cf59a50' name='tpool'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='tpool_suspend' mangled-name='tpool_suspend' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_suspend'>
- <parameter type-id='9cf59a50' name='tpool'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='tpool_suspended' mangled-name='tpool_suspended' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_suspended'>
- <parameter type-id='9cf59a50' name='tpool'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='tpool_resume' mangled-name='tpool_resume' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_resume'>
- <parameter type-id='9cf59a50' name='tpool'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='tpool_member' mangled-name='tpool_member' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_member'>
- <parameter type-id='9cf59a50' name='tpool'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <pointer-type-def type-id='b1bbf10d' size-in-bits='64' id='9cf59a50'/>
- <typedef-decl name='tpool_t' type-id='88d1b7f9' id='b1bbf10d'/>
- <class-decl name='tpool' size-in-bits='2496' is-struct='yes' visibility='default' id='88d1b7f9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tp_forw' type-id='9cf59a50' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tp_back' type-id='9cf59a50' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='tp_mutex' type-id='7a6844eb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='tp_busycv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='tp_workcv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1216'>
- <var-decl name='tp_waitcv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1600'>
- <var-decl name='tp_active' type-id='ad33e5e7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1664'>
- <var-decl name='tp_head' type-id='f32b30e4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1728'>
- <var-decl name='tp_tail' type-id='f32b30e4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1792'>
- <var-decl name='tp_attr' type-id='7d8569fd' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2240'>
- <var-decl name='tp_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2272'>
- <var-decl name='tp_linger' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2304'>
- <var-decl name='tp_njobs' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2336'>
- <var-decl name='tp_minimum' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2368'>
- <var-decl name='tp_maximum' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2400'>
- <var-decl name='tp_current' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2432'>
- <var-decl name='tp_idle' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <function-type size-in-bits='64' id='c5c76c9c'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_changelist.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='bf311473' size-in-bits='128' id='f0f65199'>
- <subrange length='2' type-id='7359adad' id='52efc4ef'/>
- </array-type-def>
- <type-decl name='char' size-in-bits='8' id='a84c031d'/>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8192' id='b54ce520'>
- <subrange length='1024' type-id='7359adad' id='c60446f8'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='2048' id='d1617432'>
- <subrange length='256' type-id='7359adad' id='36e5b9fa'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='320' id='36c46961'>
- <subrange length='40' type-id='7359adad' id='8f80b239'/>
- </array-type-def>
- <class-decl name='re_dfa_t' is-struct='yes' visibility='default' is-declaration-only='yes' id='b48d2441'/>
- <class-decl name='uu_avl' is-struct='yes' visibility='default' is-declaration-only='yes' id='4af029d1'/>
- <class-decl name='uu_avl_pool' is-struct='yes' visibility='default' is-declaration-only='yes' id='12a530a8'/>
- <class-decl name='uu_avl_walk' is-struct='yes' visibility='default' is-declaration-only='yes' id='e70a39e3'/>
- <array-type-def dimensions='1' type-id='80f4b756' size-in-bits='256' id='71dc54ac'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <type-decl name='int' size-in-bits='32' id='95e97e5e'/>
- <type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
- <type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
- <type-decl name='short int' size-in-bits='16' id='a2185560'/>
- <array-type-def dimensions='1' type-id='e475ab95' size-in-bits='192' id='0ce65a8b'>
- <subrange length='3' type-id='7359adad' id='56f209d2'/>
- </array-type-def>
- <type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
- <type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
- <type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
- <type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
- <type-decl name='void' id='48b5725f'/>
- <typedef-decl name='uu_compare_fn_t' type-id='add6e811' id='40f93560'/>
- <typedef-decl name='uu_avl_pool_t' type-id='12a530a8' id='7f84e390'/>
- <typedef-decl name='uu_avl_t' type-id='4af029d1' id='bb7f0973'/>
- <class-decl name='uu_avl_node' size-in-bits='192' is-struct='yes' visibility='default' id='f65f4326'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='uan_opaque' type-id='0ce65a8b' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='uu_avl_node_t' type-id='f65f4326' id='73a65116'/>
- <typedef-decl name='uu_avl_walk_t' type-id='e70a39e3' id='edd8457b'/>
- <typedef-decl name='uu_avl_index_t' type-id='e475ab95' id='5d7f5fc8'/>
- <typedef-decl name='zfs_handle_t' type-id='f6ee4445' id='775509eb'/>
- <typedef-decl name='zpool_handle_t' type-id='67002a8a' id='b1efc708'/>
- <typedef-decl name='libzfs_handle_t' type-id='c8a9d9d8' id='95942d0c'/>
- <typedef-decl name='zfs_iter_f' type-id='5571cde4' id='d8e49ab9'/>
- <typedef-decl name='avl_tree_t' type-id='b351119f' id='f20fbd51'/>
- <class-decl name='avl_node' size-in-bits='192' is-struct='yes' visibility='default' id='428b67b3'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='avl_child' type-id='f0f65199' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='avl_pcb' type-id='e475ab95' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='avl_tree' size-in-bits='320' is-struct='yes' visibility='default' id='b351119f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='avl_root' type-id='bf311473' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='avl_compar' type-id='585e1de9' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='avl_offset' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='avl_numnodes' type-id='ee1f298e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='avl_pad' type-id='b59d7dce' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='dmu_objset_stats' size-in-bits='2304' is-struct='yes' visibility='default' id='098f0221'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='dds_num_clones' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='dds_creation_txg' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='dds_guid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='dds_type' type-id='230f1e16' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='dds_is_snapshot' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='232'>
- <var-decl name='dds_inconsistent' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='240'>
- <var-decl name='dds_redacted' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='248'>
- <var-decl name='dds_origin' type-id='d1617432' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2296'>
- <var-decl name='dds_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='dmu_objset_stats_t' type-id='098f0221' id='b2c14f17'/>
- <enum-decl name='zfs_type_t' naming-typedef-id='2e45de5d' id='5d8f7321'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_TYPE_INVALID' value='0'/>
- <enumerator name='ZFS_TYPE_FILESYSTEM' value='1'/>
- <enumerator name='ZFS_TYPE_SNAPSHOT' value='2'/>
- <enumerator name='ZFS_TYPE_VOLUME' value='4'/>
- <enumerator name='ZFS_TYPE_POOL' value='8'/>
- <enumerator name='ZFS_TYPE_BOOKMARK' value='16'/>
- <enumerator name='ZFS_TYPE_VDEV' value='32'/>
- </enum-decl>
- <typedef-decl name='zfs_type_t' type-id='5d8f7321' id='2e45de5d'/>
- <enum-decl name='dmu_objset_type' id='6b1b19f9'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='DMU_OST_NONE' value='0'/>
- <enumerator name='DMU_OST_META' value='1'/>
- <enumerator name='DMU_OST_ZFS' value='2'/>
- <enumerator name='DMU_OST_ZVOL' value='3'/>
- <enumerator name='DMU_OST_OTHER' value='4'/>
- <enumerator name='DMU_OST_ANY' value='5'/>
- <enumerator name='DMU_OST_NUMTYPES' value='6'/>
- </enum-decl>
- <typedef-decl name='dmu_objset_type_t' type-id='6b1b19f9' id='230f1e16'/>
- <enum-decl name='zfs_prop_t' naming-typedef-id='58603c44' id='4b000d60'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPROP_CONT' value='-2'/>
- <enumerator name='ZPROP_INVAL' value='-1'/>
- <enumerator name='ZPROP_USERPROP' value='-1'/>
- <enumerator name='ZFS_PROP_TYPE' value='0'/>
- <enumerator name='ZFS_PROP_CREATION' value='1'/>
- <enumerator name='ZFS_PROP_USED' value='2'/>
- <enumerator name='ZFS_PROP_AVAILABLE' value='3'/>
- <enumerator name='ZFS_PROP_REFERENCED' value='4'/>
- <enumerator name='ZFS_PROP_COMPRESSRATIO' value='5'/>
- <enumerator name='ZFS_PROP_MOUNTED' value='6'/>
- <enumerator name='ZFS_PROP_ORIGIN' value='7'/>
- <enumerator name='ZFS_PROP_QUOTA' value='8'/>
- <enumerator name='ZFS_PROP_RESERVATION' value='9'/>
- <enumerator name='ZFS_PROP_VOLSIZE' value='10'/>
- <enumerator name='ZFS_PROP_VOLBLOCKSIZE' value='11'/>
- <enumerator name='ZFS_PROP_RECORDSIZE' value='12'/>
- <enumerator name='ZFS_PROP_MOUNTPOINT' value='13'/>
- <enumerator name='ZFS_PROP_SHARENFS' value='14'/>
- <enumerator name='ZFS_PROP_CHECKSUM' value='15'/>
- <enumerator name='ZFS_PROP_COMPRESSION' value='16'/>
- <enumerator name='ZFS_PROP_ATIME' value='17'/>
- <enumerator name='ZFS_PROP_DEVICES' value='18'/>
- <enumerator name='ZFS_PROP_EXEC' value='19'/>
- <enumerator name='ZFS_PROP_SETUID' value='20'/>
- <enumerator name='ZFS_PROP_READONLY' value='21'/>
- <enumerator name='ZFS_PROP_ZONED' value='22'/>
- <enumerator name='ZFS_PROP_SNAPDIR' value='23'/>
- <enumerator name='ZFS_PROP_ACLMODE' value='24'/>
- <enumerator name='ZFS_PROP_ACLINHERIT' value='25'/>
- <enumerator name='ZFS_PROP_CREATETXG' value='26'/>
- <enumerator name='ZFS_PROP_NAME' value='27'/>
- <enumerator name='ZFS_PROP_CANMOUNT' value='28'/>
- <enumerator name='ZFS_PROP_ISCSIOPTIONS' value='29'/>
- <enumerator name='ZFS_PROP_XATTR' value='30'/>
- <enumerator name='ZFS_PROP_NUMCLONES' value='31'/>
- <enumerator name='ZFS_PROP_COPIES' value='32'/>
- <enumerator name='ZFS_PROP_VERSION' value='33'/>
- <enumerator name='ZFS_PROP_UTF8ONLY' value='34'/>
- <enumerator name='ZFS_PROP_NORMALIZE' value='35'/>
- <enumerator name='ZFS_PROP_CASE' value='36'/>
- <enumerator name='ZFS_PROP_VSCAN' value='37'/>
- <enumerator name='ZFS_PROP_NBMAND' value='38'/>
- <enumerator name='ZFS_PROP_SHARESMB' value='39'/>
- <enumerator name='ZFS_PROP_REFQUOTA' value='40'/>
- <enumerator name='ZFS_PROP_REFRESERVATION' value='41'/>
- <enumerator name='ZFS_PROP_GUID' value='42'/>
- <enumerator name='ZFS_PROP_PRIMARYCACHE' value='43'/>
- <enumerator name='ZFS_PROP_SECONDARYCACHE' value='44'/>
- <enumerator name='ZFS_PROP_USEDSNAP' value='45'/>
- <enumerator name='ZFS_PROP_USEDDS' value='46'/>
- <enumerator name='ZFS_PROP_USEDCHILD' value='47'/>
- <enumerator name='ZFS_PROP_USEDREFRESERV' value='48'/>
- <enumerator name='ZFS_PROP_USERACCOUNTING' value='49'/>
- <enumerator name='ZFS_PROP_STMF_SHAREINFO' value='50'/>
- <enumerator name='ZFS_PROP_DEFER_DESTROY' value='51'/>
- <enumerator name='ZFS_PROP_USERREFS' value='52'/>
- <enumerator name='ZFS_PROP_LOGBIAS' value='53'/>
- <enumerator name='ZFS_PROP_UNIQUE' value='54'/>
- <enumerator name='ZFS_PROP_OBJSETID' value='55'/>
- <enumerator name='ZFS_PROP_DEDUP' value='56'/>
- <enumerator name='ZFS_PROP_MLSLABEL' value='57'/>
- <enumerator name='ZFS_PROP_SYNC' value='58'/>
- <enumerator name='ZFS_PROP_DNODESIZE' value='59'/>
- <enumerator name='ZFS_PROP_REFRATIO' value='60'/>
- <enumerator name='ZFS_PROP_WRITTEN' value='61'/>
- <enumerator name='ZFS_PROP_CLONES' value='62'/>
- <enumerator name='ZFS_PROP_LOGICALUSED' value='63'/>
- <enumerator name='ZFS_PROP_LOGICALREFERENCED' value='64'/>
- <enumerator name='ZFS_PROP_INCONSISTENT' value='65'/>
- <enumerator name='ZFS_PROP_VOLMODE' value='66'/>
- <enumerator name='ZFS_PROP_FILESYSTEM_LIMIT' value='67'/>
- <enumerator name='ZFS_PROP_SNAPSHOT_LIMIT' value='68'/>
- <enumerator name='ZFS_PROP_FILESYSTEM_COUNT' value='69'/>
- <enumerator name='ZFS_PROP_SNAPSHOT_COUNT' value='70'/>
- <enumerator name='ZFS_PROP_SNAPDEV' value='71'/>
- <enumerator name='ZFS_PROP_ACLTYPE' value='72'/>
- <enumerator name='ZFS_PROP_SELINUX_CONTEXT' value='73'/>
- <enumerator name='ZFS_PROP_SELINUX_FSCONTEXT' value='74'/>
- <enumerator name='ZFS_PROP_SELINUX_DEFCONTEXT' value='75'/>
- <enumerator name='ZFS_PROP_SELINUX_ROOTCONTEXT' value='76'/>
- <enumerator name='ZFS_PROP_RELATIME' value='77'/>
- <enumerator name='ZFS_PROP_REDUNDANT_METADATA' value='78'/>
- <enumerator name='ZFS_PROP_OVERLAY' value='79'/>
- <enumerator name='ZFS_PROP_PREV_SNAP' value='80'/>
- <enumerator name='ZFS_PROP_RECEIVE_RESUME_TOKEN' value='81'/>
- <enumerator name='ZFS_PROP_ENCRYPTION' value='82'/>
- <enumerator name='ZFS_PROP_KEYLOCATION' value='83'/>
- <enumerator name='ZFS_PROP_KEYFORMAT' value='84'/>
- <enumerator name='ZFS_PROP_PBKDF2_SALT' value='85'/>
- <enumerator name='ZFS_PROP_PBKDF2_ITERS' value='86'/>
- <enumerator name='ZFS_PROP_ENCRYPTION_ROOT' value='87'/>
- <enumerator name='ZFS_PROP_KEY_GUID' value='88'/>
- <enumerator name='ZFS_PROP_KEYSTATUS' value='89'/>
- <enumerator name='ZFS_PROP_REMAPTXG' value='90'/>
- <enumerator name='ZFS_PROP_SPECIAL_SMALL_BLOCKS' value='91'/>
- <enumerator name='ZFS_PROP_IVSET_GUID' value='92'/>
- <enumerator name='ZFS_PROP_REDACTED' value='93'/>
- <enumerator name='ZFS_PROP_REDACT_SNAPS' value='94'/>
- <enumerator name='ZFS_PROP_SNAPSHOTS_CHANGED' value='95'/>
- <enumerator name='ZFS_PROP_PREFETCH' value='96'/>
- <enumerator name='ZFS_PROP_VOLTHREADING' value='97'/>
- <enumerator name='ZFS_PROP_DIRECT' value='98'/>
- <enumerator name='ZFS_PROP_LONGNAME' value='99'/>
- <enumerator name='ZFS_PROP_DEFAULTUSERQUOTA' value='100'/>
- <enumerator name='ZFS_PROP_DEFAULTGROUPQUOTA' value='101'/>
- <enumerator name='ZFS_PROP_DEFAULTPROJECTQUOTA' value='102'/>
- <enumerator name='ZFS_PROP_DEFAULTUSEROBJQUOTA' value='103'/>
- <enumerator name='ZFS_PROP_DEFAULTGROUPOBJQUOTA' value='104'/>
- <enumerator name='ZFS_PROP_DEFAULTPROJECTOBJQUOTA' value='105'/>
- <enumerator name='ZFS_NUM_PROPS' value='106'/>
- </enum-decl>
- <typedef-decl name='zfs_prop_t' type-id='4b000d60' id='58603c44'/>
- <enum-decl name='zprop_source_t' naming-typedef-id='a2256d42' id='5903f80e'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPROP_SRC_NONE' value='1'/>
- <enumerator name='ZPROP_SRC_DEFAULT' value='2'/>
- <enumerator name='ZPROP_SRC_TEMPORARY' value='4'/>
- <enumerator name='ZPROP_SRC_LOCAL' value='8'/>
- <enumerator name='ZPROP_SRC_INHERITED' value='16'/>
- <enumerator name='ZPROP_SRC_RECEIVED' value='32'/>
- </enum-decl>
- <typedef-decl name='zprop_source_t' type-id='5903f80e' id='a2256d42'/>
- <class-decl name='nvlist' size-in-bits='192' is-struct='yes' visibility='default' id='ac266fd9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='nvl_version' type-id='3ff5601b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='nvl_nvflag' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='nvl_priv' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='nvl_flag' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='nvl_pad' type-id='3ff5601b' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='nvlist_t' type-id='ac266fd9' id='8e8d4be3'/>
- <enum-decl name='sa_protocol' id='9155d4b5'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='SA_PROTOCOL_NFS' value='0'/>
- <enumerator name='SA_PROTOCOL_SMB' value='1'/>
- <enumerator name='SA_PROTOCOL_COUNT' value='2'/>
- </enum-decl>
- <enum-decl name='boolean_t' naming-typedef-id='c19b74c3' id='f58c8277'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='B_FALSE' value='0'/>
- <enumerator name='B_TRUE' value='1'/>
- </enum-decl>
- <typedef-decl name='boolean_t' type-id='f58c8277' id='c19b74c3'/>
- <typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
- <typedef-decl name='ulong_t' type-id='7359adad' id='ee1f298e'/>
- <typedef-decl name='longlong_t' type-id='1eb56b1e' id='9b3ff54f'/>
- <typedef-decl name='diskaddr_t' type-id='9b3ff54f' id='804dc465'/>
- <typedef-decl name='zoneid_t' type-id='3502e3ff' id='4da03624'/>
- <typedef-decl name='__re_long_size_t' type-id='7359adad' id='ba516949'/>
- <typedef-decl name='reg_syntax_t' type-id='7359adad' id='1b72c3b3'/>
- <class-decl name='re_pattern_buffer' size-in-bits='512' is-struct='yes' visibility='default' id='19fc9a8c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='buffer' type-id='33976309' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='allocated' type-id='ba516949' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='used' type-id='ba516949' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='syntax' type-id='1b72c3b3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='fastmap' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='translate' type-id='cf536864' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='re_nsub' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='can_be_null' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='449'>
- <var-decl name='regs_allocated' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='451'>
- <var-decl name='fastmap_accurate' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='452'>
- <var-decl name='no_sub' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='453'>
- <var-decl name='not_bol' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='454'>
- <var-decl name='not_eol' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='455'>
- <var-decl name='newline_anchor' type-id='f0981eeb' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='regex_t' type-id='19fc9a8c' id='aca3bac8'/>
- <typedef-decl name='uintptr_t' type-id='7359adad' id='e475ab95'/>
- <union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='7a6844eb' visibility='default' id='70681f9b'>
- <data-member access='public'>
- <var-decl name='__data' type-id='4c734837' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__size' type-id='36c46961' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__align' type-id='bd54fe1a' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='pthread_mutex_t' type-id='70681f9b' id='7a6844eb'/>
- <typedef-decl name='int32_t' type-id='33f57a65' id='3ff5601b'/>
- <typedef-decl name='uint8_t' type-id='c51d6389' id='b96825af'/>
- <typedef-decl name='uint32_t' type-id='62f1140c' id='8f92235e'/>
- <typedef-decl name='uint64_t' type-id='8910171f' id='9c313c2d'/>
- <class-decl name='__pthread_mutex_s' size-in-bits='320' is-struct='yes' visibility='default' id='4c734837'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__lock' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='__count' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='__owner' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='__nusers' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='__kind' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='__spins' type-id='a2185560' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='176'>
- <var-decl name='__elision' type-id='a2185560' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='__list' type-id='518fb49c' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__pthread_internal_list' size-in-bits='128' is-struct='yes' visibility='default' id='0e01899c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__prev' type-id='4d98cd5a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='__next' type-id='4d98cd5a' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__pthread_list_t' type-id='0e01899c' id='518fb49c'/>
- <typedef-decl name='__uint8_t' type-id='002ac4a6' id='c51d6389'/>
- <typedef-decl name='__int32_t' type-id='95e97e5e' id='33f57a65'/>
- <typedef-decl name='__uint32_t' type-id='f0981eeb' id='62f1140c'/>
- <typedef-decl name='__uint64_t' type-id='7359adad' id='8910171f'/>
- <typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
- <class-decl name='libzfs_handle' size-in-bits='18240' is-struct='yes' visibility='default' id='c8a9d9d8'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='libzfs_error' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='libzfs_fd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='libzfs_pool_handles' type-id='4c81de99' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='libzfs_ns_avlpool' type-id='de82c773' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='libzfs_ns_avl' type-id='a5c21a38' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='libzfs_ns_gen' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='libzfs_desc_active' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='libzfs_action' type-id='b54ce520' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8544'>
- <var-decl name='libzfs_desc' type-id='b54ce520' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='16736'>
- <var-decl name='libzfs_printerr' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='16768'>
- <var-decl name='libzfs_mnttab_enable' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='16832'>
- <var-decl name='libzfs_mnttab_cache_lock' type-id='7a6844eb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='17152'>
- <var-decl name='libzfs_mnttab_cache' type-id='f20fbd51' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='17472'>
- <var-decl name='libzfs_pool_iter' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='17504'>
- <var-decl name='libzfs_prop_debug' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='17536'>
- <var-decl name='libzfs_urire' type-id='aca3bac8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='18048'>
- <var-decl name='libzfs_max_nvlist' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='18112'>
- <var-decl name='libfetch' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='18176'>
- <var-decl name='libfetch_load_error' type-id='26a90f95' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='zfs_handle' size-in-bits='4928' is-struct='yes' visibility='default' id='f6ee4445'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zfs_hdl' type-id='b0382bb3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zpool_hdl' type-id='4c81de99' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zfs_name' type-id='d1617432' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2176'>
- <var-decl name='zfs_type' type-id='2e45de5d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2208'>
- <var-decl name='zfs_head_type' type-id='2e45de5d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2240'>
- <var-decl name='zfs_dmustats' type-id='b2c14f17' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4544'>
- <var-decl name='zfs_props' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4608'>
- <var-decl name='zfs_user_props' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4672'>
- <var-decl name='zfs_recvd_props' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4736'>
- <var-decl name='zfs_mntcheck' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4800'>
- <var-decl name='zfs_mntopts' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='4864'>
- <var-decl name='zfs_props_table' type-id='ae3e8ca6' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='zpool_handle' size-in-bits='2816' is-struct='yes' visibility='default' id='67002a8a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zpool_hdl' type-id='b0382bb3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zpool_next' type-id='4c81de99' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zpool_name' type-id='d1617432' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2176'>
- <var-decl name='zpool_state' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2208'>
- <var-decl name='zpool_n_propnames' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2240'>
- <var-decl name='zpool_propnames' type-id='71dc54ac' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2496'>
- <var-decl name='zpool_config_size' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2560'>
- <var-decl name='zpool_config' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2624'>
- <var-decl name='zpool_old_config' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2688'>
- <var-decl name='zpool_props' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2752'>
- <var-decl name='zpool_start_block' type-id='804dc465' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='0e01899c' size-in-bits='64' id='4d98cd5a'/>
- <pointer-type-def type-id='428b67b3' size-in-bits='64' id='bf311473'/>
- <pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
- <pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
- <qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
- <pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
- <qualified-type-def type-id='9155d4b5' const='yes' id='9f2c1699'/>
- <pointer-type-def type-id='9f2c1699' size-in-bits='64' id='4567bbc9'/>
- <qualified-type-def type-id='775509eb' const='yes' id='5eadf2db'/>
- <pointer-type-def type-id='5eadf2db' size-in-bits='64' id='fcd57163'/>
- <pointer-type-def type-id='96ee24a5' size-in-bits='64' id='585e1de9'/>
- <pointer-type-def type-id='cb9628fa' size-in-bits='64' id='5571cde4'/>
- <pointer-type-def type-id='95942d0c' size-in-bits='64' id='b0382bb3'/>
- <pointer-type-def type-id='8e8d4be3' size-in-bits='64' id='5ce45b60'/>
- <pointer-type-def type-id='b48d2441' size-in-bits='64' id='33976309'/>
- <pointer-type-def type-id='b96825af' size-in-bits='64' id='ae3e8ca6'/>
- <pointer-type-def type-id='002ac4a6' size-in-bits='64' id='cf536864'/>
- <pointer-type-def type-id='5d7f5fc8' size-in-bits='64' id='813a2225'/>
- <pointer-type-def type-id='73a65116' size-in-bits='64' id='2dc35b9d'/>
- <pointer-type-def type-id='7f84e390' size-in-bits='64' id='de82c773'/>
- <pointer-type-def type-id='bb7f0973' size-in-bits='64' id='a5c21a38'/>
- <pointer-type-def type-id='edd8457b' size-in-bits='64' id='5842d146'/>
- <pointer-type-def type-id='40f93560' size-in-bits='64' id='d502b39f'/>
- <pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
- <pointer-type-def type-id='775509eb' size-in-bits='64' id='9200a744'/>
- <pointer-type-def type-id='b1efc708' size-in-bits='64' id='4c81de99'/>
- <pointer-type-def type-id='a2256d42' size-in-bits='64' id='debc6aa3'/>
- <class-decl name='re_dfa_t' is-struct='yes' visibility='default' is-declaration-only='yes' id='b48d2441'/>
- <class-decl name='uu_avl' is-struct='yes' visibility='default' is-declaration-only='yes' id='4af029d1'/>
- <class-decl name='uu_avl_pool' is-struct='yes' visibility='default' is-declaration-only='yes' id='12a530a8'/>
- <class-decl name='uu_avl_walk' is-struct='yes' visibility='default' is-declaration-only='yes' id='e70a39e3'/>
- <function-decl name='uu_avl_pool_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='d502b39f'/>
- <parameter type-id='8f92235e'/>
- <return type-id='de82c773'/>
- </function-decl>
- <function-decl name='uu_avl_pool_destroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='de82c773'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uu_avl_node_init' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='2dc35b9d'/>
- <parameter type-id='de82c773'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uu_avl_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='de82c773'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='8f92235e'/>
- <return type-id='a5c21a38'/>
- </function-decl>
- <function-decl name='uu_avl_destroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uu_avl_last' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='uu_avl_walk_start' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='8f92235e'/>
- <return type-id='5842d146'/>
- </function-decl>
- <function-decl name='uu_avl_walk_next' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5842d146'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='uu_avl_walk_end' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5842d146'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uu_avl_find' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='813a2225'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='uu_avl_insert' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='5d7f5fc8'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='uu_avl_remove' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_get_handle' mangled-name='zfs_get_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_handle'>
- <parameter type-id='9200a744'/>
- <return type-id='b0382bb3'/>
- </function-decl>
- <function-decl name='zfs_open' mangled-name='zfs_open' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_open'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='zfs_close' mangled-name='zfs_close' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_close'>
- <parameter type-id='9200a744'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_get_name' mangled-name='zfs_get_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_name'>
- <parameter type-id='fcd57163'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_prop_get' mangled-name='zfs_prop_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get'>
- <parameter type-id='9200a744'/>
- <parameter type-id='58603c44'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='debc6aa3'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_int' mangled-name='zfs_prop_get_int' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_int'>
- <parameter type-id='9200a744'/>
- <parameter type-id='58603c44'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_iter_children_v2' mangled-name='zfs_iter_children_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children_v2'>
- <parameter type-id='9200a744'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_dependents_v2' mangled-name='zfs_iter_dependents_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents_v2'>
- <parameter type-id='9200a744'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_filesystems_v2' mangled-name='zfs_iter_filesystems_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems_v2'>
- <parameter type-id='9200a744'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_mounted' mangled-name='zfs_iter_mounted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_mounted'>
- <parameter type-id='9200a744'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_refresh_properties' mangled-name='zfs_refresh_properties' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_refresh_properties'>
- <parameter type-id='9200a744'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_is_mounted' mangled-name='zfs_is_mounted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_is_mounted'>
- <parameter type-id='9200a744'/>
- <parameter type-id='9b23c9ad'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_mount' mangled-name='zfs_mount' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_mount'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_unmount' mangled-name='zfs_unmount' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_unmount'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_is_shared' mangled-name='zfs_is_shared' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_is_shared'>
- <parameter type-id='9200a744'/>
- <parameter type-id='9b23c9ad'/>
- <parameter type-id='4567bbc9'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_share' mangled-name='zfs_share' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_share'>
- <parameter type-id='9200a744'/>
- <parameter type-id='4567bbc9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_unshare' mangled-name='zfs_unshare' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_unshare'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='4567bbc9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_commit_shares' mangled-name='zfs_commit_shares' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_commit_shares'>
- <parameter type-id='4567bbc9'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='getzoneid' mangled-name='getzoneid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getzoneid'>
- <return type-id='4da03624'/>
- </function-decl>
- <function-decl name='sa_commit_shares' mangled-name='sa_commit_shares' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_commit_shares'>
- <parameter type-id='9155d4b5'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='strlcat' mangled-name='strlcat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strlcat'>
- <parameter type-id='26a90f95'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='strlcpy' mangled-name='strlcpy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='strlcpy'>
- <parameter type-id='26a90f95'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='free' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='strncmp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='strlen' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_error' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_alloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='remove_mountpoint' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-type size-in-bits='64' id='96ee24a5'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='add6e811'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='cb9628fa'>
- <parameter type-id='9200a744'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_config.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='2816' id='514368c7'>
- <subrange length='352' type-id='7359adad' id='b715cd6f'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='32768' id='d16c6df4'>
- <subrange length='4096' type-id='7359adad' id='bc1b5ddc'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='65536' id='163f6aa5'>
- <subrange length='8192' type-id='7359adad' id='c88f397d'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='infinite' id='e84913bd'>
- <subrange length='infinite' type-id='7359adad' id='031f2035'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='9c313c2d' size-in-bits='128' id='c1c22e6c'>
- <subrange length='2' type-id='7359adad' id='52efc4ef'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='24' id='d3490169'>
- <subrange length='3' type-id='7359adad' id='56f209d2'/>
- </array-type-def>
- <type-decl name='variadic parameter type' id='2c1145c5'/>
- <typedef-decl name='zpool_iter_f' type-id='3aebb66f' id='fa476e62'/>
- <enum-decl name='data_type_t' naming-typedef-id='8d0687d2' id='aeeae136'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='DATA_TYPE_DONTCARE' value='-1'/>
- <enumerator name='DATA_TYPE_UNKNOWN' value='0'/>
- <enumerator name='DATA_TYPE_BOOLEAN' value='1'/>
- <enumerator name='DATA_TYPE_BYTE' value='2'/>
- <enumerator name='DATA_TYPE_INT16' value='3'/>
- <enumerator name='DATA_TYPE_UINT16' value='4'/>
- <enumerator name='DATA_TYPE_INT32' value='5'/>
- <enumerator name='DATA_TYPE_UINT32' value='6'/>
- <enumerator name='DATA_TYPE_INT64' value='7'/>
- <enumerator name='DATA_TYPE_UINT64' value='8'/>
- <enumerator name='DATA_TYPE_STRING' value='9'/>
- <enumerator name='DATA_TYPE_BYTE_ARRAY' value='10'/>
- <enumerator name='DATA_TYPE_INT16_ARRAY' value='11'/>
- <enumerator name='DATA_TYPE_UINT16_ARRAY' value='12'/>
- <enumerator name='DATA_TYPE_INT32_ARRAY' value='13'/>
- <enumerator name='DATA_TYPE_UINT32_ARRAY' value='14'/>
- <enumerator name='DATA_TYPE_INT64_ARRAY' value='15'/>
- <enumerator name='DATA_TYPE_UINT64_ARRAY' value='16'/>
- <enumerator name='DATA_TYPE_STRING_ARRAY' value='17'/>
- <enumerator name='DATA_TYPE_HRTIME' value='18'/>
- <enumerator name='DATA_TYPE_NVLIST' value='19'/>
- <enumerator name='DATA_TYPE_NVLIST_ARRAY' value='20'/>
- <enumerator name='DATA_TYPE_BOOLEAN_VALUE' value='21'/>
- <enumerator name='DATA_TYPE_INT8' value='22'/>
- <enumerator name='DATA_TYPE_UINT8' value='23'/>
- <enumerator name='DATA_TYPE_BOOLEAN_ARRAY' value='24'/>
- <enumerator name='DATA_TYPE_INT8_ARRAY' value='25'/>
- <enumerator name='DATA_TYPE_UINT8_ARRAY' value='26'/>
- <enumerator name='DATA_TYPE_DOUBLE' value='27'/>
- </enum-decl>
- <typedef-decl name='data_type_t' type-id='aeeae136' id='8d0687d2'/>
- <class-decl name='nvpair' size-in-bits='128' is-struct='yes' visibility='default' id='1c34e459'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='nvp_size' type-id='3ff5601b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='nvp_name_sz' type-id='23bd8cb5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='48'>
- <var-decl name='nvp_reserve' type-id='23bd8cb5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='nvp_value_elem' type-id='3ff5601b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='nvp_type' type-id='8d0687d2' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='nvp_name' type-id='e84913bd' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='nvpair_t' type-id='1c34e459' id='57928edf'/>
- <class-decl name='drr_begin' size-in-bits='2432' is-struct='yes' visibility='default' id='09fcdc01'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_magic' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_versioninfo' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_creation_time' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_type' type-id='230f1e16' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='drr_flags' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_fromguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='drr_toname' type-id='d1617432' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='zinject_record' size-in-bits='2944' is-struct='yes' visibility='default' id='3216f820'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zi_objset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zi_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zi_start' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zi_end' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='zi_guid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='zi_level' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='zi_error' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='zi_type' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='zi_freq' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='zi_failfast' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='zi_func' type-id='d1617432' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2560'>
- <var-decl name='zi_iotype' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2592'>
- <var-decl name='zi_duration' type-id='3ff5601b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2624'>
- <var-decl name='zi_timer' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2688'>
- <var-decl name='zi_nlanes' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2752'>
- <var-decl name='zi_cmd' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2784'>
- <var-decl name='zi_dvas' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2816'>
- <var-decl name='zi_match_count' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2880'>
- <var-decl name='zi_inject_count' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zinject_record_t' type-id='3216f820' id='a4301ca6'/>
- <class-decl name='zfs_share' size-in-bits='256' is-struct='yes' visibility='default' id='feb6f2da'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='z_exportdata' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='z_sharedata' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='z_sharetype' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='z_sharemax' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_share_t' type-id='feb6f2da' id='ee5cec36'/>
- <class-decl name='zfs_cmd' size-in-bits='109952' is-struct='yes' visibility='default' id='3522cd69'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zc_name' type-id='d16c6df4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32768'>
- <var-decl name='zc_nvlist_src' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32832'>
- <var-decl name='zc_nvlist_src_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32896'>
- <var-decl name='zc_nvlist_dst' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32960'>
- <var-decl name='zc_nvlist_dst_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='33024'>
- <var-decl name='zc_nvlist_dst_filled' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='33056'>
- <var-decl name='zc_pad2' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='33088'>
- <var-decl name='zc_history' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='33152'>
- <var-decl name='zc_value' type-id='163f6aa5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='98688'>
- <var-decl name='zc_string' type-id='d1617432' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='100736'>
- <var-decl name='zc_guid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='100800'>
- <var-decl name='zc_nvlist_conf' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='100864'>
- <var-decl name='zc_nvlist_conf_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='100928'>
- <var-decl name='zc_cookie' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='100992'>
- <var-decl name='zc_objset_type' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101056'>
- <var-decl name='zc_perm_action' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101120'>
- <var-decl name='zc_history_len' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101184'>
- <var-decl name='zc_history_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101248'>
- <var-decl name='zc_obj' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101312'>
- <var-decl name='zc_iflags' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101376'>
- <var-decl name='zc_share' type-id='ee5cec36' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='101632'>
- <var-decl name='zc_objset_stats' type-id='b2c14f17' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='103936'>
- <var-decl name='zc_begin_record' type-id='09fcdc01' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='106368'>
- <var-decl name='' type-id='ac5ab595' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109312'>
- <var-decl name='zc_cleanup_fd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109344'>
- <var-decl name='zc_simple' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109352'>
- <var-decl name='zc_pad' type-id='d3490169' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109376'>
- <var-decl name='zc_sendobj' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109440'>
- <var-decl name='zc_fromobj' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109504'>
- <var-decl name='zc_createtxg' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109568'>
- <var-decl name='zc_stat' type-id='0371a9c7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='109888'>
- <var-decl name='zc_zoneid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='__anonymous_union__' size-in-bits='2944' is-anonymous='yes' visibility='default' id='ac5ab595'>
- <data-member access='public'>
- <var-decl name='zc_inject_record' type-id='a4301ca6' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='' type-id='e7f43f73' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='__anonymous_struct__' size-in-bits='2944' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f73'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zc_pad1' type-id='514368c7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2816'>
- <var-decl name='zc_defer_destroy' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2848'>
- <var-decl name='zc_flags' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2880'>
- <var-decl name='zc_action_handle' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_cmd_t' type-id='3522cd69' id='a5559cdd'/>
- <class-decl name='zfs_stat' size-in-bits='320' is-struct='yes' visibility='default' id='6417f0b9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zs_gen' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zs_mode' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zs_links' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zs_ctime' type-id='c1c22e6c' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_stat_t' type-id='6417f0b9' id='0371a9c7'/>
- <typedef-decl name='int16_t' type-id='03896e23' id='23bd8cb5'/>
- <typedef-decl name='__int16_t' type-id='a2185560' id='03896e23'/>
- <pointer-type-def type-id='c19b74c3' size-in-bits='64' id='37e3bd22'/>
- <qualified-type-def type-id='8e8d4be3' const='yes' id='693c3853'/>
- <pointer-type-def type-id='693c3853' size-in-bits='64' id='22cce67b'/>
- <qualified-type-def type-id='57928edf' const='yes' id='642ee20f'/>
- <pointer-type-def type-id='642ee20f' size-in-bits='64' id='dace003f'/>
- <pointer-type-def type-id='2bce87e3' size-in-bits='64' id='3aebb66f'/>
- <pointer-type-def type-id='95e97e5e' size-in-bits='64' id='7292109c'/>
- <pointer-type-def type-id='5ce45b60' size-in-bits='64' id='857bb57e'/>
- <pointer-type-def type-id='57928edf' size-in-bits='64' id='3fa542f0'/>
- <pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
- <pointer-type-def type-id='3522cd69' size-in-bits='64' id='b65f7fd1'/>
- <pointer-type-def type-id='a5559cdd' size-in-bits='64' id='e4ec4540'/>
- <pointer-type-def type-id='4c81de99' size-in-bits='64' id='237193c9'/>
- <function-decl name='uu_avl_first' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='uu_avl_next' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='uu_avl_teardown' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a5c21a38'/>
- <parameter type-id='63e171df'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='zfs_standard_error' mangled-name='zfs_standard_error' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_standard_error'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_ioctl' mangled-name='zfs_ioctl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_ioctl'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='b65f7fd1'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_free' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='nvlist_dup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='857bb57e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_exists' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='nvlist_next_nvpair' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='dace003f'/>
- <return type-id='3fa542f0'/>
- </function-decl>
- <function-decl name='nvpair_name' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='fnvlist_dup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='fnvpair_value_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3fa542f0'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='libspl_assertf' mangled-name='libspl_assertf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_assertf'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__errno_location' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='7292109c'/>
- </function-decl>
- <function-decl name='dcgettext' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='getenv' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='strchr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zpool_get_config' mangled-name='zpool_get_config' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_config'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='857bb57e' name='oldconfig'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_get_features' mangled-name='zpool_get_features' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_features'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_refresh_stats' mangled-name='zpool_refresh_stats' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_refresh_stats'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='37e3bd22' name='missing'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_refresh_stats_from_handle' mangled-name='zpool_refresh_stats_from_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_refresh_stats_from_handle'>
- <parameter type-id='4c81de99' name='dzhp'/>
- <parameter type-id='4c81de99' name='szhp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_skip_pool' mangled-name='zpool_skip_pool' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_skip_pool'>
- <parameter type-id='80f4b756' name='poolname'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_iter' mangled-name='zpool_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_iter'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='fa476e62' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_root' mangled-name='zfs_iter_root' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_root'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_strdup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='no_memory' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zcmd_alloc_dst_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zcmd_expand_dst_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zcmd_read_dst_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zcmd_free_nvlists' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e4ec4540'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='make_dataset_handle' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='zpool_open_silent' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='237193c9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='2bce87e3'>
- <parameter type-id='4c81de99'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_crypto.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='fb7c6451' size-in-bits='256' id='64177143'>
- <subrange length='32' type-id='7359adad' id='ae5bde82'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8' id='89feb1ec'>
- <subrange length='1' type-id='7359adad' id='52f813b4'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='160' id='664ac0b7'>
- <subrange length='20' type-id='7359adad' id='fdca39cf'/>
- </array-type-def>
- <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
- <class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
- <class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
- <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='896' id='47394ee0'>
- <subrange length='28' type-id='7359adad' id='3db583d7'/>
- </array-type-def>
- <type-decl name='signed char' size-in-bits='8' id='28577a57'/>
- <array-type-def dimensions='1' type-id='7359adad' size-in-bits='1024' id='d2baa450'>
- <subrange length='16' type-id='7359adad' id='848d0938'/>
- </array-type-def>
- <type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
- <enum-decl name='zpool_prop_t' naming-typedef-id='5d0c23fb' id='af1ba157'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_PROP_INVAL' value='-1'/>
- <enumerator name='ZPOOL_PROP_NAME' value='0'/>
- <enumerator name='ZPOOL_PROP_SIZE' value='1'/>
- <enumerator name='ZPOOL_PROP_CAPACITY' value='2'/>
- <enumerator name='ZPOOL_PROP_ALTROOT' value='3'/>
- <enumerator name='ZPOOL_PROP_HEALTH' value='4'/>
- <enumerator name='ZPOOL_PROP_GUID' value='5'/>
- <enumerator name='ZPOOL_PROP_VERSION' value='6'/>
- <enumerator name='ZPOOL_PROP_BOOTFS' value='7'/>
- <enumerator name='ZPOOL_PROP_DELEGATION' value='8'/>
- <enumerator name='ZPOOL_PROP_AUTOREPLACE' value='9'/>
- <enumerator name='ZPOOL_PROP_CACHEFILE' value='10'/>
- <enumerator name='ZPOOL_PROP_FAILUREMODE' value='11'/>
- <enumerator name='ZPOOL_PROP_LISTSNAPS' value='12'/>
- <enumerator name='ZPOOL_PROP_AUTOEXPAND' value='13'/>
- <enumerator name='ZPOOL_PROP_DEDUPDITTO' value='14'/>
- <enumerator name='ZPOOL_PROP_DEDUPRATIO' value='15'/>
- <enumerator name='ZPOOL_PROP_FREE' value='16'/>
- <enumerator name='ZPOOL_PROP_ALLOCATED' value='17'/>
- <enumerator name='ZPOOL_PROP_READONLY' value='18'/>
- <enumerator name='ZPOOL_PROP_ASHIFT' value='19'/>
- <enumerator name='ZPOOL_PROP_COMMENT' value='20'/>
- <enumerator name='ZPOOL_PROP_EXPANDSZ' value='21'/>
- <enumerator name='ZPOOL_PROP_FREEING' value='22'/>
- <enumerator name='ZPOOL_PROP_FRAGMENTATION' value='23'/>
- <enumerator name='ZPOOL_PROP_LEAKED' value='24'/>
- <enumerator name='ZPOOL_PROP_MAXBLOCKSIZE' value='25'/>
- <enumerator name='ZPOOL_PROP_TNAME' value='26'/>
- <enumerator name='ZPOOL_PROP_MAXDNODESIZE' value='27'/>
- <enumerator name='ZPOOL_PROP_MULTIHOST' value='28'/>
- <enumerator name='ZPOOL_PROP_CHECKPOINT' value='29'/>
- <enumerator name='ZPOOL_PROP_LOAD_GUID' value='30'/>
- <enumerator name='ZPOOL_PROP_AUTOTRIM' value='31'/>
- <enumerator name='ZPOOL_PROP_COMPATIBILITY' value='32'/>
- <enumerator name='ZPOOL_PROP_BCLONEUSED' value='33'/>
- <enumerator name='ZPOOL_PROP_BCLONESAVED' value='34'/>
- <enumerator name='ZPOOL_PROP_BCLONERATIO' value='35'/>
- <enumerator name='ZPOOL_PROP_DEDUP_TABLE_SIZE' value='36'/>
- <enumerator name='ZPOOL_PROP_DEDUP_TABLE_QUOTA' value='37'/>
- <enumerator name='ZPOOL_PROP_DEDUPCACHED' value='38'/>
- <enumerator name='ZPOOL_PROP_LAST_SCRUBBED_TXG' value='39'/>
- <enumerator name='ZPOOL_NUM_PROPS' value='40'/>
- </enum-decl>
- <typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
- <typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
- <class-decl name='regmatch_t' size-in-bits='64' is-struct='yes' naming-typedef-id='1b941664' visibility='default' id='4f932615'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='rm_so' type-id='54a2a2a8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='rm_eo' type-id='54a2a2a8' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='regmatch_t' type-id='4f932615' id='1b941664'/>
- <typedef-decl name='__sighandler_t' type-id='03347643' id='8cdd9566'/>
- <typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/>
- <class-decl name='sigaction' size-in-bits='1216' is-struct='yes' visibility='default' id='fe391c48'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__sigaction_handler' type-id='ac5ab596' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='sa_mask' type-id='b9c97942' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1088'>
- <var-decl name='sa_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1152'>
- <var-decl name='sa_restorer' type-id='953b12f8' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' id='ac5ab596'>
- <data-member access='public'>
- <var-decl name='sa_handler' type-id='8cdd9566' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='sa_sigaction' type-id='6e756877' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='termios' size-in-bits='480' is-struct='yes' visibility='default' id='ad55d2bc'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='c_iflag' type-id='241ce6f8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='c_oflag' type-id='241ce6f8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='c_cflag' type-id='241ce6f8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='c_lflag' type-id='241ce6f8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='c_line' type-id='fb7c6451' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='136'>
- <var-decl name='c_cc' type-id='64177143' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='416'>
- <var-decl name='c_ispeed' type-id='6a8e8a14' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='c_ospeed' type-id='6a8e8a14' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='cc_t' type-id='002ac4a6' id='fb7c6451'/>
- <typedef-decl name='speed_t' type-id='f0981eeb' id='6a8e8a14'/>
- <typedef-decl name='tcflag_t' type-id='f0981eeb' id='241ce6f8'/>
- <typedef-decl name='__uid_t' type-id='f0981eeb' id='cc5fcceb'/>
- <typedef-decl name='__off_t' type-id='bd54fe1a' id='79989e9c'/>
- <typedef-decl name='__off64_t' type-id='bd54fe1a' id='724e4de6'/>
- <typedef-decl name='__pid_t' type-id='95e97e5e' id='3629bad8'/>
- <typedef-decl name='__clock_t' type-id='bd54fe1a' id='4d66c6d7'/>
- <typedef-decl name='__ssize_t' type-id='bd54fe1a' id='41060289'/>
- <typedef-decl name='FILE' type-id='ec1ed955' id='aa12d1ba'/>
- <class-decl name='__sigset_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='b9c97942' visibility='default' id='2616147f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__val' type-id='d2baa450' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__sigset_t' type-id='2616147f' id='b9c97942'/>
- <union-decl name='sigval' size-in-bits='64' visibility='default' id='a094b870'>
- <data-member access='public'>
- <var-decl name='sival_int' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='sival_ptr' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='__sigval_t' type-id='a094b870' id='eabacd01'/>
- <class-decl name='siginfo_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='cb681f62' visibility='default' id='d8149419'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_signo' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='si_errno' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_code' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='__pad0' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='_sifields' type-id='ac5ab597' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='__anonymous_union__1' size-in-bits='896' is-anonymous='yes' visibility='default' id='ac5ab597'>
- <data-member access='public'>
- <var-decl name='_pad' type-id='47394ee0' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_kill' type-id='e7f43f74' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_timer' type-id='e7f43f75' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_rt' type-id='e7f43f76' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_sigchld' type-id='e7f43f77' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_sigfault' type-id='e7f43f78' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_sigpoll' type-id='e7f43f79' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_sigsys' type-id='e7f43f7a' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='__anonymous_struct__1' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f74'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_pid' type-id='3629bad8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='si_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__2' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f75'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_tid' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='si_overrun' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_sigval' type-id='eabacd01' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__3' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f76'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_pid' type-id='3629bad8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='si_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_sigval' type-id='eabacd01' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__4' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f77'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_pid' type-id='3629bad8' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='si_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_status' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='si_utime' type-id='4d66c6d7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='si_stime' type-id='4d66c6d7' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__5' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f78'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_addr' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_addr_lsb' type-id='a2185560' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='_bounds' type-id='ac5ab598' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='__anonymous_union__2' size-in-bits='128' is-anonymous='yes' visibility='default' id='ac5ab598'>
- <data-member access='public'>
- <var-decl name='_addr_bnd' type-id='e7f43f7b' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_pkey' type-id='62f1140c' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='__anonymous_struct__6' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f7b'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='_lower' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='_upper' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__7' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f79'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='si_band' type-id='bd54fe1a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='si_fd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__anonymous_struct__8' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f7a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='_call_addr' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='_syscall' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='_arch' type-id='f0981eeb' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='siginfo_t' type-id='d8149419' id='cb681f62'/>
- <typedef-decl name='sigset_t' type-id='b9c97942' id='daf33c64'/>
- <typedef-decl name='_IO_lock_t' type-id='48b5725f' id='bb4788fa'/>
- <class-decl name='_IO_FILE' size-in-bits='1728' is-struct='yes' visibility='default' id='ec1ed955'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='_IO_read_ptr' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='_IO_read_end' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='_IO_read_base' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='_IO_write_base' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='_IO_write_ptr' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='_IO_write_end' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='_IO_buf_base' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='_IO_buf_end' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='_IO_save_base' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='640'>
- <var-decl name='_IO_backup_base' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='_IO_save_end' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='768'>
- <var-decl name='_markers' type-id='e4c6fa61' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='_chain' type-id='dca988a5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='896'>
- <var-decl name='_fileno' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='928'>
- <var-decl name='_flags2' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='960'>
- <var-decl name='_old_offset' type-id='79989e9c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1024'>
- <var-decl name='_cur_column' type-id='8efea9e5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1040'>
- <var-decl name='_vtable_offset' type-id='28577a57' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1048'>
- <var-decl name='_shortbuf' type-id='89feb1ec' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1088'>
- <var-decl name='_lock' type-id='cecf4ea7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1152'>
- <var-decl name='_offset' type-id='724e4de6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1216'>
- <var-decl name='_codecvt' type-id='570f8c59' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1280'>
- <var-decl name='_wide_data' type-id='c65a1f29' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1344'>
- <var-decl name='_freeres_list' type-id='dca988a5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1408'>
- <var-decl name='_freeres_buf' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1472'>
- <var-decl name='__pad5' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1536'>
- <var-decl name='_mode' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1568'>
- <var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
- <qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
- <pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
- <pointer-type-def type-id='a4036571' size-in-bits='64' id='570f8c59'/>
- <pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
- <pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
- <pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
- <qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
- <qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
- <pointer-type-def type-id='80f4b756' size-in-bits='64' id='7d3cd834'/>
- <qualified-type-def type-id='aca3bac8' const='yes' id='2498fd78'/>
- <pointer-type-def type-id='2498fd78' size-in-bits='64' id='eed6c816'/>
- <qualified-type-def type-id='eed6c816' restrict='yes' id='a431a9da'/>
- <qualified-type-def type-id='fe391c48' const='yes' id='14a93b33'/>
- <pointer-type-def type-id='14a93b33' size-in-bits='64' id='9f68085b'/>
- <qualified-type-def type-id='9f68085b' restrict='yes' id='e2a5e6f9'/>
- <qualified-type-def type-id='ad55d2bc' const='yes' id='a46bf13f'/>
- <pointer-type-def type-id='a46bf13f' size-in-bits='64' id='eaec840f'/>
- <qualified-type-def type-id='002ac4a6' const='yes' id='ea86de29'/>
- <pointer-type-def type-id='ea86de29' size-in-bits='64' id='354f7eb9'/>
- <qualified-type-def type-id='8efea9e5' const='yes' id='3beb2af4'/>
- <pointer-type-def type-id='3beb2af4' size-in-bits='64' id='31347b7a'/>
- <pointer-type-def type-id='31347b7a' size-in-bits='64' id='c59e1ef0'/>
- <pointer-type-def type-id='7a6844eb' size-in-bits='64' id='18c91f9e'/>
- <pointer-type-def type-id='1b941664' size-in-bits='64' id='7e2979d5'/>
- <qualified-type-def type-id='7e2979d5' restrict='yes' id='fc212857'/>
- <pointer-type-def type-id='fe391c48' size-in-bits='64' id='568dd84e'/>
- <qualified-type-def type-id='568dd84e' restrict='yes' id='3d8ee6f2'/>
- <pointer-type-def type-id='cb681f62' size-in-bits='64' id='185869c1'/>
- <pointer-type-def type-id='daf33c64' size-in-bits='64' id='9e80f729'/>
- <pointer-type-def type-id='b59d7dce' size-in-bits='64' id='78c01427'/>
- <qualified-type-def type-id='78c01427' restrict='yes' id='d19b2c25'/>
- <pointer-type-def type-id='ad55d2bc' size-in-bits='64' id='665a4eda'/>
- <pointer-type-def type-id='9c313c2d' size-in-bits='64' id='5d6479ae'/>
- <pointer-type-def type-id='ae3e8ca6' size-in-bits='64' id='d8774064'/>
- <pointer-type-def type-id='3502e3ff' size-in-bits='64' id='4dd26a40'/>
- <pointer-type-def type-id='ee076206' size-in-bits='64' id='953b12f8'/>
- <pointer-type-def type-id='f712e2b7' size-in-bits='64' id='03347643'/>
- <pointer-type-def type-id='ef70d893' size-in-bits='64' id='6e756877'/>
- <qualified-type-def type-id='eaa32e2f' restrict='yes' id='1b7446cd'/>
- <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
- <class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
- <class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
- <function-decl name='zpool_get_prop_int' mangled-name='zpool_get_prop_int' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_prop_int'>
- <parameter type-id='4c81de99'/>
- <parameter type-id='5d0c23fb'/>
- <parameter type-id='debc6aa3'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_handle_dup' mangled-name='zfs_handle_dup' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_handle_dup'>
- <parameter type-id='9200a744'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='zfs_valid_proplist' mangled-name='zfs_valid_proplist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valid_proplist'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='2e45de5d'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9200a744'/>
- <parameter type-id='4c81de99'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_prop_to_name' mangled-name='zfs_prop_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_to_name'>
- <parameter type-id='58603c44'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_parent_name' mangled-name='zfs_parent_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_parent_name'>
- <parameter type-id='9200a744'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_load_key' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='ae3e8ca6'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_unload_key' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_change_key' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='ae3e8ca6'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_name_to_prop' mangled-name='zfs_name_to_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_name_to_prop'>
- <parameter type-id='80f4b756'/>
- <return type-id='58603c44'/>
- </function-decl>
- <function-decl name='nvlist_add_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_add_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5d6479ae'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fnvlist_alloc' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='__ctype_b_loc' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='c59e1ef0'/>
- </function-decl>
- <function-decl name='dlopen' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='dlsym' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='1b7446cd'/>
- <parameter type-id='9d26089a'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='dlerror' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='PKCS5_PBKDF2_HMAC_SHA1' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='354f7eb9'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='cf536864'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_mutex_lock' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='18c91f9e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_mutex_unlock' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='18c91f9e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='regexec' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a431a9da'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='fc212857'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='kill' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3629bad8'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sigemptyset' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9e80f729'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sigaction' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='e2a5e6f9'/>
- <parameter type-id='3d8ee6f2'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fclose' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fflush' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fdopen' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <return type-id='822cd80b'/>
- </function-decl>
- <function-decl name='fputc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__getdelim' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='8c85230f'/>
- <parameter type-id='d19b2c25'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='e75a27e9'/>
- <return type-id='41060289'/>
- </function-decl>
- <function-decl name='rewind' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='ferror' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fileno' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='malloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='calloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='strerror' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='tcgetattr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='665a4eda'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='tcsetattr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaec840f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='close' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='getpid' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='3629bad8'/>
- </function-decl>
- <function-decl name='isatty' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='unlink' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__open_too_many_args' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__open_missing_mode' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__printf_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9d26089a'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__fread_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='1b7446cd'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='e75a27e9'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='__read_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='79a0948f'/>
- </function-decl>
- <function-decl name='zfs_crypto_get_encryption_root' mangled-name='zfs_crypto_get_encryption_root' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_get_encryption_root'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='37e3bd22' name='is_encroot'/>
- <parameter type-id='26a90f95' name='buf'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_create' mangled-name='zfs_crypto_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_create'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='parent_name'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='5ce45b60' name='pool_props'/>
- <parameter type-id='c19b74c3' name='stdin_available'/>
- <parameter type-id='d8774064' name='wkeydata_out'/>
- <parameter type-id='4dd26a40' name='wkeylen_out'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_clone_check' mangled-name='zfs_crypto_clone_check' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_clone_check'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='9200a744' name='origin_zhp'/>
- <parameter type-id='26a90f95' name='parent_name'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_attempt_load_keys' mangled-name='zfs_crypto_attempt_load_keys' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_attempt_load_keys'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='fsname'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_load_key' mangled-name='zfs_crypto_load_key' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_load_key'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='c19b74c3' name='noop'/>
- <parameter type-id='80f4b756' name='alt_keylocation'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_unload_key' mangled-name='zfs_crypto_unload_key' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_unload_key'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_crypto_rewrap' mangled-name='zfs_crypto_rewrap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_crypto_rewrap'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='5ce45b60' name='raw_props'/>
- <parameter type-id='c19b74c3' name='inheritkey'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_is_encrypted' mangled-name='zfs_is_encrypted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_is_encrypted'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_error_aux' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-type size-in-bits='64' id='f712e2b7'>
- <parameter type-id='95e97e5e'/>
- <return type-id='48b5725f'/>
- </function-type>
- <function-type size-in-bits='64' id='ef70d893'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='185869c1'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_dataset.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='32' id='8e0573fd'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <class-decl name='prop_changelist' is-struct='yes' visibility='default' is-declaration-only='yes' id='d86edc51'/>
- <class-decl name='zprop_list' size-in-bits='448' is-struct='yes' visibility='default' id='bd9b4291'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='pl_prop' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='pl_user_prop' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='pl_next' type-id='9f1a1109' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='pl_all' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='pl_width' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='pl_recvd_width' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='pl_fixed' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zprop_list_t' type-id='bd9b4291' id='bdb8ac4f'/>
- <class-decl name='renameflags' size-in-bits='32' is-struct='yes' visibility='default' id='7aee5792'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='recursive' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1'>
- <var-decl name='nounmount' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2'>
- <var-decl name='forceunmount' type-id='f0981eeb' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='renameflags_t' type-id='7aee5792' id='067170c2'/>
- <typedef-decl name='zfs_userspace_cb_t' type-id='bbaa4f9c' id='16c5f410'/>
- <enum-decl name='lzc_dataset_type' id='bc9887f1'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='LZC_DATSET_TYPE_ZFS' value='2'/>
- <enumerator name='LZC_DATSET_TYPE_ZVOL' value='3'/>
- </enum-decl>
- <typedef-decl name='avl_index_t' type-id='e475ab95' id='fba6cb51'/>
- <enum-decl name='zfs_userquota_prop_t' naming-typedef-id='279fde6a' id='5258d2f6'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_PROP_USERUSED' value='0'/>
- <enumerator name='ZFS_PROP_USERQUOTA' value='1'/>
- <enumerator name='ZFS_PROP_GROUPUSED' value='2'/>
- <enumerator name='ZFS_PROP_GROUPQUOTA' value='3'/>
- <enumerator name='ZFS_PROP_USEROBJUSED' value='4'/>
- <enumerator name='ZFS_PROP_USEROBJQUOTA' value='5'/>
- <enumerator name='ZFS_PROP_GROUPOBJUSED' value='6'/>
- <enumerator name='ZFS_PROP_GROUPOBJQUOTA' value='7'/>
- <enumerator name='ZFS_PROP_PROJECTUSED' value='8'/>
- <enumerator name='ZFS_PROP_PROJECTQUOTA' value='9'/>
- <enumerator name='ZFS_PROP_PROJECTOBJUSED' value='10'/>
- <enumerator name='ZFS_PROP_PROJECTOBJQUOTA' value='11'/>
- <enumerator name='ZFS_NUM_USERQUOTA_PROPS' value='12'/>
- </enum-decl>
- <typedef-decl name='zfs_userquota_prop_t' type-id='5258d2f6' id='279fde6a'/>
- <enum-decl name='zfs_wait_activity_t' naming-typedef-id='3024501a' id='527d5dc6'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_WAIT_DELETEQ' value='0'/>
- <enumerator name='ZFS_WAIT_NUM_ACTIVITIES' value='1'/>
- </enum-decl>
- <typedef-decl name='zfs_wait_activity_t' type-id='527d5dc6' id='3024501a'/>
- <enum-decl name='namecheck_err_t' naming-typedef-id='8e0af06e' id='f43bbcda'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='NAME_ERR_LEADING_SLASH' value='0'/>
- <enumerator name='NAME_ERR_EMPTY_COMPONENT' value='1'/>
- <enumerator name='NAME_ERR_TRAILING_SLASH' value='2'/>
- <enumerator name='NAME_ERR_INVALCHAR' value='3'/>
- <enumerator name='NAME_ERR_MULTIPLE_DELIMITERS' value='4'/>
- <enumerator name='NAME_ERR_NOLETTER' value='5'/>
- <enumerator name='NAME_ERR_RESERVED' value='6'/>
- <enumerator name='NAME_ERR_DISKLIKE' value='7'/>
- <enumerator name='NAME_ERR_TOOLONG' value='8'/>
- <enumerator name='NAME_ERR_SELF_REF' value='9'/>
- <enumerator name='NAME_ERR_PARENT_REF' value='10'/>
- <enumerator name='NAME_ERR_NO_AT' value='11'/>
- <enumerator name='NAME_ERR_NO_POUND' value='12'/>
- </enum-decl>
- <typedef-decl name='namecheck_err_t' type-id='f43bbcda' id='8e0af06e'/>
- <enum-decl name='zprop_type_t' naming-typedef-id='31429eff' id='87676253'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='PROP_TYPE_NUMBER' value='0'/>
- <enumerator name='PROP_TYPE_STRING' value='1'/>
- <enumerator name='PROP_TYPE_INDEX' value='2'/>
- </enum-decl>
- <typedef-decl name='zprop_type_t' type-id='87676253' id='31429eff'/>
- <class-decl name='mnttab' size-in-bits='256' is-struct='yes' visibility='default' id='1b055409'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='mnt_mountp' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='mnt_fstype' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='group' size-in-bits='256' is-struct='yes' visibility='default' id='01a1b934'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='gr_name' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='gr_passwd' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='gr_gid' type-id='d94ec6d9' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='gr_mem' type-id='9b23c9ad' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='mntent' size-in-bits='320' is-struct='yes' visibility='default' id='56fe4a37'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='mnt_fsname' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='mnt_dir' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='mnt_type' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='mnt_opts' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='mnt_freq' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='mnt_passno' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='passwd' size-in-bits='384' is-struct='yes' visibility='default' id='a63d15a3'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='pw_name' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='pw_passwd' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='pw_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='pw_gid' type-id='d94ec6d9' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='pw_gecos' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='pw_dir' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='pw_shell' type-id='26a90f95' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='8afd6070' visibility='default' id='7300eb00'>
- <data-member access='public'>
- <var-decl name='__size' type-id='8e0573fd' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__align' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='pthread_mutexattr_t' type-id='7300eb00' id='8afd6070'/>
- <typedef-decl name='int64_t' type-id='0c9942d2' id='9da381c4'/>
- <typedef-decl name='__int64_t' type-id='bd54fe1a' id='0c9942d2'/>
- <typedef-decl name='__gid_t' type-id='f0981eeb' id='d94ec6d9'/>
- <typedef-decl name='__time_t' type-id='bd54fe1a' id='65eda9c0'/>
- <class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' id='dddf6ca2'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tm_sec' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='tm_min' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tm_hour' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='tm_mday' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='tm_mon' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='tm_year' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='tm_wday' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='tm_yday' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='tm_isdst' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='tm_gmtoff' type-id='bd54fe1a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='tm_zone' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='time_t' type-id='65eda9c0' id='c9d12d66'/>
- <typedef-decl name='uid_t' type-id='cc5fcceb' id='354978ed'/>
- <typedef-decl name='prop_changelist_t' type-id='d86edc51' id='eae6431d'/>
- <pointer-type-def type-id='fba6cb51' size-in-bits='64' id='32adbf30'/>
- <pointer-type-def type-id='f20fbd51' size-in-bits='64' id='a3681dea'/>
- <qualified-type-def type-id='26a90f95' restrict='yes' id='266fe297'/>
- <qualified-type-def type-id='56fe4a37' const='yes' id='a75125ce'/>
- <pointer-type-def type-id='a75125ce' size-in-bits='64' id='48bea5ec'/>
- <qualified-type-def type-id='8afd6070' const='yes' id='1d853360'/>
- <pointer-type-def type-id='1d853360' size-in-bits='64' id='c2afbd7e'/>
- <qualified-type-def type-id='c9d12d66' const='yes' id='588b3216'/>
- <pointer-type-def type-id='588b3216' size-in-bits='64' id='9f201474'/>
- <qualified-type-def type-id='9f201474' restrict='yes' id='d6e2847c'/>
- <qualified-type-def type-id='dddf6ca2' const='yes' id='e824a34f'/>
- <pointer-type-def type-id='e824a34f' size-in-bits='64' id='d6ad37ff'/>
- <qualified-type-def type-id='d6ad37ff' restrict='yes' id='f8c6051d'/>
- <qualified-type-def type-id='9c313c2d' const='yes' id='c3b7ba7d'/>
- <pointer-type-def type-id='c3b7ba7d' size-in-bits='64' id='713a56f5'/>
- <pointer-type-def type-id='01a1b934' size-in-bits='64' id='566b3f52'/>
- <qualified-type-def type-id='566b3f52' restrict='yes' id='c878edd6'/>
- <pointer-type-def type-id='566b3f52' size-in-bits='64' id='82d4e9e8'/>
- <qualified-type-def type-id='82d4e9e8' restrict='yes' id='aa19c230'/>
- <pointer-type-def type-id='02362c02' size-in-bits='64' id='bbaa4f9c'/>
- <pointer-type-def type-id='9da381c4' size-in-bits='64' id='cb785ebf'/>
- <pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
- <pointer-type-def type-id='8e0af06e' size-in-bits='64' id='053457bd'/>
- <pointer-type-def type-id='857bb57e' size-in-bits='64' id='75be733c'/>
- <pointer-type-def type-id='a63d15a3' size-in-bits='64' id='a195f4a3'/>
- <qualified-type-def type-id='a195f4a3' restrict='yes' id='33518961'/>
- <pointer-type-def type-id='a195f4a3' size-in-bits='64' id='e80ff3ab'/>
- <qualified-type-def type-id='e80ff3ab' restrict='yes' id='8f2c7109'/>
- <pointer-type-def type-id='eae6431d' size-in-bits='64' id='0d41d328'/>
- <pointer-type-def type-id='dddf6ca2' size-in-bits='64' id='d915a820'/>
- <qualified-type-def type-id='d915a820' restrict='yes' id='f099ad08'/>
- <pointer-type-def type-id='5d6479ae' size-in-bits='64' id='892b4acc'/>
- <pointer-type-def type-id='bd9b4291' size-in-bits='64' id='9f1a1109'/>
- <pointer-type-def type-id='bdb8ac4f' size-in-bits='64' id='3a9b2288'/>
- <pointer-type-def type-id='3a9b2288' size-in-bits='64' id='e4378506'/>
- <class-decl name='prop_changelist' is-struct='yes' visibility='default' is-declaration-only='yes' id='d86edc51'/>
- <function-decl name='zpool_open' mangled-name='zpool_open' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_open'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='4c81de99'/>
- </function-decl>
- <function-decl name='zpool_open_canfail' mangled-name='zpool_open_canfail' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_open_canfail'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='4c81de99'/>
- </function-decl>
- <function-decl name='zpool_close' mangled-name='zpool_close' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_close'>
- <parameter type-id='4c81de99'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_get_name' mangled-name='zpool_get_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_name'>
- <parameter type-id='4c81de99'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_get_prop' mangled-name='zpool_get_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_prop'>
- <parameter type-id='4c81de99'/>
- <parameter type-id='5d0c23fb'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='debc6aa3'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_default_string' mangled-name='zfs_prop_default_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_default_string'>
- <parameter type-id='58603c44'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_prop_default_numeric' mangled-name='zfs_prop_default_numeric' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_default_numeric'>
- <parameter type-id='58603c44'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_iter_snapshots_v2' mangled-name='zfs_iter_snapshots_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_v2'>
- <parameter type-id='9200a744'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_bookmarks_v2' mangled-name='zfs_iter_bookmarks_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks_v2'>
- <parameter type-id='9200a744'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='d8e49ab9'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_destroy_snaps_nvl_os' mangled-name='zfs_destroy_snaps_nvl_os' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_destroy_snaps_nvl_os'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_nicestrtonum' mangled-name='zfs_nicestrtonum' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_nicestrtonum'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5d6479ae'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_ioctl_fd' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='7359adad'/>
- <parameter type-id='b65f7fd1'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_snapshot' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='bc9887f1'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='ae3e8ca6'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_clone' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_promote' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_destroy_snaps' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_get_bookmarks' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_destroy_bookmarks' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_hold' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_release' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_get_holds' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_exists' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='lzc_rollback_to' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_destroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_channel_program_nosync' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_wait_fs' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='3024501a'/>
- <parameter type-id='37e3bd22'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_nicebytes' mangled-name='zfs_nicebytes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_nicebytes'>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_nicenum' mangled-name='zfs_nicenum' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_nicenum'>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_create' mangled-name='avl_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_create'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='585e1de9'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_find' mangled-name='avl_find' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_find'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='32adbf30'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='avl_add' mangled-name='avl_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_add'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_remove' mangled-name='avl_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_remove'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_numnodes' mangled-name='avl_numnodes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_numnodes'>
- <parameter type-id='a3681dea'/>
- <return type-id='ee1f298e'/>
- </function-decl>
- <function-decl name='avl_destroy_nodes' mangled-name='avl_destroy_nodes' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_destroy_nodes'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='63e171df'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='avl_destroy' mangled-name='avl_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_destroy'>
- <parameter type-id='a3681dea'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_prop_readonly' mangled-name='zfs_prop_readonly' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_readonly'>
- <parameter type-id='58603c44'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_inheritable' mangled-name='zfs_prop_inheritable' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_inheritable'>
- <parameter type-id='58603c44'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_setonce' mangled-name='zfs_prop_setonce' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_setonce'>
- <parameter type-id='58603c44'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_encryption_key_param' mangled-name='zfs_prop_encryption_key_param' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_encryption_key_param'>
- <parameter type-id='58603c44'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_valid_keylocation' mangled-name='zfs_prop_valid_keylocation' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_valid_keylocation'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_user' mangled-name='zfs_prop_user' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_user'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_userquota' mangled-name='zfs_prop_userquota' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_userquota'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_written' mangled-name='zfs_prop_written' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_written'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_index_to_string' mangled-name='zfs_prop_index_to_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_index_to_string'>
- <parameter type-id='58603c44'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_valid_for_type' mangled-name='zfs_prop_valid_for_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_valid_for_type'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='2e45de5d'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='nvlist_alloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='857bb57e'/>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_size' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='78c01427'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_pack' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='9b23c9ad'/>
- <parameter type-id='78c01427'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_unpack' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='857bb57e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_add_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='22cce67b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_add_uint64_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='713a56f5'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_remove' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='8d0687d2'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_remove_all' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_int64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='cb785ebf'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_uint64_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='892b4acc'/>
- <parameter type-id='4dd26a40'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_nvlist_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='75be733c'/>
- <parameter type-id='4dd26a40'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_empty' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='nvpair_type' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='8d0687d2'/>
- </function-decl>
- <function-decl name='nvpair_value_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <parameter type-id='5d6479ae'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvpair_value_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fnvlist_free' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_boolean' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_lookup_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='fnvlist_lookup_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='fnvlist_lookup_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='fnvpair_value_int32' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='3ff5601b'/>
- </function-decl>
- <function-decl name='fnvpair_value_uint64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='entity_namecheck' mangled-name='entity_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='entity_namecheck'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='053457bd'/>
- <parameter type-id='26a90f95'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='dataset_nestcheck' mangled-name='dataset_nestcheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dataset_nestcheck'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='mountpoint_namecheck' mangled-name='mountpoint_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mountpoint_namecheck'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='053457bd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_type' mangled-name='zfs_prop_get_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_type'>
- <parameter type-id='58603c44'/>
- <return type-id='31429eff'/>
- </function-decl>
- <function-decl name='sa_validate_shareopts' mangled-name='sa_validate_shareopts' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_validate_shareopts'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9155d4b5'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='getmntany' mangled-name='getmntany' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getmntany'>
- <parameter type-id='822cd80b'/>
- <parameter type-id='9d424d31'/>
- <parameter type-id='9d424d31'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_sol_getmntent' mangled-name='_sol_getmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_sol_getmntent'>
- <parameter type-id='822cd80b'/>
- <parameter type-id='9d424d31'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='getgrnam_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='c878edd6'/>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='aa19c230'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='hasmntopt' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='48bea5ec'/>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='pthread_mutex_init' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='18c91f9e'/>
- <parameter type-id='c2afbd7e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_mutex_destroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='18c91f9e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='getpwnam_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='33518961'/>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='8f2c7109'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='strtol' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='bd54fe1a'/>
- </function-decl>
- <function-decl name='strtoul' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='7359adad'/>
- </function-decl>
- <function-decl name='abort' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='strrchr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='strcspn' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='strstr' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='strsep' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='8c85230f'/>
- <parameter type-id='9d26089a'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='strftime' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='f8c6051d'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='localtime_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='d6e2847c'/>
- <parameter type-id='f099ad08'/>
- <return type-id='d915a820'/>
- </function-decl>
- <function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e75a27e9'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9d26089a'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_type_to_name' mangled-name='zfs_type_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_type_to_name'>
- <parameter type-id='2e45de5d' name='type'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_name_valid' mangled-name='zfs_name_valid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_name_valid'>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='2e45de5d' name='type'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_free_handles' mangled-name='zpool_free_handles' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_free_handles'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_bookmark_exists' mangled-name='zfs_bookmark_exists' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_bookmark_exists'>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_init' mangled-name='libzfs_mnttab_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_init'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_fini' mangled-name='libzfs_mnttab_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_fini'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_cache' mangled-name='libzfs_mnttab_cache' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_cache'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='c19b74c3' name='enable'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_find' mangled-name='libzfs_mnttab_find' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_find'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='fsname'/>
- <parameter type-id='9d424d31' name='entry'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_add' mangled-name='libzfs_mnttab_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_add'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='special'/>
- <parameter type-id='80f4b756' name='mountp'/>
- <parameter type-id='80f4b756' name='mntopts'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_mnttab_remove' mangled-name='libzfs_mnttab_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_mnttab_remove'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='fsname'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_spa_version' mangled-name='zfs_spa_version' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_spa_version'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='7292109c' name='spa_version'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_set' mangled-name='zfs_prop_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_set'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='propval'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_set_list' mangled-name='zfs_prop_set_list' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_set_list'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_set_list_flags' mangled-name='zfs_prop_set_list_flags' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_set_list_flags'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_inherit' mangled-name='zfs_prop_inherit' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_inherit'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='c19b74c3' name='received'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='getprop_uint64' mangled-name='getprop_uint64' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getprop_uint64'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='58603c44' name='prop'/>
- <parameter type-id='7d3cd834' name='source'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_prop_get_recvd' mangled-name='zfs_prop_get_recvd' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_recvd'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='26a90f95' name='propbuf'/>
- <parameter type-id='b59d7dce' name='proplen'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_get_clones_nvl' mangled-name='zfs_get_clones_nvl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_clones_nvl'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_prop_get_numeric' mangled-name='zfs_prop_get_numeric' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_numeric'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='58603c44' name='prop'/>
- <parameter type-id='5d6479ae' name='value'/>
- <parameter type-id='debc6aa3' name='src'/>
- <parameter type-id='26a90f95' name='statbuf'/>
- <parameter type-id='b59d7dce' name='statlen'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_userquota_int' mangled-name='zfs_prop_get_userquota_int' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_userquota_int'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='5d6479ae' name='propvalue'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_userquota' mangled-name='zfs_prop_get_userquota' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_userquota'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='26a90f95' name='propbuf'/>
- <parameter type-id='95e97e5e' name='proplen'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_written_int' mangled-name='zfs_prop_get_written_int' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_written_int'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='5d6479ae' name='propvalue'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_get_written' mangled-name='zfs_prop_get_written' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_written'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='26a90f95' name='propbuf'/>
- <parameter type-id='95e97e5e' name='proplen'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_get_pool_name' mangled-name='zfs_get_pool_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_pool_name'>
- <parameter type-id='fcd57163' name='zhp'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_get_type' mangled-name='zfs_get_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_type'>
- <parameter type-id='fcd57163' name='zhp'/>
- <return type-id='2e45de5d'/>
- </function-decl>
- <function-decl name='zfs_get_underlying_type' mangled-name='zfs_get_underlying_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_underlying_type'>
- <parameter type-id='fcd57163' name='zhp'/>
- <return type-id='2e45de5d'/>
- </function-decl>
- <function-decl name='zfs_dataset_exists' mangled-name='zfs_dataset_exists' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dataset_exists'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='2e45de5d' name='types'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_create_ancestors' mangled-name='zfs_create_ancestors' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_create_ancestors'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_create' mangled-name='zfs_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_create'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='2e45de5d' name='type'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_destroy' mangled-name='zfs_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_destroy'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='c19b74c3' name='defer'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_destroy_snaps' mangled-name='zfs_destroy_snaps' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_destroy_snaps'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='26a90f95' name='snapname'/>
- <parameter type-id='c19b74c3' name='defer'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_destroy_snaps_nvl' mangled-name='zfs_destroy_snaps_nvl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_destroy_snaps_nvl'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='5ce45b60' name='snaps'/>
- <parameter type-id='c19b74c3' name='defer'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_clone' mangled-name='zfs_clone' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_clone'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='target'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_promote' mangled-name='zfs_promote' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_promote'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_snapshot_nvl' mangled-name='zfs_snapshot_nvl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_snapshot_nvl'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='5ce45b60' name='snaps'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_snapshot' mangled-name='zfs_snapshot' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_snapshot'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='c19b74c3' name='recursive'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_rollback' mangled-name='zfs_rollback' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_rollback'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='9200a744' name='snap'/>
- <parameter type-id='c19b74c3' name='force'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_rename' mangled-name='zfs_rename' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_rename'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='target'/>
- <parameter type-id='067170c2' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_get_all_props' mangled-name='zfs_get_all_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_all_props'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_get_recvd_props' mangled-name='zfs_get_recvd_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_recvd_props'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_get_user_props' mangled-name='zfs_get_user_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_user_props'>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_expand_proplist' mangled-name='zfs_expand_proplist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_expand_proplist'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='e4378506' name='plp'/>
- <parameter type-id='c19b74c3' name='received'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prune_proplist' mangled-name='zfs_prune_proplist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prune_proplist'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='ae3e8ca6' name='props'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_smb_acl_add' mangled-name='zfs_smb_acl_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_smb_acl_add'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='dataset'/>
- <parameter type-id='26a90f95' name='path'/>
- <parameter type-id='26a90f95' name='resource'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_smb_acl_remove' mangled-name='zfs_smb_acl_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_smb_acl_remove'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='dataset'/>
- <parameter type-id='26a90f95' name='path'/>
- <parameter type-id='26a90f95' name='resource'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_smb_acl_purge' mangled-name='zfs_smb_acl_purge' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_smb_acl_purge'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='dataset'/>
- <parameter type-id='26a90f95' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_smb_acl_rename' mangled-name='zfs_smb_acl_rename' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_smb_acl_rename'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='dataset'/>
- <parameter type-id='26a90f95' name='path'/>
- <parameter type-id='26a90f95' name='oldname'/>
- <parameter type-id='26a90f95' name='newname'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_userspace' mangled-name='zfs_userspace' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_userspace'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='279fde6a' name='type'/>
- <parameter type-id='16c5f410' name='func'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_hold' mangled-name='zfs_hold' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_hold'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='snapname'/>
- <parameter type-id='80f4b756' name='tag'/>
- <parameter type-id='c19b74c3' name='recursive'/>
- <parameter type-id='95e97e5e' name='cleanup_fd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_hold_nvl' mangled-name='zfs_hold_nvl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_hold_nvl'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='95e97e5e' name='cleanup_fd'/>
- <parameter type-id='5ce45b60' name='holds'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_release' mangled-name='zfs_release' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_release'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='snapname'/>
- <parameter type-id='80f4b756' name='tag'/>
- <parameter type-id='c19b74c3' name='recursive'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_get_fsacl' mangled-name='zfs_get_fsacl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_fsacl'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='857bb57e' name='nvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_set_fsacl' mangled-name='zfs_set_fsacl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_set_fsacl'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='c19b74c3' name='un'/>
- <parameter type-id='5ce45b60' name='nvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_get_holds' mangled-name='zfs_get_holds' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_holds'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='857bb57e' name='nvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zvol_volsize_to_reservation' mangled-name='zvol_volsize_to_reservation' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zvol_volsize_to_reservation'>
- <parameter type-id='4c81de99' name='zph'/>
- <parameter type-id='9c313c2d' name='volsize'/>
- <parameter type-id='5ce45b60' name='props'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_wait_status' mangled-name='zfs_wait_status' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_wait_status'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='3024501a' name='activity'/>
- <parameter type-id='37e3bd22' name='missing'/>
- <parameter type-id='37e3bd22' name='waited'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_error_fmt' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_standard_error_fmt' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_setprop_error' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='58603c44'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='26a90f95'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_parse_value' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='3fa542f0'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='2e45de5d'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='7d3cd834'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_expand_list' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4378506'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zcmd_write_src_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='changelist_prefix' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='changelist_postfix' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='changelist_rename' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='changelist_remove' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='changelist_free' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='changelist_gather' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <parameter type-id='58603c44'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='0d41d328'/>
- </function-decl>
- <function-decl name='changelist_haszonedchild' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_name_valid' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-type size-in-bits='64' id='02362c02'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='354978ed'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='95e97e5e'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_diff.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='448' id='6093ff7c'>
- <subrange length='56' type-id='7359adad' id='f8137894'/>
- </array-type-def>
- <typedef-decl name='pthread_t' type-id='7359adad' id='4051f5e7'/>
- <union-decl name='pthread_attr_t' size-in-bits='448' visibility='default' id='b63afacd'>
- <data-member access='public'>
- <var-decl name='__size' type-id='6093ff7c' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='__align' type-id='bd54fe1a' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='pthread_attr_t' type-id='b63afacd' id='7d8569fd'/>
- <class-decl name='differ_info' size-in-bits='9088' is-struct='yes' visibility='default' id='d41965ee'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zhp' type-id='9200a744' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='fromsnap' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='frommnt' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='tosnap' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='tomnt' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='ds' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='dsmnt' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='tmpsnap' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='errbuf' type-id='b54ce520' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8704'>
- <var-decl name='isclone' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8736'>
- <var-decl name='scripted' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8768'>
- <var-decl name='classify' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8800'>
- <var-decl name='timestamped' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8832'>
- <var-decl name='no_mangle' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8896'>
- <var-decl name='shares' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8960'>
- <var-decl name='zerr' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8992'>
- <var-decl name='cleanupfd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='9024'>
- <var-decl name='outputfd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='9056'>
- <var-decl name='datafd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='differ_info_t' type-id='d41965ee' id='e8525f0e'/>
- <qualified-type-def type-id='7d8569fd' const='yes' id='e06dee2d'/>
- <pointer-type-def type-id='e06dee2d' size-in-bits='64' id='540db505'/>
- <qualified-type-def type-id='540db505' restrict='yes' id='e1815e87'/>
- <pointer-type-def type-id='e8525f0e' size-in-bits='64' id='ee78f675'/>
- <pointer-type-def type-id='4051f5e7' size-in-bits='64' id='e01b5462'/>
- <qualified-type-def type-id='e01b5462' restrict='yes' id='cc338b26'/>
- <pointer-type-def type-id='cd5d79f4' size-in-bits='64' id='5ad9edb6'/>
- <function-decl name='is_mounted' mangled-name='is_mounted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='is_mounted'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9b23c9ad'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='color_start' mangled-name='color_start' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_start'>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='color_end' mangled-name='color_end' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='color_end'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='pthread_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='cc338b26'/>
- <parameter type-id='e1815e87'/>
- <parameter type-id='5ad9edb6'/>
- <parameter type-id='1b7446cd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_join' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='4051f5e7'/>
- <parameter type-id='63e171df'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_cancel' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='4051f5e7'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fputs' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='e75a27e9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pipe2' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='7292109c'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_show_diffs' mangled-name='zfs_show_diffs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_show_diffs'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='95e97e5e' name='outfd'/>
- <parameter type-id='80f4b756' name='fromsnap'/>
- <parameter type-id='80f4b756' name='tosnap'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_asprintf' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zfs_validate_name' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='find_shares_object' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='ee78f675'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='cd5d79f4'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='eaa32e2f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_import.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>
- <subrange length='3' type-id='7359adad' id='56f209d2'/>
- </array-type-def>
- <typedef-decl name='refresh_config_func_t' type-id='29f040d2' id='b7c58eaa'/>
- <typedef-decl name='pool_active_func_t' type-id='baa42fef' id='de5d1d8f'/>
- <class-decl name='pool_config_ops' size-in-bits='128' is-struct='yes' visibility='default' id='8b092c69'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='pco_refresh_config' type-id='e7c00489' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='pco_pool_active' type-id='9eadf5e0' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='pool_config_ops_t' type-id='1a21babe' id='b1e62775'/>
- <enum-decl name='pool_state' id='4871ac24'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='POOL_STATE_ACTIVE' value='0'/>
- <enumerator name='POOL_STATE_EXPORTED' value='1'/>
- <enumerator name='POOL_STATE_DESTROYED' value='2'/>
- <enumerator name='POOL_STATE_SPARE' value='3'/>
- <enumerator name='POOL_STATE_L2CACHE' value='4'/>
- <enumerator name='POOL_STATE_UNINITIALIZED' value='5'/>
- <enumerator name='POOL_STATE_UNAVAIL' value='6'/>
- <enumerator name='POOL_STATE_POTENTIALLY_ACTIVE' value='7'/>
- </enum-decl>
- <typedef-decl name='pool_state_t' type-id='4871ac24' id='084a08a3'/>
- <class-decl name='stat64' size-in-bits='1152' is-struct='yes' visibility='default' id='0bbec9cd'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='st_dev' type-id='35ed8932' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='st_ino' type-id='71288a47' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='st_nlink' type-id='80f0b9df' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='st_mode' type-id='e1c52942' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='st_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='st_gid' type-id='d94ec6d9' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='__pad0' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='st_rdev' type-id='35ed8932' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='st_size' type-id='79989e9c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='st_blksize' type-id='d3f10a7f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='st_blocks' type-id='4e711bf1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='st_atim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='st_mtim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='st_ctim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='960'>
- <var-decl name='__glibc_reserved' type-id='083f8d58' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__dev_t' type-id='7359adad' id='35ed8932'/>
- <typedef-decl name='__ino64_t' type-id='7359adad' id='71288a47'/>
- <typedef-decl name='__mode_t' type-id='f0981eeb' id='e1c52942'/>
- <typedef-decl name='__nlink_t' type-id='7359adad' id='80f0b9df'/>
- <typedef-decl name='__blksize_t' type-id='bd54fe1a' id='d3f10a7f'/>
- <typedef-decl name='__blkcnt64_t' type-id='bd54fe1a' id='4e711bf1'/>
- <typedef-decl name='__syscall_slong_t' type-id='bd54fe1a' id='03085adc'/>
- <class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' id='a9c79a1f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tv_sec' type-id='65eda9c0' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tv_nsec' type-id='03085adc' visibility='default'/>
- </data-member>
- </class-decl>
- <qualified-type-def type-id='8b092c69' const='yes' id='1a21babe'/>
- <pointer-type-def type-id='de5d1d8f' size-in-bits='64' id='9eadf5e0'/>
- <pointer-type-def type-id='084a08a3' size-in-bits='64' id='b9ea57b8'/>
- <pointer-type-def type-id='b7c58eaa' size-in-bits='64' id='e7c00489'/>
- <pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
- <var-decl name='libzfs_config_ops' type-id='b1e62775' mangled-name='libzfs_config_ops' visibility='default' elf-symbol-id='libzfs_config_ops'/>
- <function-decl name='zpool_read_label' mangled-name='zpool_read_label' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_read_label'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='857bb57e'/>
- <parameter type-id='7292109c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pwrite64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='724e4de6'/>
- <return type-id='79a0948f'/>
- </function-decl>
- <function-decl name='__pread64_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='724e4de6'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='79a0948f'/>
- </function-decl>
- <function-decl name='ioctl' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='7359adad'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fstat64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='62f7a03d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zcmd_write_conf_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_clear_label' mangled-name='zpool_clear_label' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_clear_label'>
- <parameter type-id='95e97e5e' name='fd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_in_use' mangled-name='zpool_in_use' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_in_use'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='95e97e5e' name='fd'/>
- <parameter type-id='b9ea57b8' name='state'/>
- <parameter type-id='9b23c9ad' name='namestr'/>
- <parameter type-id='37e3bd22' name='inuse'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='baa42fef'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='37e3bd22'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='29f040d2'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='5ce45b60'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_iter.c' language='LANG_C99'>
- <pointer-type-def type-id='b351119f' size-in-bits='64' id='716943c7'/>
- <function-decl name='avl_first' mangled-name='avl_first' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_first'>
- <parameter type-id='a3681dea'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='avl_walk' mangled-name='avl_walk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_walk'>
- <parameter type-id='716943c7'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='make_dataset_handle_zc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='e4ec4540'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='make_dataset_simple_handle_zc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <parameter type-id='e4ec4540'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='make_bookmark_handle' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='zfs_iter_filesystems' mangled-name='zfs_iter_filesystems' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_snapshots' mangled-name='zfs_iter_snapshots' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='c19b74c3' name='simple'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <parameter type-id='9c313c2d' name='min_txg'/>
- <parameter type-id='9c313c2d' name='max_txg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_bookmarks' mangled-name='zfs_iter_bookmarks' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_snapshots_sorted' mangled-name='zfs_iter_snapshots_sorted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_sorted'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='d8e49ab9' name='callback'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <parameter type-id='9c313c2d' name='min_txg'/>
- <parameter type-id='9c313c2d' name='max_txg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_snapshots_sorted_v2' mangled-name='zfs_iter_snapshots_sorted_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_sorted_v2'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <parameter type-id='d8e49ab9' name='callback'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <parameter type-id='9c313c2d' name='min_txg'/>
- <parameter type-id='9c313c2d' name='max_txg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_snapspec' mangled-name='zfs_iter_snapspec' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapspec'>
- <parameter type-id='9200a744' name='fs_zhp'/>
- <parameter type-id='80f4b756' name='spec_orig'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_snapspec_v2' mangled-name='zfs_iter_snapspec_v2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapspec_v2'>
- <parameter type-id='9200a744' name='fs_zhp'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <parameter type-id='80f4b756' name='spec_orig'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='arg'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_children' mangled-name='zfs_iter_children' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_iter_dependents' mangled-name='zfs_iter_dependents' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='c19b74c3' name='allowrecursion'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_mount.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='6028cbfe' size-in-bits='256' id='b39b9aa7'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='20cd73f2'/>
- <class-decl name='tpool' size-in-bits='2496' is-struct='yes' visibility='default' id='88d1b7f9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tp_forw' type-id='9cf59a50' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='tp_back' type-id='9cf59a50' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='tp_mutex' type-id='7a6844eb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='tp_busycv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='tp_workcv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1216'>
- <var-decl name='tp_waitcv' type-id='62fab762' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1600'>
- <var-decl name='tp_active' type-id='ad33e5e7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1664'>
- <var-decl name='tp_head' type-id='f32b30e4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1728'>
- <var-decl name='tp_tail' type-id='f32b30e4' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1792'>
- <var-decl name='tp_attr' type-id='7d8569fd' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2240'>
- <var-decl name='tp_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2272'>
- <var-decl name='tp_linger' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2304'>
- <var-decl name='tp_njobs' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2336'>
- <var-decl name='tp_minimum' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2368'>
- <var-decl name='tp_maximum' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2400'>
- <var-decl name='tp_current' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2432'>
- <var-decl name='tp_idle' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='64' id='e4266c7e'>
- <subrange length='2' type-id='7359adad' id='52efc4ef'/>
- </array-type-def>
- <class-decl name='get_all_cb' size-in-bits='192' is-struct='yes' visibility='default' id='803dac95'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='cb_handles' type-id='4507922a' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='cb_alloc' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='cb_used' type-id='b59d7dce' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='get_all_cb_t' type-id='803dac95' id='9b293607'/>
- <typedef-decl name='tpool_t' type-id='88d1b7f9' id='b1bbf10d'/>
- <typedef-decl name='DIR' type-id='20cd73f2' id='54a5d683'/>
- <typedef-decl name='mode_t' type-id='e1c52942' id='d50d396c'/>
- <typedef-decl name='__compar_fn_t' type-id='585e1de9' id='aba7edd8'/>
- <class-decl name='dirent64' size-in-bits='2240' is-struct='yes' visibility='default' id='5725d813'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='d_ino' type-id='71288a47' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='d_off' type-id='724e4de6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='d_reclen' type-id='8efea9e5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='144'>
- <var-decl name='d_type' type-id='002ac4a6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='152'>
- <var-decl name='d_name' type-id='d1617432' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='statfs64' size-in-bits='960' is-struct='yes' visibility='default' id='a2a6be1a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='f_type' type-id='6028cbfe' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='f_bsize' type-id='6028cbfe' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='f_blocks' type-id='95fe1a02' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='f_bfree' type-id='95fe1a02' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='f_bavail' type-id='95fe1a02' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='f_files' type-id='0c3a4dde' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='f_ffree' type-id='0c3a4dde' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='f_fsid' type-id='0f35d263' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='f_namelen' type-id='6028cbfe' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='f_frsize' type-id='6028cbfe' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='640'>
- <var-decl name='f_flags' type-id='6028cbfe' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='f_spare' type-id='b39b9aa7' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='stat' size-in-bits='1152' is-struct='yes' visibility='default' id='aafc373f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='st_dev' type-id='35ed8932' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='st_ino' type-id='e43e523d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='st_nlink' type-id='80f0b9df' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='st_mode' type-id='e1c52942' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='st_uid' type-id='cc5fcceb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='st_gid' type-id='d94ec6d9' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='__pad0' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='st_rdev' type-id='35ed8932' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='st_size' type-id='79989e9c' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='st_blksize' type-id='d3f10a7f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='st_blocks' type-id='dbc43803' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='st_atim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='st_mtim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='st_ctim' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='960'>
- <var-decl name='__glibc_reserved' type-id='083f8d58' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__ino_t' type-id='7359adad' id='e43e523d'/>
- <class-decl name='__fsid_t' size-in-bits='64' is-struct='yes' naming-typedef-id='0f35d263' visibility='default' id='ea35c84a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__val' type-id='e4266c7e' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__fsid_t' type-id='ea35c84a' id='0f35d263'/>
- <typedef-decl name='__blkcnt_t' type-id='bd54fe1a' id='dbc43803'/>
- <typedef-decl name='__fsblkcnt64_t' type-id='7359adad' id='95fe1a02'/>
- <typedef-decl name='__fsfilcnt64_t' type-id='7359adad' id='0c3a4dde'/>
- <typedef-decl name='__fsword_t' type-id='bd54fe1a' id='6028cbfe'/>
- <pointer-type-def type-id='54a5d683' size-in-bits='64' id='f09217ba'/>
- <pointer-type-def type-id='5725d813' size-in-bits='64' id='07b96073'/>
- <pointer-type-def type-id='9b293607' size-in-bits='64' id='77bf1784'/>
- <pointer-type-def type-id='7d8569fd' size-in-bits='64' id='7347a39e'/>
- <pointer-type-def type-id='aafc373f' size-in-bits='64' id='4330df87'/>
- <qualified-type-def type-id='4330df87' restrict='yes' id='73665405'/>
- <pointer-type-def type-id='a2a6be1a' size-in-bits='64' id='7fd094c8'/>
- <pointer-type-def type-id='b1bbf10d' size-in-bits='64' id='9cf59a50'/>
- <pointer-type-def type-id='c5c76c9c' size-in-bits='64' id='b7f9d8e6'/>
- <pointer-type-def type-id='9200a744' size-in-bits='64' id='4507922a'/>
- <class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='20cd73f2'/>
- <function-decl name='zpool_disable_datasets_os' mangled-name='zpool_disable_datasets_os' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_disable_datasets_os'>
- <parameter type-id='4c81de99'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_disable_volume_os' mangled-name='zpool_disable_volume_os' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_disable_volume_os'>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='tpool_create' mangled-name='tpool_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_create'>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='7347a39e'/>
- <return type-id='9cf59a50'/>
- </function-decl>
- <function-decl name='tpool_dispatch' mangled-name='tpool_dispatch' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_dispatch'>
- <parameter type-id='9cf59a50'/>
- <parameter type-id='b7f9d8e6'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='tpool_destroy' mangled-name='tpool_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_destroy'>
- <parameter type-id='9cf59a50'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='tpool_wait' mangled-name='tpool_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='tpool_wait'>
- <parameter type-id='9cf59a50'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='mkdirp' mangled-name='mkdirp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='mkdirp'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='d50d396c'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sa_errorstr' mangled-name='sa_errorstr' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_errorstr'>
- <parameter type-id='95e97e5e'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='sa_enable_share' mangled-name='sa_enable_share' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_enable_share'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9155d4b5'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sa_disable_share' mangled-name='sa_disable_share' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_disable_share'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9155d4b5'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sa_is_shared' mangled-name='sa_is_shared' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_is_shared'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9155d4b5'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='sa_truncate_shares' mangled-name='sa_truncate_shares' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sa_truncate_shares'>
- <parameter type-id='9155d4b5'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fdopendir' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='f09217ba'/>
- </function-decl>
- <function-decl name='closedir' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f09217ba'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='readdir64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f09217ba'/>
- <return type-id='07b96073'/>
- </function-decl>
- <function-decl name='qsort' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='aba7edd8'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='rmdir' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__openat_too_many_args' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__openat_missing_mode' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='statfs64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='7fd094c8'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_realloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='changelist_unshare' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0d41d328'/>
- <parameter type-id='4567bbc9'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='do_mount' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='do_unmount' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9200a744'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_mount_at' mangled-name='zfs_mount_at' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_mount_at'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='options'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <parameter type-id='80f4b756' name='mountpoint'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_unmountall' mangled-name='zfs_unmountall' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_unmountall'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_truncate_shares' mangled-name='zfs_truncate_shares' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_truncate_shares'>
- <parameter type-id='4567bbc9' name='proto'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_unshareall' mangled-name='zfs_unshareall' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_unshareall'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='4567bbc9' name='proto'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_add_handle' mangled-name='libzfs_add_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_add_handle'>
- <parameter type-id='77bf1784' name='cbp'/>
- <parameter type-id='9200a744' name='zhp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_foreach_mountpoint' mangled-name='zfs_foreach_mountpoint' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_foreach_mountpoint'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='4507922a' name='handles'/>
- <parameter type-id='b59d7dce' name='num_handles'/>
- <parameter type-id='d8e49ab9' name='func'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <parameter type-id='3502e3ff' name='nthr'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_enable_datasets' mangled-name='zpool_enable_datasets' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_enable_datasets'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='mntopts'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <parameter type-id='3502e3ff' name='nthr'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_disable_datasets' mangled-name='zpool_disable_datasets' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_disable_datasets'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='c19b74c3' name='force'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_pool.c' language='LANG_C99'>
- <type-decl name='long long unsigned int' size-in-bits='64' id='3a47d82b'/>
- <class-decl name='splitflags' size-in-bits='64' is-struct='yes' visibility='default' id='dc01bf52'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='dryrun' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1'>
- <var-decl name='import' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='name_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='splitflags_t' type-id='dc01bf52' id='325c1e34'/>
- <class-decl name='trimflags' size-in-bits='192' is-struct='yes' visibility='default' id='8ef58008'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='fullpool' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='secure' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='wait' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='rate' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='trimflags_t' type-id='8ef58008' id='a093cbb8'/>
- <enum-decl name='zpool_status_t' naming-typedef-id='d3dd6294' id='5e770b40'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_STATUS_CORRUPT_CACHE' value='0'/>
- <enumerator name='ZPOOL_STATUS_MISSING_DEV_R' value='1'/>
- <enumerator name='ZPOOL_STATUS_MISSING_DEV_NR' value='2'/>
- <enumerator name='ZPOOL_STATUS_CORRUPT_LABEL_R' value='3'/>
- <enumerator name='ZPOOL_STATUS_CORRUPT_LABEL_NR' value='4'/>
- <enumerator name='ZPOOL_STATUS_BAD_GUID_SUM' value='5'/>
- <enumerator name='ZPOOL_STATUS_CORRUPT_POOL' value='6'/>
- <enumerator name='ZPOOL_STATUS_CORRUPT_DATA' value='7'/>
- <enumerator name='ZPOOL_STATUS_FAILING_DEV' value='8'/>
- <enumerator name='ZPOOL_STATUS_VERSION_NEWER' value='9'/>
- <enumerator name='ZPOOL_STATUS_HOSTID_MISMATCH' value='10'/>
- <enumerator name='ZPOOL_STATUS_HOSTID_ACTIVE' value='11'/>
- <enumerator name='ZPOOL_STATUS_HOSTID_REQUIRED' value='12'/>
- <enumerator name='ZPOOL_STATUS_IO_FAILURE_WAIT' value='13'/>
- <enumerator name='ZPOOL_STATUS_IO_FAILURE_CONTINUE' value='14'/>
- <enumerator name='ZPOOL_STATUS_IO_FAILURE_MMP' value='15'/>
- <enumerator name='ZPOOL_STATUS_BAD_LOG' value='16'/>
- <enumerator name='ZPOOL_STATUS_ERRATA' value='17'/>
- <enumerator name='ZPOOL_STATUS_UNSUP_FEAT_READ' value='18'/>
- <enumerator name='ZPOOL_STATUS_UNSUP_FEAT_WRITE' value='19'/>
- <enumerator name='ZPOOL_STATUS_FAULTED_DEV_R' value='20'/>
- <enumerator name='ZPOOL_STATUS_FAULTED_DEV_NR' value='21'/>
- <enumerator name='ZPOOL_STATUS_VERSION_OLDER' value='22'/>
- <enumerator name='ZPOOL_STATUS_FEAT_DISABLED' value='23'/>
- <enumerator name='ZPOOL_STATUS_RESILVERING' value='24'/>
- <enumerator name='ZPOOL_STATUS_OFFLINE_DEV' value='25'/>
- <enumerator name='ZPOOL_STATUS_REMOVED_DEV' value='26'/>
- <enumerator name='ZPOOL_STATUS_REBUILDING' value='27'/>
- <enumerator name='ZPOOL_STATUS_REBUILD_SCRUB' value='28'/>
- <enumerator name='ZPOOL_STATUS_NON_NATIVE_ASHIFT' value='29'/>
- <enumerator name='ZPOOL_STATUS_COMPATIBILITY_ERR' value='30'/>
- <enumerator name='ZPOOL_STATUS_INCOMPATIBLE_FEAT' value='31'/>
- <enumerator name='ZPOOL_STATUS_OK' value='32'/>
- </enum-decl>
- <typedef-decl name='zpool_status_t' type-id='5e770b40' id='d3dd6294'/>
- <enum-decl name='zpool_compat_status_t' naming-typedef-id='901b78d1' id='20676925'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_COMPATIBILITY_OK' value='0'/>
- <enumerator name='ZPOOL_COMPATIBILITY_WARNTOKEN' value='1'/>
- <enumerator name='ZPOOL_COMPATIBILITY_BADTOKEN' value='2'/>
- <enumerator name='ZPOOL_COMPATIBILITY_BADFILE' value='3'/>
- <enumerator name='ZPOOL_COMPATIBILITY_NOFILES' value='4'/>
- </enum-decl>
- <typedef-decl name='zpool_compat_status_t' type-id='20676925' id='901b78d1'/>
- <enum-decl name='vdev_prop_t' naming-typedef-id='5aa5c90c' id='1573bec8'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='VDEV_PROP_INVAL' value='-1'/>
- <enumerator name='VDEV_PROP_USERPROP' value='-1'/>
- <enumerator name='VDEV_PROP_NAME' value='0'/>
- <enumerator name='VDEV_PROP_CAPACITY' value='1'/>
- <enumerator name='VDEV_PROP_STATE' value='2'/>
- <enumerator name='VDEV_PROP_GUID' value='3'/>
- <enumerator name='VDEV_PROP_ASIZE' value='4'/>
- <enumerator name='VDEV_PROP_PSIZE' value='5'/>
- <enumerator name='VDEV_PROP_ASHIFT' value='6'/>
- <enumerator name='VDEV_PROP_SIZE' value='7'/>
- <enumerator name='VDEV_PROP_FREE' value='8'/>
- <enumerator name='VDEV_PROP_ALLOCATED' value='9'/>
- <enumerator name='VDEV_PROP_COMMENT' value='10'/>
- <enumerator name='VDEV_PROP_EXPANDSZ' value='11'/>
- <enumerator name='VDEV_PROP_FRAGMENTATION' value='12'/>
- <enumerator name='VDEV_PROP_BOOTSIZE' value='13'/>
- <enumerator name='VDEV_PROP_PARITY' value='14'/>
- <enumerator name='VDEV_PROP_PATH' value='15'/>
- <enumerator name='VDEV_PROP_DEVID' value='16'/>
- <enumerator name='VDEV_PROP_PHYS_PATH' value='17'/>
- <enumerator name='VDEV_PROP_ENC_PATH' value='18'/>
- <enumerator name='VDEV_PROP_FRU' value='19'/>
- <enumerator name='VDEV_PROP_PARENT' value='20'/>
- <enumerator name='VDEV_PROP_CHILDREN' value='21'/>
- <enumerator name='VDEV_PROP_NUMCHILDREN' value='22'/>
- <enumerator name='VDEV_PROP_READ_ERRORS' value='23'/>
- <enumerator name='VDEV_PROP_WRITE_ERRORS' value='24'/>
- <enumerator name='VDEV_PROP_CHECKSUM_ERRORS' value='25'/>
- <enumerator name='VDEV_PROP_INITIALIZE_ERRORS' value='26'/>
- <enumerator name='VDEV_PROP_OPS_NULL' value='27'/>
- <enumerator name='VDEV_PROP_OPS_READ' value='28'/>
- <enumerator name='VDEV_PROP_OPS_WRITE' value='29'/>
- <enumerator name='VDEV_PROP_OPS_FREE' value='30'/>
- <enumerator name='VDEV_PROP_OPS_CLAIM' value='31'/>
- <enumerator name='VDEV_PROP_OPS_TRIM' value='32'/>
- <enumerator name='VDEV_PROP_BYTES_NULL' value='33'/>
- <enumerator name='VDEV_PROP_BYTES_READ' value='34'/>
- <enumerator name='VDEV_PROP_BYTES_WRITE' value='35'/>
- <enumerator name='VDEV_PROP_BYTES_FREE' value='36'/>
- <enumerator name='VDEV_PROP_BYTES_CLAIM' value='37'/>
- <enumerator name='VDEV_PROP_BYTES_TRIM' value='38'/>
- <enumerator name='VDEV_PROP_REMOVING' value='39'/>
- <enumerator name='VDEV_PROP_ALLOCATING' value='40'/>
- <enumerator name='VDEV_PROP_FAILFAST' value='41'/>
- <enumerator name='VDEV_PROP_CHECKSUM_N' value='42'/>
- <enumerator name='VDEV_PROP_CHECKSUM_T' value='43'/>
- <enumerator name='VDEV_PROP_IO_N' value='44'/>
- <enumerator name='VDEV_PROP_IO_T' value='45'/>
- <enumerator name='VDEV_PROP_RAIDZ_EXPANDING' value='46'/>
- <enumerator name='VDEV_PROP_SLOW_IO_N' value='47'/>
- <enumerator name='VDEV_PROP_SLOW_IO_T' value='48'/>
- <enumerator name='VDEV_PROP_TRIM_SUPPORT' value='49'/>
- <enumerator name='VDEV_PROP_TRIM_ERRORS' value='50'/>
- <enumerator name='VDEV_PROP_SLOW_IOS' value='51'/>
- <enumerator name='VDEV_PROP_SIT_OUT' value='52'/>
- <enumerator name='VDEV_PROP_AUTOSIT' value='53'/>
- <enumerator name='VDEV_NUM_PROPS' value='54'/>
- </enum-decl>
- <typedef-decl name='vdev_prop_t' type-id='1573bec8' id='5aa5c90c'/>
- <class-decl name='zpool_load_policy' size-in-bits='256' is-struct='yes' visibility='default' id='2f65b36f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zlp_rewind' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='zlp_maxmeta' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='zlp_maxdata' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='zlp_txg' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zpool_load_policy_t' type-id='2f65b36f' id='d11b7617'/>
- <enum-decl name='vdev_state' id='21566197'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='VDEV_STATE_UNKNOWN' value='0'/>
- <enumerator name='VDEV_STATE_CLOSED' value='1'/>
- <enumerator name='VDEV_STATE_OFFLINE' value='2'/>
- <enumerator name='VDEV_STATE_REMOVED' value='3'/>
- <enumerator name='VDEV_STATE_CANT_OPEN' value='4'/>
- <enumerator name='VDEV_STATE_FAULTED' value='5'/>
- <enumerator name='VDEV_STATE_DEGRADED' value='6'/>
- <enumerator name='VDEV_STATE_HEALTHY' value='7'/>
- </enum-decl>
- <typedef-decl name='vdev_state_t' type-id='21566197' id='35acf840'/>
- <enum-decl name='vdev_aux' id='7f5bcca4'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='VDEV_AUX_NONE' value='0'/>
- <enumerator name='VDEV_AUX_OPEN_FAILED' value='1'/>
- <enumerator name='VDEV_AUX_CORRUPT_DATA' value='2'/>
- <enumerator name='VDEV_AUX_NO_REPLICAS' value='3'/>
- <enumerator name='VDEV_AUX_BAD_GUID_SUM' value='4'/>
- <enumerator name='VDEV_AUX_TOO_SMALL' value='5'/>
- <enumerator name='VDEV_AUX_BAD_LABEL' value='6'/>
- <enumerator name='VDEV_AUX_VERSION_NEWER' value='7'/>
- <enumerator name='VDEV_AUX_VERSION_OLDER' value='8'/>
- <enumerator name='VDEV_AUX_UNSUP_FEAT' value='9'/>
- <enumerator name='VDEV_AUX_SPARED' value='10'/>
- <enumerator name='VDEV_AUX_ERR_EXCEEDED' value='11'/>
- <enumerator name='VDEV_AUX_IO_FAILURE' value='12'/>
- <enumerator name='VDEV_AUX_BAD_LOG' value='13'/>
- <enumerator name='VDEV_AUX_EXTERNAL' value='14'/>
- <enumerator name='VDEV_AUX_SPLIT_POOL' value='15'/>
- <enumerator name='VDEV_AUX_BAD_ASHIFT' value='16'/>
- <enumerator name='VDEV_AUX_EXTERNAL_PERSIST' value='17'/>
- <enumerator name='VDEV_AUX_ACTIVE' value='18'/>
- <enumerator name='VDEV_AUX_CHILDREN_OFFLINE' value='19'/>
- <enumerator name='VDEV_AUX_ASHIFT_TOO_BIG' value='20'/>
- </enum-decl>
- <typedef-decl name='vdev_aux_t' type-id='7f5bcca4' id='9d774e0b'/>
- <enum-decl name='pool_scan_func' id='1b092565'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='POOL_SCAN_NONE' value='0'/>
- <enumerator name='POOL_SCAN_SCRUB' value='1'/>
- <enumerator name='POOL_SCAN_RESILVER' value='2'/>
- <enumerator name='POOL_SCAN_ERRORSCRUB' value='3'/>
- <enumerator name='POOL_SCAN_FUNCS' value='4'/>
- </enum-decl>
- <typedef-decl name='pool_scan_func_t' type-id='1b092565' id='7313fbe2'/>
- <enum-decl name='pool_scrub_cmd' id='a1474cbd'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='POOL_SCRUB_NORMAL' value='0'/>
- <enumerator name='POOL_SCRUB_PAUSE' value='1'/>
- <enumerator name='POOL_SCRUB_FROM_LAST_TXG' value='2'/>
- <enumerator name='POOL_SCRUB_FLAGS_END' value='3'/>
- </enum-decl>
- <typedef-decl name='pool_scrub_cmd_t' type-id='a1474cbd' id='b51cf3c2'/>
- <enum-decl name='zpool_errata' id='d9abbf54'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_ERRATA_NONE' value='0'/>
- <enumerator name='ZPOOL_ERRATA_ZOL_2094_SCRUB' value='1'/>
- <enumerator name='ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY' value='2'/>
- <enumerator name='ZPOOL_ERRATA_ZOL_6845_ENCRYPTION' value='3'/>
- <enumerator name='ZPOOL_ERRATA_ZOL_8308_ENCRYPTION' value='4'/>
- </enum-decl>
- <typedef-decl name='zpool_errata_t' type-id='d9abbf54' id='688c495b'/>
- <enum-decl name='pool_initialize_func' id='5c246ad4'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='POOL_INITIALIZE_START' value='0'/>
- <enumerator name='POOL_INITIALIZE_CANCEL' value='1'/>
- <enumerator name='POOL_INITIALIZE_SUSPEND' value='2'/>
- <enumerator name='POOL_INITIALIZE_UNINIT' value='3'/>
- <enumerator name='POOL_INITIALIZE_FUNCS' value='4'/>
- </enum-decl>
- <typedef-decl name='pool_initialize_func_t' type-id='5c246ad4' id='7063e1ab'/>
- <enum-decl name='pool_trim_func' id='54ed608a'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='POOL_TRIM_START' value='0'/>
- <enumerator name='POOL_TRIM_CANCEL' value='1'/>
- <enumerator name='POOL_TRIM_SUSPEND' value='2'/>
- <enumerator name='POOL_TRIM_FUNCS' value='3'/>
- </enum-decl>
- <typedef-decl name='pool_trim_func_t' type-id='54ed608a' id='b1146b8d'/>
- <enum-decl name='zfs_ioc' id='12033f13'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_IOC_FIRST' value='23040'/>
- <enumerator name='ZFS_IOC' value='23040'/>
- <enumerator name='ZFS_IOC_POOL_CREATE' value='23040'/>
- <enumerator name='ZFS_IOC_POOL_DESTROY' value='23041'/>
- <enumerator name='ZFS_IOC_POOL_IMPORT' value='23042'/>
- <enumerator name='ZFS_IOC_POOL_EXPORT' value='23043'/>
- <enumerator name='ZFS_IOC_POOL_CONFIGS' value='23044'/>
- <enumerator name='ZFS_IOC_POOL_STATS' value='23045'/>
- <enumerator name='ZFS_IOC_POOL_TRYIMPORT' value='23046'/>
- <enumerator name='ZFS_IOC_POOL_SCAN' value='23047'/>
- <enumerator name='ZFS_IOC_POOL_FREEZE' value='23048'/>
- <enumerator name='ZFS_IOC_POOL_UPGRADE' value='23049'/>
- <enumerator name='ZFS_IOC_POOL_GET_HISTORY' value='23050'/>
- <enumerator name='ZFS_IOC_VDEV_ADD' value='23051'/>
- <enumerator name='ZFS_IOC_VDEV_REMOVE' value='23052'/>
- <enumerator name='ZFS_IOC_VDEV_SET_STATE' value='23053'/>
- <enumerator name='ZFS_IOC_VDEV_ATTACH' value='23054'/>
- <enumerator name='ZFS_IOC_VDEV_DETACH' value='23055'/>
- <enumerator name='ZFS_IOC_VDEV_SETPATH' value='23056'/>
- <enumerator name='ZFS_IOC_VDEV_SETFRU' value='23057'/>
- <enumerator name='ZFS_IOC_OBJSET_STATS' value='23058'/>
- <enumerator name='ZFS_IOC_OBJSET_ZPLPROPS' value='23059'/>
- <enumerator name='ZFS_IOC_DATASET_LIST_NEXT' value='23060'/>
- <enumerator name='ZFS_IOC_SNAPSHOT_LIST_NEXT' value='23061'/>
- <enumerator name='ZFS_IOC_SET_PROP' value='23062'/>
- <enumerator name='ZFS_IOC_CREATE' value='23063'/>
- <enumerator name='ZFS_IOC_DESTROY' value='23064'/>
- <enumerator name='ZFS_IOC_ROLLBACK' value='23065'/>
- <enumerator name='ZFS_IOC_RENAME' value='23066'/>
- <enumerator name='ZFS_IOC_RECV' value='23067'/>
- <enumerator name='ZFS_IOC_SEND' value='23068'/>
- <enumerator name='ZFS_IOC_INJECT_FAULT' value='23069'/>
- <enumerator name='ZFS_IOC_CLEAR_FAULT' value='23070'/>
- <enumerator name='ZFS_IOC_INJECT_LIST_NEXT' value='23071'/>
- <enumerator name='ZFS_IOC_ERROR_LOG' value='23072'/>
- <enumerator name='ZFS_IOC_CLEAR' value='23073'/>
- <enumerator name='ZFS_IOC_PROMOTE' value='23074'/>
- <enumerator name='ZFS_IOC_SNAPSHOT' value='23075'/>
- <enumerator name='ZFS_IOC_DSOBJ_TO_DSNAME' value='23076'/>
- <enumerator name='ZFS_IOC_OBJ_TO_PATH' value='23077'/>
- <enumerator name='ZFS_IOC_POOL_SET_PROPS' value='23078'/>
- <enumerator name='ZFS_IOC_POOL_GET_PROPS' value='23079'/>
- <enumerator name='ZFS_IOC_SET_FSACL' value='23080'/>
- <enumerator name='ZFS_IOC_GET_FSACL' value='23081'/>
- <enumerator name='ZFS_IOC_SHARE' value='23082'/>
- <enumerator name='ZFS_IOC_INHERIT_PROP' value='23083'/>
- <enumerator name='ZFS_IOC_SMB_ACL' value='23084'/>
- <enumerator name='ZFS_IOC_USERSPACE_ONE' value='23085'/>
- <enumerator name='ZFS_IOC_USERSPACE_MANY' value='23086'/>
- <enumerator name='ZFS_IOC_USERSPACE_UPGRADE' value='23087'/>
- <enumerator name='ZFS_IOC_HOLD' value='23088'/>
- <enumerator name='ZFS_IOC_RELEASE' value='23089'/>
- <enumerator name='ZFS_IOC_GET_HOLDS' value='23090'/>
- <enumerator name='ZFS_IOC_OBJSET_RECVD_PROPS' value='23091'/>
- <enumerator name='ZFS_IOC_VDEV_SPLIT' value='23092'/>
- <enumerator name='ZFS_IOC_NEXT_OBJ' value='23093'/>
- <enumerator name='ZFS_IOC_DIFF' value='23094'/>
- <enumerator name='ZFS_IOC_TMP_SNAPSHOT' value='23095'/>
- <enumerator name='ZFS_IOC_OBJ_TO_STATS' value='23096'/>
- <enumerator name='ZFS_IOC_SPACE_WRITTEN' value='23097'/>
- <enumerator name='ZFS_IOC_SPACE_SNAPS' value='23098'/>
- <enumerator name='ZFS_IOC_DESTROY_SNAPS' value='23099'/>
- <enumerator name='ZFS_IOC_POOL_REGUID' value='23100'/>
- <enumerator name='ZFS_IOC_POOL_REOPEN' value='23101'/>
- <enumerator name='ZFS_IOC_SEND_PROGRESS' value='23102'/>
- <enumerator name='ZFS_IOC_LOG_HISTORY' value='23103'/>
- <enumerator name='ZFS_IOC_SEND_NEW' value='23104'/>
- <enumerator name='ZFS_IOC_SEND_SPACE' value='23105'/>
- <enumerator name='ZFS_IOC_CLONE' value='23106'/>
- <enumerator name='ZFS_IOC_BOOKMARK' value='23107'/>
- <enumerator name='ZFS_IOC_GET_BOOKMARKS' value='23108'/>
- <enumerator name='ZFS_IOC_DESTROY_BOOKMARKS' value='23109'/>
- <enumerator name='ZFS_IOC_RECV_NEW' value='23110'/>
- <enumerator name='ZFS_IOC_POOL_SYNC' value='23111'/>
- <enumerator name='ZFS_IOC_CHANNEL_PROGRAM' value='23112'/>
- <enumerator name='ZFS_IOC_LOAD_KEY' value='23113'/>
- <enumerator name='ZFS_IOC_UNLOAD_KEY' value='23114'/>
- <enumerator name='ZFS_IOC_CHANGE_KEY' value='23115'/>
- <enumerator name='ZFS_IOC_REMAP' value='23116'/>
- <enumerator name='ZFS_IOC_POOL_CHECKPOINT' value='23117'/>
- <enumerator name='ZFS_IOC_POOL_DISCARD_CHECKPOINT' value='23118'/>
- <enumerator name='ZFS_IOC_POOL_INITIALIZE' value='23119'/>
- <enumerator name='ZFS_IOC_POOL_TRIM' value='23120'/>
- <enumerator name='ZFS_IOC_REDACT' value='23121'/>
- <enumerator name='ZFS_IOC_GET_BOOKMARK_PROPS' value='23122'/>
- <enumerator name='ZFS_IOC_WAIT' value='23123'/>
- <enumerator name='ZFS_IOC_WAIT_FS' value='23124'/>
- <enumerator name='ZFS_IOC_VDEV_GET_PROPS' value='23125'/>
- <enumerator name='ZFS_IOC_VDEV_SET_PROPS' value='23126'/>
- <enumerator name='ZFS_IOC_POOL_SCRUB' value='23127'/>
- <enumerator name='ZFS_IOC_POOL_PREFETCH' value='23128'/>
- <enumerator name='ZFS_IOC_DDT_PRUNE' value='23129'/>
- <enumerator name='ZFS_IOC_PLATFORM' value='23168'/>
- <enumerator name='ZFS_IOC_EVENTS_NEXT' value='23169'/>
- <enumerator name='ZFS_IOC_EVENTS_CLEAR' value='23170'/>
- <enumerator name='ZFS_IOC_EVENTS_SEEK' value='23171'/>
- <enumerator name='ZFS_IOC_NEXTBOOT' value='23172'/>
- <enumerator name='ZFS_IOC_JAIL' value='23173'/>
- <enumerator name='ZFS_IOC_USERNS_ATTACH' value='23173'/>
- <enumerator name='ZFS_IOC_UNJAIL' value='23174'/>
- <enumerator name='ZFS_IOC_USERNS_DETACH' value='23174'/>
- <enumerator name='ZFS_IOC_SET_BOOTENV' value='23175'/>
- <enumerator name='ZFS_IOC_GET_BOOTENV' value='23176'/>
- <enumerator name='ZFS_IOC_LAST' value='23177'/>
- </enum-decl>
- <typedef-decl name='zfs_ioc_t' type-id='12033f13' id='5b35941c'/>
- <enum-decl name='zpool_wait_activity_t' naming-typedef-id='73446457' id='849338e3'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_WAIT_CKPT_DISCARD' value='0'/>
- <enumerator name='ZPOOL_WAIT_FREE' value='1'/>
- <enumerator name='ZPOOL_WAIT_INITIALIZE' value='2'/>
- <enumerator name='ZPOOL_WAIT_REPLACE' value='3'/>
- <enumerator name='ZPOOL_WAIT_REMOVE' value='4'/>
- <enumerator name='ZPOOL_WAIT_RESILVER' value='5'/>
- <enumerator name='ZPOOL_WAIT_SCRUB' value='6'/>
- <enumerator name='ZPOOL_WAIT_TRIM' value='7'/>
- <enumerator name='ZPOOL_WAIT_RAIDZ_EXPAND' value='8'/>
- <enumerator name='ZPOOL_WAIT_NUM_ACTIVITIES' value='9'/>
- </enum-decl>
- <typedef-decl name='zpool_wait_activity_t' type-id='849338e3' id='73446457'/>
- <enum-decl name='zpool_prefetch_type_t' naming-typedef-id='e55ff6bc' id='0299ab50'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_PREFETCH_NONE' value='0'/>
- <enumerator name='ZPOOL_PREFETCH_DDT' value='1'/>
- </enum-decl>
- <typedef-decl name='zpool_prefetch_type_t' type-id='0299ab50' id='e55ff6bc'/>
- <enum-decl name='zpool_ddt_prune_unit_t' naming-typedef-id='02e25ab0' id='509ae11c'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZPOOL_DDT_PRUNE_NONE' value='0'/>
- <enumerator name='ZPOOL_DDT_PRUNE_AGE' value='1'/>
- <enumerator name='ZPOOL_DDT_PRUNE_PERCENTAGE' value='2'/>
- </enum-decl>
- <typedef-decl name='zpool_ddt_prune_unit_t' type-id='509ae11c' id='02e25ab0'/>
- <enum-decl name='spa_feature' id='33ecb627'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='SPA_FEATURE_NONE' value='-1'/>
- <enumerator name='SPA_FEATURE_ASYNC_DESTROY' value='0'/>
- <enumerator name='SPA_FEATURE_EMPTY_BPOBJ' value='1'/>
- <enumerator name='SPA_FEATURE_LZ4_COMPRESS' value='2'/>
- <enumerator name='SPA_FEATURE_MULTI_VDEV_CRASH_DUMP' value='3'/>
- <enumerator name='SPA_FEATURE_SPACEMAP_HISTOGRAM' value='4'/>
- <enumerator name='SPA_FEATURE_ENABLED_TXG' value='5'/>
- <enumerator name='SPA_FEATURE_HOLE_BIRTH' value='6'/>
- <enumerator name='SPA_FEATURE_EXTENSIBLE_DATASET' value='7'/>
- <enumerator name='SPA_FEATURE_EMBEDDED_DATA' value='8'/>
- <enumerator name='SPA_FEATURE_BOOKMARKS' value='9'/>
- <enumerator name='SPA_FEATURE_FS_SS_LIMIT' value='10'/>
- <enumerator name='SPA_FEATURE_LARGE_BLOCKS' value='11'/>
- <enumerator name='SPA_FEATURE_LARGE_DNODE' value='12'/>
- <enumerator name='SPA_FEATURE_SHA512' value='13'/>
- <enumerator name='SPA_FEATURE_SKEIN' value='14'/>
- <enumerator name='SPA_FEATURE_EDONR' value='15'/>
- <enumerator name='SPA_FEATURE_USEROBJ_ACCOUNTING' value='16'/>
- <enumerator name='SPA_FEATURE_ENCRYPTION' value='17'/>
- <enumerator name='SPA_FEATURE_PROJECT_QUOTA' value='18'/>
- <enumerator name='SPA_FEATURE_DEVICE_REMOVAL' value='19'/>
- <enumerator name='SPA_FEATURE_OBSOLETE_COUNTS' value='20'/>
- <enumerator name='SPA_FEATURE_POOL_CHECKPOINT' value='21'/>
- <enumerator name='SPA_FEATURE_SPACEMAP_V2' value='22'/>
- <enumerator name='SPA_FEATURE_ALLOCATION_CLASSES' value='23'/>
- <enumerator name='SPA_FEATURE_RESILVER_DEFER' value='24'/>
- <enumerator name='SPA_FEATURE_BOOKMARK_V2' value='25'/>
- <enumerator name='SPA_FEATURE_REDACTION_BOOKMARKS' value='26'/>
- <enumerator name='SPA_FEATURE_REDACTED_DATASETS' value='27'/>
- <enumerator name='SPA_FEATURE_BOOKMARK_WRITTEN' value='28'/>
- <enumerator name='SPA_FEATURE_LOG_SPACEMAP' value='29'/>
- <enumerator name='SPA_FEATURE_LIVELIST' value='30'/>
- <enumerator name='SPA_FEATURE_DEVICE_REBUILD' value='31'/>
- <enumerator name='SPA_FEATURE_ZSTD_COMPRESS' value='32'/>
- <enumerator name='SPA_FEATURE_DRAID' value='33'/>
- <enumerator name='SPA_FEATURE_ZILSAXATTR' value='34'/>
- <enumerator name='SPA_FEATURE_HEAD_ERRLOG' value='35'/>
- <enumerator name='SPA_FEATURE_BLAKE3' value='36'/>
- <enumerator name='SPA_FEATURE_BLOCK_CLONING' value='37'/>
- <enumerator name='SPA_FEATURE_AVZ_V2' value='38'/>
- <enumerator name='SPA_FEATURE_REDACTION_LIST_SPILL' value='39'/>
- <enumerator name='SPA_FEATURE_RAIDZ_EXPANSION' value='40'/>
- <enumerator name='SPA_FEATURE_FAST_DEDUP' value='41'/>
- <enumerator name='SPA_FEATURE_LONGNAME' value='42'/>
- <enumerator name='SPA_FEATURE_LARGE_MICROZAP' value='43'/>
- <enumerator name='SPA_FEATURE_DYNAMIC_GANG_HEADER' value='44'/>
- <enumerator name='SPA_FEATURE_BLOCK_CLONING_ENDIAN' value='45'/>
- <enumerator name='SPA_FEATURE_PHYSICAL_REWRITE' value='46'/>
- <enumerator name='SPA_FEATURES' value='47'/>
- </enum-decl>
- <typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
- <qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
- <pointer-type-def type-id='b99c00c9' size-in-bits='64' id='13956559'/>
- <qualified-type-def type-id='22cce67b' const='yes' id='d2816df0'/>
- <pointer-type-def type-id='d2816df0' size-in-bits='64' id='3bbfee2e'/>
- <qualified-type-def type-id='b96825af' const='yes' id='2b61797f'/>
- <pointer-type-def type-id='2b61797f' size-in-bits='64' id='9f7200cf'/>
- <pointer-type-def type-id='d6618c78' size-in-bits='64' id='a8425263'/>
- <qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
- <pointer-type-def type-id='a093cbb8' size-in-bits='64' id='b13f38c3'/>
- <pointer-type-def type-id='35acf840' size-in-bits='64' id='17f3480d'/>
- <pointer-type-def type-id='688c495b' size-in-bits='64' id='cec6f2e4'/>
- <pointer-type-def type-id='d11b7617' size-in-bits='64' id='23432aaa'/>
- <function-decl name='zpool_get_handle' mangled-name='zpool_get_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_handle'>
- <parameter type-id='4c81de99'/>
- <return type-id='b0382bb3'/>
- </function-decl>
- <function-decl name='zpool_prop_to_name' mangled-name='zpool_prop_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_to_name'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='vdev_prop_to_name' mangled-name='vdev_prop_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_to_name'>
- <parameter type-id='5aa5c90c'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='vdev_prop_user' mangled-name='vdev_prop_user' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_user'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_get_status' mangled-name='zpool_get_status' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_status'>
- <parameter type-id='4c81de99'/>
- <parameter type-id='7d3cd834'/>
- <parameter type-id='cec6f2e4'/>
- <return type-id='d3dd6294'/>
- </function-decl>
- <function-decl name='zpool_prop_default_string' mangled-name='zpool_prop_default_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_default_string'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_prop_default_numeric' mangled-name='zpool_prop_default_numeric' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_default_numeric'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='libzfs_envvar_is_set' mangled-name='libzfs_envvar_is_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_envvar_is_set'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='lzc_initialize' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='7063e1ab'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_trim' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b1146b8d'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_sync' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_reopen' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_pool_checkpoint' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_pool_checkpoint_discard' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_wait' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='73446457'/>
- <parameter type-id='37e3bd22'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_wait_tag' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='73446457'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='37e3bd22'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_pool_prefetch' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='e55ff6bc'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_set_bootenv' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='22cce67b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_get_bootenv' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_get_vdev_prop' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_set_vdev_prop' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_scrub' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5b35941c'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_ddt_prune' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='02e25ab0'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_resolve_shortname' mangled-name='zfs_resolve_shortname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_resolve_shortname'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_strip_partition' mangled-name='zfs_strip_partition' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_strip_partition'>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zfs_strip_path' mangled-name='zfs_strip_path' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_strip_path'>
- <parameter type-id='80f4b756'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_strcmp_pathname' mangled-name='zfs_strcmp_pathname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_strcmp_pathname'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_history_unpack' mangled-name='zpool_history_unpack' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_history_unpack'>
- <parameter type-id='26a90f95'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='75be733c'/>
- <parameter type-id='4dd26a40'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_basename' mangled-name='zfs_basename' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_basename'>
- <parameter type-id='80f4b756'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_name_to_prop' mangled-name='zpool_name_to_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_name_to_prop'>
- <parameter type-id='80f4b756'/>
- <return type-id='5d0c23fb'/>
- </function-decl>
- <function-decl name='zpool_prop_readonly' mangled-name='zpool_prop_readonly' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_readonly'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_prop_setonce' mangled-name='zpool_prop_setonce' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_setonce'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_prop_feature' mangled-name='zpool_prop_feature' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_feature'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_prop_index_to_string' mangled-name='zpool_prop_index_to_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_index_to_string'>
- <parameter type-id='5d0c23fb'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='vdev_name_to_prop' mangled-name='vdev_name_to_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_name_to_prop'>
- <parameter type-id='80f4b756'/>
- <return type-id='5aa5c90c'/>
- </function-decl>
- <function-decl name='vdev_prop_default_string' mangled-name='vdev_prop_default_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_default_string'>
- <parameter type-id='5aa5c90c'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='vdev_prop_default_numeric' mangled-name='vdev_prop_default_numeric' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_default_numeric'>
- <parameter type-id='5aa5c90c'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='vdev_prop_readonly' mangled-name='vdev_prop_readonly' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_readonly'>
- <parameter type-id='5aa5c90c'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='vdev_prop_index_to_string' mangled-name='vdev_prop_index_to_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_index_to_string'>
- <parameter type-id='5aa5c90c'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prop_vdev' mangled-name='zpool_prop_vdev' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_vdev'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='nvlist_add_nvpair' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='3fa542f0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_add_uint8_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9f7200cf'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_add_nvlist_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='3bbfee2e'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvpair_value_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3fa542f0'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fnvlist_add_boolean_value' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_int64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9da381c4'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_string_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='13956559'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_add_nvlist_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='3bbfee2e'/>
- <parameter type-id='3502e3ff'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_lookup_uint64_array' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='4dd26a40'/>
- <return type-id='5d6479ae'/>
- </function-decl>
- <function-decl name='fnvpair_value_int64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='9da381c4'/>
- </function-decl>
- <function-decl name='fnvpair_value_string' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfeature_is_supported' mangled-name='zfeature_is_supported' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_is_supported'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfeature_lookup_guid' mangled-name='zfeature_lookup_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_lookup_guid'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='a8425263'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfeature_lookup_name' mangled-name='zfeature_lookup_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_lookup_name'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='a8425263'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_load_policy' mangled-name='zpool_get_load_policy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_load_policy'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='23432aaa'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='pool_namecheck' mangled-name='pool_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='pool_namecheck'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='053457bd'/>
- <parameter type-id='26a90f95'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prop_get_type' mangled-name='zpool_prop_get_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_get_type'>
- <parameter type-id='5d0c23fb'/>
- <return type-id='31429eff'/>
- </function-decl>
- <function-decl name='vdev_prop_get_type' mangled-name='vdev_prop_get_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_get_type'>
- <parameter type-id='5aa5c90c'/>
- <return type-id='31429eff'/>
- </function-decl>
- <function-decl name='get_system_hostid' mangled-name='get_system_hostid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_system_hostid'>
- <return type-id='7359adad'/>
- </function-decl>
- <function-decl name='strtoull' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='3a47d82b'/>
- </function-decl>
- <function-decl name='memcmp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='strtok_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='266fe297'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='ctime_r' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='d6e2847c'/>
- <parameter type-id='266fe297'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='__realpath_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='munmap' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='stat64' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='f1cadedf'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_standard_error' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_standard_error_fmt' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_relabel_disk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_props_refresh' mangled-name='zpool_props_refresh' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_props_refresh'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_state_to_name' mangled-name='zpool_state_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_state_to_name'>
- <parameter type-id='35acf840' name='state'/>
- <parameter type-id='9d774e0b' name='aux'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_pool_state_to_name' mangled-name='zpool_pool_state_to_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_pool_state_to_name'>
- <parameter type-id='084a08a3' name='state'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_get_state_str' mangled-name='zpool_get_state_str' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_state_str'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_get_userprop' mangled-name='zpool_get_userprop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_userprop'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='len'/>
- <parameter type-id='debc6aa3' name='srctype'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_set_prop' mangled-name='zpool_set_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_prop'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='propval'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_expand_proplist' mangled-name='zpool_expand_proplist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_expand_proplist'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='e4378506' name='plp'/>
- <parameter type-id='2e45de5d' name='type'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='vdev_expand_proplist' mangled-name='vdev_expand_proplist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_expand_proplist'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='vdevname'/>
- <parameter type-id='e4378506' name='plp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prop_get_feature' mangled-name='zpool_prop_get_feature' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_get_feature'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='len'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_state' mangled-name='zpool_get_state' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_state'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_is_draid_spare' mangled-name='zpool_is_draid_spare' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_is_draid_spare'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_create' mangled-name='zpool_create' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_create'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='pool'/>
- <parameter type-id='5ce45b60' name='nvroot'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='5ce45b60' name='fsprops'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_destroy' mangled-name='zpool_destroy' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_destroy'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='log_str'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_checkpoint' mangled-name='zpool_checkpoint' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_checkpoint'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_discard_checkpoint' mangled-name='zpool_discard_checkpoint' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_discard_checkpoint'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prefetch' mangled-name='zpool_prefetch' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prefetch'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='e55ff6bc' name='type'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_add' mangled-name='zpool_add' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_add'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='5ce45b60' name='nvroot'/>
- <parameter type-id='c19b74c3' name='check_ashift'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_export' mangled-name='zpool_export' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_export'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='c19b74c3' name='force'/>
- <parameter type-id='80f4b756' name='log_str'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_export_force' mangled-name='zpool_export_force' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_export_force'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='log_str'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_explain_recover' mangled-name='zpool_explain_recover' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_explain_recover'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='95e97e5e' name='reason'/>
- <parameter type-id='5ce45b60' name='config'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='size'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_import' mangled-name='zpool_import' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='5ce45b60' name='config'/>
- <parameter type-id='80f4b756' name='newname'/>
- <parameter type-id='26a90f95' name='altroot'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_collect_unsup_feat' mangled-name='zpool_collect_unsup_feat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_collect_unsup_feat'>
- <parameter type-id='5ce45b60' name='config'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='size'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_import_props' mangled-name='zpool_import_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import_props'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='5ce45b60' name='config'/>
- <parameter type-id='80f4b756' name='newname'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_initialize_one' mangled-name='zpool_initialize_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_initialize_one'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_initialize' mangled-name='zpool_initialize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_initialize'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='7063e1ab' name='cmd_type'/>
- <parameter type-id='5ce45b60' name='vds'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_initialize_wait' mangled-name='zpool_initialize_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_initialize_wait'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='7063e1ab' name='cmd_type'/>
- <parameter type-id='5ce45b60' name='vds'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_collect_leaves' mangled-name='zpool_collect_leaves' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_collect_leaves'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='5ce45b60' name='nvroot'/>
- <parameter type-id='5ce45b60' name='res'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_trim_one' mangled-name='zpool_trim_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_trim_one'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_trim' mangled-name='zpool_trim' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_trim'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='b1146b8d' name='cmd_type'/>
- <parameter type-id='5ce45b60' name='vds'/>
- <parameter type-id='b13f38c3' name='trim_flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_scan' mangled-name='zpool_scan' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_scan'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='7313fbe2' name='func'/>
- <parameter type-id='b51cf3c2' name='cmd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_scan_range' mangled-name='zpool_scan_range' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_scan_range'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='7313fbe2' name='func'/>
- <parameter type-id='b51cf3c2' name='cmd'/>
- <parameter type-id='c9d12d66' name='date_start'/>
- <parameter type-id='c9d12d66' name='date_end'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_find_vdev_by_physpath' mangled-name='zpool_find_vdev_by_physpath' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_vdev_by_physpath'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='ppath'/>
- <parameter type-id='37e3bd22' name='avail_spare'/>
- <parameter type-id='37e3bd22' name='l2cache'/>
- <parameter type-id='37e3bd22' name='log'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_find_vdev' mangled-name='zpool_find_vdev' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_vdev'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='37e3bd22' name='avail_spare'/>
- <parameter type-id='37e3bd22' name='l2cache'/>
- <parameter type-id='37e3bd22' name='log'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_find_parent_vdev' mangled-name='zpool_find_parent_vdev' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_parent_vdev'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='37e3bd22' name='avail_spare'/>
- <parameter type-id='37e3bd22' name='l2cache'/>
- <parameter type-id='37e3bd22' name='log'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_vdev_path_to_guid' mangled-name='zpool_vdev_path_to_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_path_to_guid'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zpool_vdev_online' mangled-name='zpool_vdev_online' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_online'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <parameter type-id='17f3480d' name='newstate'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_offline' mangled-name='zpool_vdev_offline' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_offline'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='c19b74c3' name='istmp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_remove_wanted' mangled-name='zpool_vdev_remove_wanted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_remove_wanted'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_fault' mangled-name='zpool_vdev_fault' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_fault'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='guid'/>
- <parameter type-id='9d774e0b' name='aux'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_degrade' mangled-name='zpool_vdev_degrade' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_degrade'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='guid'/>
- <parameter type-id='9d774e0b' name='aux'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_set_removed_state' mangled-name='zpool_vdev_set_removed_state' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_set_removed_state'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='guid'/>
- <parameter type-id='9d774e0b' name='aux'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_attach' mangled-name='zpool_vdev_attach' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_attach'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='old_disk'/>
- <parameter type-id='80f4b756' name='new_disk'/>
- <parameter type-id='5ce45b60' name='nvroot'/>
- <parameter type-id='95e97e5e' name='replacing'/>
- <parameter type-id='c19b74c3' name='rebuild'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_detach' mangled-name='zpool_vdev_detach' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_detach'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_split' mangled-name='zpool_vdev_split' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_split'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='26a90f95' name='newname'/>
- <parameter type-id='857bb57e' name='newroot'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='325c1e34' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_remove' mangled-name='zpool_vdev_remove' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_remove'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_remove_cancel' mangled-name='zpool_vdev_remove_cancel' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_remove_cancel'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_indirect_size' mangled-name='zpool_vdev_indirect_size' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_indirect_size'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='5d6479ae' name='sizep'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_clear' mangled-name='zpool_clear' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_clear'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='5ce45b60' name='rewindnvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_clear' mangled-name='zpool_vdev_clear' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_clear'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='guid'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_set_guid' mangled-name='zpool_set_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_guid'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='713a56f5' name='guid'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_reguid' mangled-name='zpool_reguid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_reguid'>
- <parameter type-id='4c81de99' name='zhp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_reopen_one' mangled-name='zpool_reopen_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_reopen_one'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_sync_one' mangled-name='zpool_sync_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_sync_one'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_name' mangled-name='zpool_vdev_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_name'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='5ce45b60' name='nv'/>
- <parameter type-id='95e97e5e' name='name_flags'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zpool_add_propname' mangled-name='zpool_add_propname' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_add_propname'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_get_errlog' mangled-name='zpool_get_errlog' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_errlog'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='857bb57e' name='nverrlistp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_upgrade' mangled-name='zpool_upgrade' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_upgrade'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='new_version'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_save_arguments' mangled-name='zfs_save_arguments' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_save_arguments'>
- <parameter type-id='95e97e5e' name='argc'/>
- <parameter type-id='9b23c9ad' name='argv'/>
- <parameter type-id='26a90f95' name='string'/>
- <parameter type-id='95e97e5e' name='len'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_log_history' mangled-name='zpool_log_history' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_log_history'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='message'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_history' mangled-name='zpool_get_history' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_history'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='857bb57e' name='nvhisp'/>
- <parameter type-id='5d6479ae' name='off'/>
- <parameter type-id='37e3bd22' name='eof'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_events_next' mangled-name='zpool_events_next' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_events_next'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='857bb57e' name='nvp'/>
- <parameter type-id='7292109c' name='dropped'/>
- <parameter type-id='f0981eeb' name='flags'/>
- <parameter type-id='95e97e5e' name='zevent_fd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_events_clear' mangled-name='zpool_events_clear' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_events_clear'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='7292109c' name='count'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_events_seek' mangled-name='zpool_events_seek' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_events_seek'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='9c313c2d' name='eid'/>
- <parameter type-id='95e97e5e' name='zevent_fd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_obj_to_path' mangled-name='zpool_obj_to_path' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_obj_to_path'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='dsobj'/>
- <parameter type-id='9c313c2d' name='obj'/>
- <parameter type-id='26a90f95' name='pathname'/>
- <parameter type-id='b59d7dce' name='len'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_obj_to_path_ds' mangled-name='zpool_obj_to_path_ds' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_obj_to_path_ds'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='9c313c2d' name='dsobj'/>
- <parameter type-id='9c313c2d' name='obj'/>
- <parameter type-id='26a90f95' name='pathname'/>
- <parameter type-id='b59d7dce' name='len'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_wait' mangled-name='zpool_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_wait'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='73446457' name='activity'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_wait_status' mangled-name='zpool_wait_status' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_wait_status'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='73446457' name='activity'/>
- <parameter type-id='37e3bd22' name='missing'/>
- <parameter type-id='37e3bd22' name='waited'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_set_bootenv' mangled-name='zpool_set_bootenv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_bootenv'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='22cce67b' name='envmap'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_bootenv' mangled-name='zpool_get_bootenv' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_bootenv'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='857bb57e' name='nvlp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_load_compat' mangled-name='zpool_load_compat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_load_compat'>
- <parameter type-id='80f4b756' name='compat'/>
- <parameter type-id='37e3bd22' name='features'/>
- <parameter type-id='26a90f95' name='report'/>
- <parameter type-id='b59d7dce' name='rlen'/>
- <return type-id='901b78d1'/>
- </function-decl>
- <function-decl name='zpool_get_vdev_prop_value' mangled-name='zpool_get_vdev_prop_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_vdev_prop_value'>
- <parameter type-id='5ce45b60' name='nvprop'/>
- <parameter type-id='5aa5c90c' name='prop'/>
- <parameter type-id='26a90f95' name='prop_name'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='len'/>
- <parameter type-id='debc6aa3' name='srctype'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_vdev_prop' mangled-name='zpool_get_vdev_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_vdev_prop'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='vdevname'/>
- <parameter type-id='5aa5c90c' name='prop'/>
- <parameter type-id='26a90f95' name='prop_name'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='len'/>
- <parameter type-id='debc6aa3' name='srctype'/>
- <parameter type-id='c19b74c3' name='literal'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_get_all_vdev_props' mangled-name='zpool_get_all_vdev_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_get_all_vdev_props'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='vdevname'/>
- <parameter type-id='857bb57e' name='outnvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_set_vdev_prop' mangled-name='zpool_set_vdev_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_vdev_prop'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='vdevname'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='propval'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_ddt_prune' mangled-name='zpool_ddt_prune' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_ddt_prune'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='02e25ab0' name='unit'/>
- <parameter type-id='9c313c2d' name='amount'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_sendrecv.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='8901473c' size-in-bits='576' id='f5da478b'>
- <subrange length='1' type-id='7359adad' id='52f813b4'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='384' id='73b82f0f'>
- <subrange length='12' type-id='7359adad' id='84827bdc'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='bd54fe1a' size-in-bits='512' id='5d4efd44'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='9c313c2d' size-in-bits='2176' id='8c2bcad1'>
- <subrange length='34' type-id='7359adad' id='6a6a7e00'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='9c313c2d' size-in-bits='256' id='85c64d26'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='96' id='fa8ef949'>
- <subrange length='12' type-id='7359adad' id='84827bdc'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='128' id='fa9986a5'>
- <subrange length='16' type-id='7359adad' id='848d0938'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='40' id='0f4ddd0b'>
- <subrange length='5' type-id='7359adad' id='53010e10'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='48' id='0f562bd0'>
- <subrange length='6' type-id='7359adad' id='52fa524b'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='b96825af' size-in-bits='64' id='13339fda'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='eaa32e2f' size-in-bits='256' id='209ef23f'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <class-decl name='sendflags' size-in-bits='576' is-struct='yes' visibility='default' id='f6aa15be'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='verbosity' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='replicate' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='skipmissing' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='doall' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='fromorigin' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='pad' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='props' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='dryrun' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='parsable' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='progress' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='progressastitle' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='largeblock' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='embed_data' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='416'>
- <var-decl name='compress' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='raw' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='backup' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='holds' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='544'>
- <var-decl name='saved' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='sendflags_t' type-id='f6aa15be' id='945467e6'/>
- <typedef-decl name='snapfilter_cb_t' type-id='d2a5e211' id='3d3ffb69'/>
- <class-decl name='recvflags' size-in-bits='448' is-struct='yes' visibility='default' id='34a384dc'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='verbose' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='isprefix' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='istail' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='dryrun' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='force' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='canmountoff' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='resumable' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='byteswap' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='nomount' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='holds' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='skipholds' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='domount' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='forceunmount' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='416'>
- <var-decl name='heal' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='recvflags_t' type-id='34a384dc' id='9e59d1d4'/>
- <enum-decl name='lzc_send_flags' id='bfbd3c8e'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='LZC_SEND_FLAG_EMBED_DATA' value='1'/>
- <enumerator name='LZC_SEND_FLAG_LARGE_BLOCK' value='2'/>
- <enumerator name='LZC_SEND_FLAG_COMPRESS' value='4'/>
- <enumerator name='LZC_SEND_FLAG_RAW' value='8'/>
- <enumerator name='LZC_SEND_FLAG_SAVED' value='16'/>
- </enum-decl>
- <class-decl name='ddt_key_t' size-in-bits='320' is-struct='yes' naming-typedef-id='67f6d2cf' visibility='default' id='5fae1718'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='ddk_cksum' type-id='39730d0b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='ddk_prop' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='ddt_key_t' type-id='5fae1718' id='67f6d2cf'/>
- <enum-decl name='dmu_object_type' id='04b3b0b9'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='DMU_OT_NONE' value='0'/>
- <enumerator name='DMU_OT_OBJECT_DIRECTORY' value='1'/>
- <enumerator name='DMU_OT_OBJECT_ARRAY' value='2'/>
- <enumerator name='DMU_OT_PACKED_NVLIST' value='3'/>
- <enumerator name='DMU_OT_PACKED_NVLIST_SIZE' value='4'/>
- <enumerator name='DMU_OT_BPOBJ' value='5'/>
- <enumerator name='DMU_OT_BPOBJ_HDR' value='6'/>
- <enumerator name='DMU_OT_SPACE_MAP_HEADER' value='7'/>
- <enumerator name='DMU_OT_SPACE_MAP' value='8'/>
- <enumerator name='DMU_OT_INTENT_LOG' value='9'/>
- <enumerator name='DMU_OT_DNODE' value='10'/>
- <enumerator name='DMU_OT_OBJSET' value='11'/>
- <enumerator name='DMU_OT_DSL_DIR' value='12'/>
- <enumerator name='DMU_OT_DSL_DIR_CHILD_MAP' value='13'/>
- <enumerator name='DMU_OT_DSL_DS_SNAP_MAP' value='14'/>
- <enumerator name='DMU_OT_DSL_PROPS' value='15'/>
- <enumerator name='DMU_OT_DSL_DATASET' value='16'/>
- <enumerator name='DMU_OT_ZNODE' value='17'/>
- <enumerator name='DMU_OT_OLDACL' value='18'/>
- <enumerator name='DMU_OT_PLAIN_FILE_CONTENTS' value='19'/>
- <enumerator name='DMU_OT_DIRECTORY_CONTENTS' value='20'/>
- <enumerator name='DMU_OT_MASTER_NODE' value='21'/>
- <enumerator name='DMU_OT_UNLINKED_SET' value='22'/>
- <enumerator name='DMU_OT_ZVOL' value='23'/>
- <enumerator name='DMU_OT_ZVOL_PROP' value='24'/>
- <enumerator name='DMU_OT_PLAIN_OTHER' value='25'/>
- <enumerator name='DMU_OT_UINT64_OTHER' value='26'/>
- <enumerator name='DMU_OT_ZAP_OTHER' value='27'/>
- <enumerator name='DMU_OT_ERROR_LOG' value='28'/>
- <enumerator name='DMU_OT_SPA_HISTORY' value='29'/>
- <enumerator name='DMU_OT_SPA_HISTORY_OFFSETS' value='30'/>
- <enumerator name='DMU_OT_POOL_PROPS' value='31'/>
- <enumerator name='DMU_OT_DSL_PERMS' value='32'/>
- <enumerator name='DMU_OT_ACL' value='33'/>
- <enumerator name='DMU_OT_SYSACL' value='34'/>
- <enumerator name='DMU_OT_FUID' value='35'/>
- <enumerator name='DMU_OT_FUID_SIZE' value='36'/>
- <enumerator name='DMU_OT_NEXT_CLONES' value='37'/>
- <enumerator name='DMU_OT_SCAN_QUEUE' value='38'/>
- <enumerator name='DMU_OT_USERGROUP_USED' value='39'/>
- <enumerator name='DMU_OT_USERGROUP_QUOTA' value='40'/>
- <enumerator name='DMU_OT_USERREFS' value='41'/>
- <enumerator name='DMU_OT_DDT_ZAP' value='42'/>
- <enumerator name='DMU_OT_DDT_STATS' value='43'/>
- <enumerator name='DMU_OT_SA' value='44'/>
- <enumerator name='DMU_OT_SA_MASTER_NODE' value='45'/>
- <enumerator name='DMU_OT_SA_ATTR_REGISTRATION' value='46'/>
- <enumerator name='DMU_OT_SA_ATTR_LAYOUTS' value='47'/>
- <enumerator name='DMU_OT_SCAN_XLATE' value='48'/>
- <enumerator name='DMU_OT_DEDUP' value='49'/>
- <enumerator name='DMU_OT_DEADLIST' value='50'/>
- <enumerator name='DMU_OT_DEADLIST_HDR' value='51'/>
- <enumerator name='DMU_OT_DSL_CLONES' value='52'/>
- <enumerator name='DMU_OT_BPOBJ_SUBOBJ' value='53'/>
- <enumerator name='DMU_OT_NUMTYPES' value='54'/>
- <enumerator name='DMU_OTN_UINT8_DATA' value='128'/>
- <enumerator name='DMU_OTN_UINT8_METADATA' value='192'/>
- <enumerator name='DMU_OTN_UINT16_DATA' value='129'/>
- <enumerator name='DMU_OTN_UINT16_METADATA' value='193'/>
- <enumerator name='DMU_OTN_UINT32_DATA' value='130'/>
- <enumerator name='DMU_OTN_UINT32_METADATA' value='194'/>
- <enumerator name='DMU_OTN_UINT64_DATA' value='131'/>
- <enumerator name='DMU_OTN_UINT64_METADATA' value='195'/>
- <enumerator name='DMU_OTN_ZAP_DATA' value='132'/>
- <enumerator name='DMU_OTN_ZAP_METADATA' value='196'/>
- <enumerator name='DMU_OTN_UINT8_ENC_DATA' value='160'/>
- <enumerator name='DMU_OTN_UINT8_ENC_METADATA' value='224'/>
- <enumerator name='DMU_OTN_UINT16_ENC_DATA' value='161'/>
- <enumerator name='DMU_OTN_UINT16_ENC_METADATA' value='225'/>
- <enumerator name='DMU_OTN_UINT32_ENC_DATA' value='162'/>
- <enumerator name='DMU_OTN_UINT32_ENC_METADATA' value='226'/>
- <enumerator name='DMU_OTN_UINT64_ENC_DATA' value='163'/>
- <enumerator name='DMU_OTN_UINT64_ENC_METADATA' value='227'/>
- <enumerator name='DMU_OTN_ZAP_ENC_DATA' value='164'/>
- <enumerator name='DMU_OTN_ZAP_ENC_METADATA' value='228'/>
- </enum-decl>
- <typedef-decl name='dmu_object_type_t' type-id='04b3b0b9' id='5c9d8906'/>
- <class-decl name='zio_cksum' size-in-bits='256' is-struct='yes' visibility='default' id='1d53e28b'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='zc_word' type-id='85c64d26' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zio_cksum_t' type-id='1d53e28b' id='39730d0b'/>
- <class-decl name='dmu_replay_record' size-in-bits='2496' is-struct='yes' visibility='default' id='781a52d7'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_type' type-id='08f5ca17' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='drr_payloadlen' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_u' type-id='ac5ab599' visibility='default'/>
- </data-member>
- </class-decl>
- <enum-decl name='__anonymous_enum__' is-anonymous='yes' id='08f5ca17'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='DRR_BEGIN' value='0'/>
- <enumerator name='DRR_OBJECT' value='1'/>
- <enumerator name='DRR_FREEOBJECTS' value='2'/>
- <enumerator name='DRR_WRITE' value='3'/>
- <enumerator name='DRR_FREE' value='4'/>
- <enumerator name='DRR_END' value='5'/>
- <enumerator name='DRR_WRITE_BYREF' value='6'/>
- <enumerator name='DRR_SPILL' value='7'/>
- <enumerator name='DRR_WRITE_EMBEDDED' value='8'/>
- <enumerator name='DRR_OBJECT_RANGE' value='9'/>
- <enumerator name='DRR_REDACT' value='10'/>
- <enumerator name='DRR_NUMTYPES' value='11'/>
- </enum-decl>
- <union-decl name='__anonymous_union__' size-in-bits='2432' is-anonymous='yes' visibility='default' id='ac5ab599'>
- <data-member access='public'>
- <var-decl name='drr_begin' type-id='09fcdc01' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_end' type-id='6ee25631' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_object' type-id='f9ad530b' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_freeobjects' type-id='a27d958e' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_write' type-id='4cc69e4b' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_free' type-id='c836cfd2' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_write_byref' type-id='e511cdce' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_spill' type-id='1e69a80a' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_write_embedded' type-id='98b1345e' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_object_range' type-id='aba1f9e1' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_redact' type-id='50389039' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='drr_checksum' type-id='a5fe3647' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='drr_end' size-in-bits='320' is-struct='yes' visibility='default' id='6ee25631'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_checksum' type-id='39730d0b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_object' size-in-bits='448' is-struct='yes' visibility='default' id='f9ad530b'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_type' type-id='5c9d8906' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='drr_bonustype' type-id='5c9d8906' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_blksz' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='160'>
- <var-decl name='drr_bonuslen' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_checksumtype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='200'>
- <var-decl name='drr_compress' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='208'>
- <var-decl name='drr_dn_slots' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='216'>
- <var-decl name='drr_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='224'>
- <var-decl name='drr_raw_bonuslen' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_indblkshift' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='328'>
- <var-decl name='drr_nlevels' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='336'>
- <var-decl name='drr_nblkptr' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='344'>
- <var-decl name='drr_pad' type-id='0f4ddd0b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='drr_maxblkid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_freeobjects' size-in-bits='192' is-struct='yes' visibility='default' id='a27d958e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_firstobj' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_numobjs' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_write' size-in-bits='1088' is-struct='yes' visibility='default' id='4cc69e4b'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_type' type-id='5c9d8906' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='drr_pad' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_logical_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_checksumtype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='328'>
- <var-decl name='drr_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='336'>
- <var-decl name='drr_compressiontype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='344'>
- <var-decl name='drr_pad2' type-id='0f4ddd0b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='drr_key' type-id='67f6d2cf' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='drr_compressed_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='768'>
- <var-decl name='drr_salt' type-id='13339fda' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='drr_iv' type-id='fa8ef949' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='928'>
- <var-decl name='drr_mac' type-id='fa9986a5' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_free' size-in-bits='256' is-struct='yes' visibility='default' id='c836cfd2'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_length' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_write_byref' size-in-bits='832' is-struct='yes' visibility='default' id='e511cdce'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_length' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_refguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_refobject' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='drr_refoffset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='drr_checksumtype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='456'>
- <var-decl name='drr_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='464'>
- <var-decl name='drr_pad2' type-id='0f562bd0' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='drr_key' type-id='67f6d2cf' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_spill' size-in-bits='640' is-struct='yes' visibility='default' id='1e69a80a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_length' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='200'>
- <var-decl name='drr_compressiontype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='208'>
- <var-decl name='drr_pad' type-id='0f562bd0' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_compressed_size' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_salt' type-id='13339fda' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='drr_iv' type-id='fa8ef949' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='drr_mac' type-id='fa9986a5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='608'>
- <var-decl name='drr_type' type-id='5c9d8906' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_write_embedded' size-in-bits='384' is-struct='yes' visibility='default' id='98b1345e'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_length' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_compression' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='264'>
- <var-decl name='drr_etype' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='272'>
- <var-decl name='drr_pad' type-id='0f562bd0' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='drr_lsize' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='drr_psize' type-id='8f92235e' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_object_range' size-in-bits='512' is-struct='yes' visibility='default' id='aba1f9e1'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_firstobj' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_numslots' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_salt' type-id='13339fda' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='drr_iv' type-id='fa8ef949' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='drr_mac' type-id='fa9986a5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='drr_flags' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='488'>
- <var-decl name='drr_pad' type-id='d3490169' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_redact' size-in-bits='256' is-struct='yes' visibility='default' id='50389039'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_object' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='drr_offset' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='drr_length' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='drr_toguid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='drr_checksum' size-in-bits='2432' is-struct='yes' visibility='default' id='a5fe3647'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='drr_pad' type-id='8c2bcad1' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='2176'>
- <var-decl name='drr_checksum' type-id='39730d0b' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__cancel_jmp_buf_tag' size-in-bits='576' is-struct='yes' visibility='default' id='8901473c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__cancel_jmp_buf' type-id='379a1ab7' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='__mask_was_saved' type-id='95e97e5e' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='__pthread_unwind_buf_t' size-in-bits='832' is-struct='yes' naming-typedef-id='4423cf7f' visibility='default' id='a0abc656'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='__cancel_jmp_buf' type-id='f5da478b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='__pad' type-id='209ef23f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='__pthread_unwind_buf_t' type-id='a0abc656' id='4423cf7f'/>
- <typedef-decl name='__jmp_buf' type-id='5d4efd44' id='379a1ab7'/>
- <typedef-decl name='__clockid_t' type-id='95e97e5e' id='08f9a87a'/>
- <typedef-decl name='__timer_t' type-id='eaa32e2f' id='df209b60'/>
- <typedef-decl name='clockid_t' type-id='08f9a87a' id='a1c3b834'/>
- <class-decl name='sigevent' size-in-bits='512' is-struct='yes' visibility='default' id='519bc206'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='sigev_value' type-id='eabacd01' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='sigev_signo' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='sigev_notify' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='_sigev_un' type-id='ac5ab59a' visibility='default'/>
- </data-member>
- </class-decl>
- <union-decl name='__anonymous_union__1' size-in-bits='384' is-anonymous='yes' visibility='default' id='ac5ab59a'>
- <data-member access='public'>
- <var-decl name='_pad' type-id='73b82f0f' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_tid' type-id='3629bad8' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='_sigev_thread' type-id='e7f43f7c' visibility='default'/>
- </data-member>
- </union-decl>
- <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' id='e7f43f7c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='_function' type-id='5f147c28' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='_attribute' type-id='7347a39e' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='itimerspec' size-in-bits='256' is-struct='yes' visibility='default' id='acbdbcc6'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='it_interval' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='it_value' type-id='a9c79a1f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='timer_t' type-id='df209b60' id='b07ae406'/>
- <typedef-decl name='Byte' type-id='002ac4a6' id='efb9ba06'/>
- <typedef-decl name='uLong' type-id='7359adad' id='5bbcce85'/>
- <typedef-decl name='Bytef' type-id='efb9ba06' id='c1606520'/>
- <typedef-decl name='uLongf' type-id='5bbcce85' id='4d39af59'/>
- <pointer-type-def type-id='c1606520' size-in-bits='64' id='4c667223'/>
- <pointer-type-def type-id='8901473c' size-in-bits='64' id='eb91b7ea'/>
- <pointer-type-def type-id='4423cf7f' size-in-bits='64' id='ba7c727c'/>
- <pointer-type-def type-id='b9c97942' size-in-bits='64' id='bbf06c47'/>
- <qualified-type-def type-id='bbf06c47' restrict='yes' id='65e6ec45'/>
- <qualified-type-def type-id='c1606520' const='yes' id='a6124a50'/>
- <pointer-type-def type-id='a6124a50' size-in-bits='64' id='e8cb3e0e'/>
- <qualified-type-def type-id='b9c97942' const='yes' id='191f6b72'/>
- <pointer-type-def type-id='191f6b72' size-in-bits='64' id='e475fb88'/>
- <qualified-type-def type-id='e475fb88' restrict='yes' id='5a8729d0'/>
- <qualified-type-def type-id='781a52d7' const='yes' id='413ab2b8'/>
- <pointer-type-def type-id='413ab2b8' size-in-bits='64' id='41671bd6'/>
- <qualified-type-def type-id='acbdbcc6' const='yes' id='4ba62af7'/>
- <pointer-type-def type-id='4ba62af7' size-in-bits='64' id='f39579e7'/>
- <qualified-type-def type-id='f39579e7' restrict='yes' id='9b23e165'/>
- <pointer-type-def type-id='c70fa2e8' size-in-bits='64' id='2e711a2a'/>
- <pointer-type-def type-id='3ff5601b' size-in-bits='64' id='4aafb922'/>
- <pointer-type-def type-id='acbdbcc6' size-in-bits='64' id='116842ac'/>
- <qualified-type-def type-id='116842ac' restrict='yes' id='3d3c4cf4'/>
- <pointer-type-def type-id='9e59d1d4' size-in-bits='64' id='4ea84b4f'/>
- <pointer-type-def type-id='945467e6' size-in-bits='64' id='8def7735'/>
- <pointer-type-def type-id='519bc206' size-in-bits='64' id='ef2f159c'/>
- <qualified-type-def type-id='ef2f159c' restrict='yes' id='de0eb5a4'/>
- <pointer-type-def type-id='3d3ffb69' size-in-bits='64' id='72a26210'/>
- <pointer-type-def type-id='c9d12d66' size-in-bits='64' id='b2eb2c3f'/>
- <pointer-type-def type-id='b07ae406' size-in-bits='64' id='36e89359'/>
- <qualified-type-def type-id='36e89359' restrict='yes' id='de98c2bb'/>
- <pointer-type-def type-id='a9c79a1f' size-in-bits='64' id='3d83ba87'/>
- <pointer-type-def type-id='4d39af59' size-in-bits='64' id='60db3356'/>
- <pointer-type-def type-id='f1abb096' size-in-bits='64' id='5f147c28'/>
- <pointer-type-def type-id='39730d0b' size-in-bits='64' id='c24fc2ee'/>
- <function-decl name='nvlist_print' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_get_pool_handle' mangled-name='zfs_get_pool_handle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_pool_handle'>
- <parameter type-id='fcd57163'/>
- <return type-id='4c81de99'/>
- </function-decl>
- <function-decl name='lzc_send_wrapper' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='2e711a2a'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_send_redacted' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='bfbd3c8e'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_send_resume_redacted' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='bfbd3c8e'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_receive_with_cmdprops' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='ae3e8ca6'/>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='41671bd6'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_receive_with_heal' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='ae3e8ca6'/>
- <parameter type-id='3502e3ff'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='41671bd6'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='857bb57e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_send_space' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='bfbd3c8e'/>
- <parameter type-id='5d6479ae'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_send_space_resume_redacted' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='bfbd3c8e'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='5d6479ae'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='lzc_rename' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_setproctitle' mangled-name='zfs_setproctitle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle'>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_insert' mangled-name='avl_insert' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_insert'>
- <parameter type-id='a3681dea'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='fba6cb51'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='nvlist_add_boolean' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvlist_lookup_boolean' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='nvpair_value_int32' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <parameter type-id='4aafb922'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fnvlist_size' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='fnvlist_merge' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_remove' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fnvlist_lookup_boolean_value' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='22cce67b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='fletcher_4_native_varsize' mangled-name='fletcher_4_native_varsize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_native_varsize'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='c24fc2ee'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_4_incremental_native' mangled-name='fletcher_4_incremental_native' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_incremental_native'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fletcher_4_incremental_byteswap' mangled-name='fletcher_4_incremental_byteswap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_incremental_byteswap'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_exit' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__pthread_register_cancel' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='ba7c727c'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='__pthread_unwind_next' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='ba7c727c'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='sigaddset' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9e80f729'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='perror' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='strndup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='time' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b2eb2c3f'/>
- <return type-id='c9d12d66'/>
- </function-decl>
- <function-decl name='clock_gettime' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a1c3b834'/>
- <parameter type-id='3d83ba87'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='timer_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a1c3b834'/>
- <parameter type-id='de0eb5a4'/>
- <parameter type-id='de98c2bb'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='timer_delete' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b07ae406'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='timer_settime' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b07ae406'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9b23e165'/>
- <parameter type-id='3d3c4cf4'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='write' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='79a0948f'/>
- </function-decl>
- <function-decl name='pause' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='pthread_sigmask' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='5a8729d0'/>
- <parameter type-id='65e6ec45'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='uncompress' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='4c667223'/>
- <parameter type-id='60db3356'/>
- <parameter type-id='e8cb3e0e'/>
- <parameter type-id='5bbcce85'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='create_parents' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='26a90f95'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_send_progress' mangled-name='zfs_send_progress' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_progress'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='95e97e5e' name='fd'/>
- <parameter type-id='5d6479ae' name='bytes_written'/>
- <parameter type-id='5d6479ae' name='blocks_visited'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_send_resume_token_to_nvlist' mangled-name='zfs_send_resume_token_to_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_resume_token_to_nvlist'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='token'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zfs_send_resume' mangled-name='zfs_send_resume' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_resume'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='8def7735' name='flags'/>
- <parameter type-id='95e97e5e' name='outfd'/>
- <parameter type-id='80f4b756' name='resume_token'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_send_saved' mangled-name='zfs_send_saved' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_saved'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='8def7735' name='flags'/>
- <parameter type-id='95e97e5e' name='outfd'/>
- <parameter type-id='80f4b756' name='resume_token'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_send' mangled-name='zfs_send' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='fromsnap'/>
- <parameter type-id='80f4b756' name='tosnap'/>
- <parameter type-id='8def7735' name='flags'/>
- <parameter type-id='95e97e5e' name='outfd'/>
- <parameter type-id='72a26210' name='filter_func'/>
- <parameter type-id='eaa32e2f' name='cb_arg'/>
- <parameter type-id='857bb57e' name='debugnvp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_send_one' mangled-name='zfs_send_one' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_one'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='from'/>
- <parameter type-id='95e97e5e' name='fd'/>
- <parameter type-id='8def7735' name='flags'/>
- <parameter type-id='80f4b756' name='redactbook'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_receive' mangled-name='zfs_receive' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_receive'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='tosnap'/>
- <parameter type-id='5ce45b60' name='props'/>
- <parameter type-id='4ea84b4f' name='flags'/>
- <parameter type-id='95e97e5e' name='infd'/>
- <parameter type-id='a3681dea' name='stream_avl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-type size-in-bits='64' id='c70fa2e8'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='d2a5e211'>
- <parameter type-id='9200a744'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='c19b74c3'/>
- </function-type>
- <function-type size-in-bits='64' id='f1abb096'>
- <parameter type-id='eabacd01'/>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_status.c' language='LANG_C99'>
- <function-decl name='zpool_import_status' mangled-name='zpool_import_status' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import_status'>
- <parameter type-id='5ce45b60' name='config'/>
- <parameter type-id='7d3cd834' name='msgid'/>
- <parameter type-id='cec6f2e4' name='errata'/>
- <return type-id='d3dd6294'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/libzfs_util.c' language='LANG_C99'>
- <class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='d5027220'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='gp_offset' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='fp_offset' type-id='f0981eeb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='overflow_arg_area' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='reg_save_area' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </class-decl>
- <type-decl name='double' size-in-bits='64' id='a0eb0f08'/>
- <array-type-def dimensions='1' type-id='95e97e5e' size-in-bits='192' id='e41bdf22'>
- <subrange length='6' type-id='7359adad' id='52fa524b'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='19cefcee' size-in-bits='160' alignment-in-bits='32' id='3fcf57d2'>
- <subrange length='5' type-id='7359adad' id='53010e10'/>
- </array-type-def>
- <enum-decl name='zfs_get_column_t' naming-typedef-id='19cefcee' id='223bdcaa'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='GET_COL_NONE' value='0'/>
- <enumerator name='GET_COL_NAME' value='1'/>
- <enumerator name='GET_COL_PROPERTY' value='2'/>
- <enumerator name='GET_COL_VALUE' value='3'/>
- <enumerator name='GET_COL_RECVD' value='4'/>
- <enumerator name='GET_COL_SOURCE' value='5'/>
- </enum-decl>
- <typedef-decl name='zfs_get_column_t' type-id='223bdcaa' id='19cefcee'/>
- <class-decl name='vdev_cbdata' size-in-bits='192' is-struct='yes' visibility='default' id='b8006be8'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='cb_name_flags' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='cb_names' type-id='9b23c9ad' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='cb_names_count' type-id='f0981eeb' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='vdev_cbdata_t' type-id='b8006be8' id='a9679c94'/>
- <class-decl name='zprop_get_cbdata' size-in-bits='960' is-struct='yes' visibility='default' id='f3d3c319'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='cb_sources' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='cb_columns' type-id='3fcf57d2' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='cb_colwidths' type-id='e41bdf22' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='cb_scripted' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='416'>
- <var-decl name='cb_literal' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='cb_first' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='cb_json' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='cb_proplist' type-id='3a9b2288' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='cb_type' type-id='2e45de5d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='640'>
- <var-decl name='cb_vdevs' type-id='a9679c94' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='cb_jsobj' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='896'>
- <var-decl name='cb_json_as_int' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='928'>
- <var-decl name='cb_json_pool_key_guid' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zprop_get_cbdata_t' type-id='f3d3c319' id='f3d87113'/>
- <typedef-decl name='zprop_func' type-id='2e711a2a' id='1ec3747a'/>
- <enum-decl name='zprop_attr_t' naming-typedef-id='999701cc' id='77d05200'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='PROP_DEFAULT' value='0'/>
- <enumerator name='PROP_READONLY' value='1'/>
- <enumerator name='PROP_INHERIT' value='2'/>
- <enumerator name='PROP_ONETIME' value='3'/>
- <enumerator name='PROP_ONETIME_DEFAULT' value='4'/>
- </enum-decl>
- <typedef-decl name='zprop_attr_t' type-id='77d05200' id='999701cc'/>
- <class-decl name='zfs_index' size-in-bits='128' is-struct='yes' visibility='default' id='87957af9'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='pi_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='pi_value' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zprop_index_t' type-id='87957af9' id='64636ce3'/>
- <class-decl name='zprop_desc_t' size-in-bits='640' is-struct='yes' naming-typedef-id='ffa52b96' visibility='default' id='bbff5e4b'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='pd_name' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='pd_propnum' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='pd_proptype' type-id='31429eff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='pd_strdefault' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='pd_numdefault' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='pd_attr' type-id='999701cc' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='pd_types' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='pd_values' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='pd_colname' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='pd_rightalign' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='449'>
- <var-decl name='pd_visible' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='450'>
- <var-decl name='pd_zfs_mod_supported' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='451'>
- <var-decl name='pd_always_flex' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='pd_table' type-id='c8bc397b' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='pd_table_size' type-id='b59d7dce' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zprop_desc_t' type-id='bbff5e4b' id='ffa52b96'/>
- <class-decl name='extmnttab' size-in-bits='320' is-struct='yes' visibility='default' id='0c544dc0'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='mnt_special' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='mnt_mountp' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='mnt_fstype' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='mnt_mntopts' type-id='26a90f95' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='mnt_major' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='d5027220' size-in-bits='64' id='b7f2d5e6'/>
- <qualified-type-def type-id='26a90f95' const='yes' id='57de658a'/>
- <pointer-type-def type-id='57de658a' size-in-bits='64' id='f319fae0'/>
- <pointer-type-def type-id='9b23c9ad' size-in-bits='64' id='c0563f85'/>
- <qualified-type-def type-id='33f57a65' const='yes' id='21fd6035'/>
- <pointer-type-def type-id='21fd6035' size-in-bits='64' id='a0de50cd'/>
- <pointer-type-def type-id='a0de50cd' size-in-bits='64' id='24f95ba5'/>
- <qualified-type-def type-id='64636ce3' const='yes' id='072f7953'/>
- <pointer-type-def type-id='072f7953' size-in-bits='64' id='c8bc397b'/>
- <pointer-type-def type-id='0c544dc0' size-in-bits='64' id='394fc496'/>
- <pointer-type-def type-id='aca3bac8' size-in-bits='64' id='d33f11cb'/>
- <qualified-type-def type-id='d33f11cb' restrict='yes' id='5c53ba29'/>
- <pointer-type-def type-id='ffa52b96' size-in-bits='64' id='76c8174b'/>
- <pointer-type-def type-id='f3d87113' size-in-bits='64' id='0d2a0670'/>
- <function-decl name='nvlist_print_json' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='822cd80b'/>
- <parameter type-id='5ce45b60'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_label_disk' mangled-name='zpool_label_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_label_disk'>
- <parameter type-id='b0382bb3'/>
- <parameter type-id='4c81de99'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_version_kernel' mangled-name='zfs_version_kernel' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_kernel'>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='libzfs_core_init' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_core_fini' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_get_underlying_path' mangled-name='zfs_get_underlying_path' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_underlying_path'>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zpool_prop_unsupported' mangled-name='zpool_prop_unsupported' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_unsupported'>
- <parameter type-id='80f4b756'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zpool_feature_init' mangled-name='zpool_feature_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_feature_init'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_4_init' mangled-name='fletcher_4_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_init'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_4_fini' mangled-name='fletcher_4_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_fini'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_prop_init' mangled-name='zfs_prop_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_init'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_prop_get_table' mangled-name='zfs_prop_get_table' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_get_table'>
- <return type-id='76c8174b'/>
- </function-decl>
- <function-decl name='zpool_prop_init' mangled-name='zpool_prop_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_init'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_prop_get_table' mangled-name='zpool_prop_get_table' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_get_table'>
- <return type-id='76c8174b'/>
- </function-decl>
- <function-decl name='vdev_prop_init' mangled-name='vdev_prop_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_init'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_iter_common' mangled-name='zprop_iter_common' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_iter_common'>
- <parameter type-id='1ec3747a'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_name_to_prop' mangled-name='zprop_name_to_prop' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_name_to_prop'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_string_to_index' mangled-name='zprop_string_to_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_string_to_index'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='5d6479ae'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_values' mangled-name='zprop_values' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_values'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zprop_width' mangled-name='zprop_width' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_width'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='37e3bd22'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zprop_valid_for_type' mangled-name='zprop_valid_for_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_valid_for_type'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='2e45de5d'/>
- <parameter type-id='c19b74c3'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='getextmntent' mangled-name='getextmntent' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='getextmntent'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='394fc496'/>
- <parameter type-id='62f7a03d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__ctype_toupper_loc' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='24f95ba5'/>
- </function-decl>
- <function-decl name='dlclose' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='regcomp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5c53ba29'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='regfree' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='d33f11cb'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='putc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='822cd80b'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='puts' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='strtod' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='8c85230f'/>
- <return type-id='a0eb0f08'/>
- </function-decl>
- <function-decl name='realloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='exit' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='strspn' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='strnlen' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='strncasecmp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='access' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='dup2' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='execve' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='f319fae0'/>
- <parameter type-id='f319fae0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='execv' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='f319fae0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='execvp' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='f319fae0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='execvpe' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='f319fae0'/>
- <parameter type-id='f319fae0'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='_exit' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='setpgid' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3629bad8'/>
- <parameter type-id='3629bad8'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fork' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='3629bad8'/>
- </function-decl>
- <function-decl name='pow' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a0eb0f08'/>
- <parameter type-id='a0eb0f08'/>
- <return type-id='a0eb0f08'/>
- </function-decl>
- <function-decl name='__vfprintf_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e75a27e9'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='b7f2d5e6'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='__vasprintf_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='8c85230f'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9d26089a'/>
- <parameter type-id='b7f2d5e6'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='waitpid' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3629bad8'/>
- <parameter type-id='7292109c'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='3629bad8'/>
- </function-decl>
- <function-decl name='namespace_clear' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b0382bb3'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_load_module' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_errno' mangled-name='libzfs_errno' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_errno'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_error_action' mangled-name='libzfs_error_action' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_error_action'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='libzfs_error_description' mangled-name='libzfs_error_description' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_error_description'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='libzfs_print_on_error' mangled-name='libzfs_print_on_error' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_print_on_error'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='c19b74c3' name='printerr'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_run_process' mangled-name='libzfs_run_process' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_run_process'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='9b23c9ad' name='argv'/>
- <parameter type-id='95e97e5e' name='flags'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_run_process_get_stdout' mangled-name='libzfs_run_process_get_stdout' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_run_process_get_stdout'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='9b23c9ad' name='argv'/>
- <parameter type-id='9b23c9ad' name='env'/>
- <parameter type-id='c0563f85' name='lines'/>
- <parameter type-id='7292109c' name='lines_cnt'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_run_process_get_stdout_nopath' mangled-name='libzfs_run_process_get_stdout_nopath' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_run_process_get_stdout_nopath'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='9b23c9ad' name='argv'/>
- <parameter type-id='9b23c9ad' name='env'/>
- <parameter type-id='c0563f85' name='lines'/>
- <parameter type-id='7292109c' name='lines_cnt'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_free_str_array' mangled-name='libzfs_free_str_array' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_free_str_array'>
- <parameter type-id='9b23c9ad' name='strs'/>
- <parameter type-id='95e97e5e' name='count'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='libzfs_init' mangled-name='libzfs_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_init'>
- <return type-id='b0382bb3'/>
- </function-decl>
- <function-decl name='libzfs_fini' mangled-name='libzfs_fini' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_fini'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_path_to_zhandle' mangled-name='zfs_path_to_zhandle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_path_to_zhandle'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='2e45de5d' name='argtype'/>
- <return type-id='9200a744'/>
- </function-decl>
- <function-decl name='zcmd_print_json' mangled-name='zcmd_print_json' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zcmd_print_json'>
- <parameter type-id='5ce45b60' name='nvl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_nvlist_one_property' mangled-name='zprop_nvlist_one_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_nvlist_one_property'>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='value'/>
- <parameter type-id='a2256d42' name='sourcetype'/>
- <parameter type-id='80f4b756' name='source'/>
- <parameter type-id='80f4b756' name='recvd_value'/>
- <parameter type-id='5ce45b60' name='nvl'/>
- <parameter type-id='c19b74c3' name='as_int'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_print_one_property' mangled-name='zprop_print_one_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_print_one_property'>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='0d2a0670' name='cbp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='value'/>
- <parameter type-id='a2256d42' name='sourcetype'/>
- <parameter type-id='80f4b756' name='source'/>
- <parameter type-id='80f4b756' name='recvd_value'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_collect_property' mangled-name='zprop_collect_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_collect_property'>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='0d2a0670' name='cbp'/>
- <parameter type-id='80f4b756' name='propname'/>
- <parameter type-id='80f4b756' name='value'/>
- <parameter type-id='a2256d42' name='sourcetype'/>
- <parameter type-id='80f4b756' name='source'/>
- <parameter type-id='80f4b756' name='recvd_value'/>
- <parameter type-id='5ce45b60' name='nvl'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_get_list' mangled-name='zprop_get_list' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_get_list'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='26a90f95' name='props'/>
- <parameter type-id='e4378506' name='listp'/>
- <parameter type-id='2e45de5d' name='type'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_free_list' mangled-name='zprop_free_list' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_free_list'>
- <parameter type-id='3a9b2288' name='pl'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_iter' mangled-name='zprop_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_iter'>
- <parameter type-id='1ec3747a' name='func'/>
- <parameter type-id='eaa32e2f' name='cb'/>
- <parameter type-id='c19b74c3' name='show_all'/>
- <parameter type-id='c19b74c3' name='ordered'/>
- <parameter type-id='2e45de5d' name='type'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_version_userland' mangled-name='zfs_version_userland' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_userland'>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_version_print' mangled-name='zfs_version_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_print'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_version_nvlist' mangled-name='zfs_version_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_nvlist'>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
- <parameter type-id='80f4b756' name='color'/>
- <parameter type-id='80f4b756' name='format'/>
- <parameter is-variadic='yes'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_vdev_script_alloc_env' mangled-name='zpool_vdev_script_alloc_env' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_script_alloc_env'>
- <parameter type-id='80f4b756' name='pool_name'/>
- <parameter type-id='80f4b756' name='vdev_path'/>
- <parameter type-id='80f4b756' name='vdev_upath'/>
- <parameter type-id='80f4b756' name='vdev_enc_sysfs_path'/>
- <parameter type-id='80f4b756' name='opt_key'/>
- <parameter type-id='80f4b756' name='opt_val'/>
- <return type-id='9b23c9ad'/>
- </function-decl>
- <function-decl name='zpool_vdev_script_free_env' mangled-name='zpool_vdev_script_free_env' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_vdev_script_free_env'>
- <parameter type-id='9b23c9ad' name='env'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_prepare_disk' mangled-name='zpool_prepare_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prepare_disk'>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='5ce45b60' name='vdev_nv'/>
- <parameter type-id='80f4b756' name='prepare_str'/>
- <parameter type-id='c0563f85' name='lines'/>
- <parameter type-id='7292109c' name='lines_cnt'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prepare_and_label_disk' mangled-name='zpool_prepare_and_label_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prepare_and_label_disk'>
- <parameter type-id='b0382bb3' name='hdl'/>
- <parameter type-id='4c81de99' name='zhp'/>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='5ce45b60' name='vdev_nv'/>
- <parameter type-id='80f4b756' name='prepare_str'/>
- <parameter type-id='c0563f85' name='lines'/>
- <parameter type-id='7292109c' name='lines_cnt'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/os/linux/libzfs_mount_os.c' language='LANG_C99'>
- <pointer-type-def type-id='7359adad' size-in-bits='64' id='1d2c2b85'/>
- <function-decl name='geteuid' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='cc5fcceb'/>
- </function-decl>
- <function-decl name='mount' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='7359adad'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='umount2' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_parse_mount_options' mangled-name='zfs_parse_mount_options' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_parse_mount_options'>
- <parameter type-id='80f4b756' name='mntopts'/>
- <parameter type-id='1d2c2b85' name='mntflags'/>
- <parameter type-id='1d2c2b85' name='zfsflags'/>
- <parameter type-id='95e97e5e' name='sloppy'/>
- <parameter type-id='26a90f95' name='badopt'/>
- <parameter type-id='26a90f95' name='mtabopt'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_adjust_mount_options' mangled-name='zfs_adjust_mount_options' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_adjust_mount_options'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='mntpoint'/>
- <parameter type-id='26a90f95' name='mntopts'/>
- <parameter type-id='26a90f95' name='mtabopt'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_mount_delegation_check' mangled-name='zfs_mount_delegation_check' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_mount_delegation_check'>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/os/linux/libzfs_pool_os.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='288' id='16e6f2c6'>
- <subrange length='36' type-id='7359adad' id='ae666bde'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='a65ae39c' size-in-bits='960' id='fa198beb'>
- <subrange length='1' type-id='7359adad' id='52f813b4'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='3502e3ff' size-in-bits='384' id='dba89ba3'>
- <subrange length='12' type-id='7359adad' id='84827bdc'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='3502e3ff' size-in-bits='256' id='01d84ed4'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <class-decl name='dk_part' size-in-bits='960' is-struct='yes' visibility='default' id='a65ae39c'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='p_start' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='p_size' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='p_guid' type-id='214f32ea' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='p_tag' type-id='d908a348' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='272'>
- <var-decl name='p_flag' type-id='d908a348' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='p_name' type-id='16e6f2c6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='p_uguid' type-id='214f32ea' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='704'>
- <var-decl name='p_resv' type-id='01d84ed4' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='dk_gpt' size-in-bits='1920' is-struct='yes' visibility='default' id='dd4a2e5a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='efi_version' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='efi_nparts' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='efi_part_size' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='efi_lbasize' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='efi_last_lba' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='efi_first_u_lba' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='efi_last_u_lba' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='efi_disk_uguid' type-id='214f32ea' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='efi_flags' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='efi_reserved1' type-id='3502e3ff' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='efi_altern_lba' type-id='804dc465' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='576'>
- <var-decl name='efi_reserved' type-id='dba89ba3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='960'>
- <var-decl name='efi_parts' type-id='fa198beb' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='uuid' size-in-bits='128' is-struct='yes' visibility='default' id='214f32ea'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='time_low' type-id='8f92235e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='time_mid' type-id='149c6638' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='48'>
- <var-decl name='time_hi_and_version' type-id='149c6638' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='clock_seq_hi_and_reserved' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='72'>
- <var-decl name='clock_seq_low' type-id='b96825af' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='80'>
- <var-decl name='node_addr' type-id='0f562bd0' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='ushort_t' type-id='8efea9e5' id='d908a348'/>
- <typedef-decl name='uint16_t' type-id='253c2d2a' id='149c6638'/>
- <typedef-decl name='__uint16_t' type-id='8efea9e5' id='253c2d2a'/>
- <pointer-type-def type-id='dd4a2e5a' size-in-bits='64' id='0d8119a8'/>
- <pointer-type-def type-id='0d8119a8' size-in-bits='64' id='c43b27a6'/>
- <function-decl name='zpool_label_disk_wait' mangled-name='zpool_label_disk_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_label_disk_wait'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_append_partition' mangled-name='zfs_append_partition' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_append_partition'>
- <parameter type-id='26a90f95'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='efi_alloc_and_init' mangled-name='efi_alloc_and_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_alloc_and_init'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='8f92235e'/>
- <parameter type-id='c43b27a6'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='efi_alloc_and_read' mangled-name='efi_alloc_and_read' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_alloc_and_read'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='c43b27a6'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='efi_write' mangled-name='efi_write' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_write'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='0d8119a8'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='efi_rescan' mangled-name='efi_rescan' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_rescan'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='efi_free' mangled-name='efi_free' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_free'>
- <parameter type-id='0d8119a8'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='efi_use_whole_disk' mangled-name='efi_use_whole_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='efi_use_whole_disk'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='rand' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fsync' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzfs/os/linux/libzfs_util_os.c' language='LANG_C99'>
- <typedef-decl name='nfds_t' type-id='7359adad' id='555eef66'/>
- <class-decl name='pollfd' size-in-bits='64' is-struct='yes' visibility='default' id='b440e872'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='fd' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='events' type-id='a2185560' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='48'>
- <var-decl name='revents' type-id='a2185560' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='b440e872' size-in-bits='64' id='3ac36db0'/>
- <function-decl name='__poll_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='3ac36db0'/>
- <parameter type-id='555eef66'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='7359adad'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='inotify_init1' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='inotify_add_watch' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='8f92235e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='timerfd_create' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='08f9a87a'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='timerfd_settime' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='f39579e7'/>
- <parameter type-id='116842ac'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='libzfs_error_init' mangled-name='libzfs_error_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libzfs_error_init'>
- <parameter type-id='95e97e5e' name='error'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_userns' mangled-name='zfs_userns' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_userns'>
- <parameter type-id='9200a744' name='zhp'/>
- <parameter type-id='80f4b756' name='nspath'/>
- <parameter type-id='95e97e5e' name='attach'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/os/linux/zutil_device_path_os.c' language='LANG_C99'>
- <class-decl name='udev' is-struct='yes' visibility='default' is-declaration-only='yes' id='e4a7fb7f'/>
- <class-decl name='udev_device' is-struct='yes' visibility='default' is-declaration-only='yes' id='640b33ca'/>
- <pointer-type-def type-id='e4a7fb7f' size-in-bits='64' id='025eefe7'/>
- <pointer-type-def type-id='640b33ca' size-in-bits='64' id='b32bae08'/>
- <class-decl name='udev' is-struct='yes' visibility='default' is-declaration-only='yes' id='e4a7fb7f'/>
- <class-decl name='udev_device' is-struct='yes' visibility='default' is-declaration-only='yes' id='640b33ca'/>
- <function-decl name='udev_new' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='025eefe7'/>
- </function-decl>
- <function-decl name='udev_device_unref' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b32bae08'/>
- <return type-id='b32bae08'/>
- </function-decl>
- <function-decl name='udev_device_new_from_subsystem_sysname' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='025eefe7'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='b32bae08'/>
- </function-decl>
- <function-decl name='udev_device_get_property_value' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b32bae08'/>
- <parameter type-id='80f4b756'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='__readlink_chk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='9d26089a'/>
- <parameter type-id='266fe297'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='79a0948f'/>
- </function-decl>
- <function-decl name='zfs_get_enclosure_sysfs_path' mangled-name='zfs_get_enclosure_sysfs_path' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_get_enclosure_sysfs_path'>
- <parameter type-id='80f4b756' name='dev_name'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zfs_dev_is_dm' mangled-name='zfs_dev_is_dm' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dev_is_dm'>
- <parameter type-id='80f4b756' name='dev_name'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_dev_is_whole_disk' mangled-name='zfs_dev_is_whole_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dev_is_whole_disk'>
- <parameter type-id='80f4b756' name='dev_name'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='is_mpath_whole_disk' mangled-name='is_mpath_whole_disk' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='is_mpath_whole_disk'>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/os/linux/zutil_import_os.c' language='LANG_C99'>
- <class-decl name='blkid_struct_cache' is-struct='yes' visibility='default' is-declaration-only='yes' id='09286066'/>
- <class-decl name='blkid_struct_dev' is-struct='yes' visibility='default' is-declaration-only='yes' id='86223623'/>
- <class-decl name='blkid_struct_dev_iterate' is-struct='yes' visibility='default' is-declaration-only='yes' id='d88420d6'/>
- <class-decl name='udev_list_entry' is-struct='yes' visibility='default' is-declaration-only='yes' id='e7dbdca3'/>
- <typedef-decl name='pool_vdev_iter_f' type-id='6c16a6c8' id='dff793e0'/>
- <typedef-decl name='blkid_dev' type-id='8433f053' id='f47b023a'/>
- <typedef-decl name='blkid_cache' type-id='940e3afc' id='0882dfdf'/>
- <typedef-decl name='blkid_dev_iterate' type-id='b8fa2efc' id='f4760fa7'/>
- <typedef-decl name='__useconds_t' type-id='f0981eeb' id='4e80d4b1'/>
- <pointer-type-def type-id='0882dfdf' size-in-bits='64' id='2e3e7caa'/>
- <pointer-type-def type-id='f47b023a' size-in-bits='64' id='d87f9b75'/>
- <pointer-type-def type-id='09286066' size-in-bits='64' id='940e3afc'/>
- <pointer-type-def type-id='86223623' size-in-bits='64' id='8433f053'/>
- <pointer-type-def type-id='d88420d6' size-in-bits='64' id='b8fa2efc'/>
- <pointer-type-def type-id='2ec2411e' size-in-bits='64' id='6c16a6c8'/>
- <pointer-type-def type-id='e7dbdca3' size-in-bits='64' id='deabd0d3'/>
- <class-decl name='blkid_struct_cache' is-struct='yes' visibility='default' is-declaration-only='yes' id='09286066'/>
- <class-decl name='blkid_struct_dev' is-struct='yes' visibility='default' is-declaration-only='yes' id='86223623'/>
- <class-decl name='blkid_struct_dev_iterate' is-struct='yes' visibility='default' is-declaration-only='yes' id='d88420d6'/>
- <class-decl name='udev_list_entry' is-struct='yes' visibility='default' is-declaration-only='yes' id='e7dbdca3'/>
- <function-decl name='for_each_vdev_in_nvlist' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='dff793e0'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='label_paths' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5507783b'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='7d3cd834'/>
- <parameter type-id='7d3cd834'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zutil_alloc' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5507783b'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='zutil_strdup' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5507783b'/>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='slice_cache_compare' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='blkid_put_cache' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0882dfdf'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='blkid_get_cache' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='2e3e7caa'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='blkid_dev_devname' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f47b023a'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='blkid_dev_iterate_begin' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0882dfdf'/>
- <return type-id='f4760fa7'/>
- </function-decl>
- <function-decl name='blkid_dev_set_search' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f4760fa7'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='blkid_dev_next' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f4760fa7'/>
- <parameter type-id='d87f9b75'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='blkid_dev_iterate_end' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='f4760fa7'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='blkid_probe_all_new' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='0882dfdf'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='udev_unref' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='025eefe7'/>
- <return type-id='025eefe7'/>
- </function-decl>
- <function-decl name='udev_list_entry_get_next' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='deabd0d3'/>
- <return type-id='deabd0d3'/>
- </function-decl>
- <function-decl name='udev_list_entry_get_name' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='deabd0d3'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='udev_device_get_parent_with_subsystem_devtype' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b32bae08'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='b32bae08'/>
- </function-decl>
- <function-decl name='udev_device_get_devlinks_list_entry' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='b32bae08'/>
- <return type-id='deabd0d3'/>
- </function-decl>
- <function-decl name='sched_yield' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='usleep' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='4e80d4b1'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_dev_flush' mangled-name='zfs_dev_flush' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dev_flush'>
- <parameter type-id='95e97e5e' name='fd'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_device_get_devid' mangled-name='zfs_device_get_devid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_device_get_devid'>
- <parameter type-id='b32bae08' name='dev'/>
- <parameter type-id='26a90f95' name='bufptr'/>
- <parameter type-id='b59d7dce' name='buflen'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_device_get_physical' mangled-name='zfs_device_get_physical' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_device_get_physical'>
- <parameter type-id='b32bae08' name='dev'/>
- <parameter type-id='26a90f95' name='bufptr'/>
- <parameter type-id='b59d7dce' name='buflen'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_disk_wait' mangled-name='zpool_disk_wait' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_disk_wait'>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='update_vdev_config_dev_sysfs_path' mangled-name='update_vdev_config_dev_sysfs_path' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='update_vdev_config_dev_sysfs_path'>
- <parameter type-id='5ce45b60' name='nv'/>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='80f4b756' name='key'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-type size-in-bits='64' id='2ec2411e'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='5ce45b60'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/os/linux/zutil_setproctitle.c' language='LANG_C99'>
- <function-decl name='warnx' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter is-variadic='yes'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='setenv' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='95e97e5e'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='clearenv' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_setproctitle_init' mangled-name='zfs_setproctitle_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle_init'>
- <parameter type-id='95e97e5e' name='argc'/>
- <parameter type-id='9b23c9ad' name='argv'/>
- <parameter type-id='9b23c9ad' name='envp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/zutil_device_path.c' language='LANG_C99'>
- <function-decl name='zpool_default_search_paths' mangled-name='zpool_default_search_paths' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_default_search_paths'>
- <parameter type-id='78c01427'/>
- <return type-id='13956559'/>
- </function-decl>
- <function-decl name='zfs_dirnamelen' mangled-name='zfs_dirnamelen' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dirnamelen'>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='79a0948f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/zutil_import.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='a84c031d' size-in-bits='256' id='16dc656a'>
- <subrange length='32' type-id='7359adad' id='ae5bde82'/>
- </array-type-def>
- <class-decl name='importargs' size-in-bits='512' is-struct='yes' visibility='default' id='7ac83801'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='path' type-id='9b23c9ad' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='paths' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='poolname' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='guid' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='cachefile' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='can_be_active' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='352'>
- <var-decl name='scan' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='policy' type-id='5ce45b60' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='do_destroyed' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='480'>
- <var-decl name='do_all' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='importargs_t' type-id='7ac83801' id='7a842a6b'/>
- <class-decl name='libpc_handle' size-in-bits='8448' is-struct='yes' visibility='default' id='7c8737f0'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='lpc_error' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='lpc_printerr' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='lpc_open_access_error' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='96'>
- <var-decl name='lpc_desc_active' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='lpc_desc' type-id='b54ce520' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8320'>
- <var-decl name='lpc_ops' type-id='f095e320' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='8384'>
- <var-decl name='lpc_lib_handle' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='libpc_handle_t' type-id='7c8737f0' id='8a70a786'/>
- <class-decl name='aiocb' size-in-bits='1344' is-struct='yes' visibility='default' id='e4957c49'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='aio_fildes' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='32'>
- <var-decl name='aio_lio_opcode' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='aio_reqprio' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='aio_buf' type-id='fe09dd29' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='aio_nbytes' type-id='b59d7dce' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='aio_sigevent' type-id='519bc206' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='768'>
- <var-decl name='__next_prio' type-id='924bbc81' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='832'>
- <var-decl name='__abs_prio' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='864'>
- <var-decl name='__policy' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='896'>
- <var-decl name='__error_code' type-id='95e97e5e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='960'>
- <var-decl name='__return_value' type-id='41060289' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1024'>
- <var-decl name='aio_offset' type-id='724e4de6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='1088'>
- <var-decl name='__glibc_reserved' type-id='16dc656a' visibility='default'/>
- </data-member>
- </class-decl>
- <pointer-type-def type-id='e4957c49' size-in-bits='64' id='924bbc81'/>
- <qualified-type-def type-id='924bbc81' const='yes' id='5499dcde'/>
- <pointer-type-def type-id='5499dcde' size-in-bits='64' id='2236d41c'/>
- <qualified-type-def type-id='2236d41c' restrict='yes' id='31488924'/>
- <pointer-type-def type-id='a3681dea' size-in-bits='64' id='fce6d540'/>
- <qualified-type-def type-id='e4957c49' const='yes' id='fced9da2'/>
- <pointer-type-def type-id='fced9da2' size-in-bits='64' id='b20efd18'/>
- <pointer-type-def type-id='7a842a6b' size-in-bits='64' id='07ee4a58'/>
- <pointer-type-def type-id='8a70a786' size-in-bits='64' id='5507783b'/>
- <pointer-type-def type-id='b1e62775' size-in-bits='64' id='f095e320'/>
- <qualified-type-def type-id='48b5725f' volatile='yes' id='b0b3cbf9'/>
- <pointer-type-def type-id='b0b3cbf9' size-in-bits='64' id='fe09dd29'/>
- <function-decl name='update_vdev_config_dev_strs' mangled-name='update_vdev_config_dev_strs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='update_vdev_config_dev_strs'>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='update_vdevs_config_dev_sysfs_path' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5ce45b60'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='spl_pagesize' mangled-name='spl_pagesize' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='spl_pagesize'>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='posix_memalign' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='63e171df'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='b59d7dce'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='sysconf' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='95e97e5e'/>
- <return type-id='bd54fe1a'/>
- </function-decl>
- <function-decl name='libpc_error_description' mangled-name='libpc_error_description' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libpc_error_description'>
- <parameter type-id='5507783b' name='hdl'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_search_import' mangled-name='zpool_search_import' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_search_import'>
- <parameter type-id='5507783b' name='hdl'/>
- <parameter type-id='07ee4a58' name='import'/>
- <return type-id='5ce45b60'/>
- </function-decl>
- <function-decl name='zpool_find_config' mangled-name='zpool_find_config' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_find_config'>
- <parameter type-id='5507783b' name='hdl'/>
- <parameter type-id='80f4b756' name='target'/>
- <parameter type-id='857bb57e' name='configp'/>
- <parameter type-id='07ee4a58' name='args'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_find_import_blkid' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='5507783b'/>
- <parameter type-id='18c91f9e'/>
- <parameter type-id='fce6d540'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_open_func' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/zutil_nicenum.c' language='LANG_C99'>
- <type-decl name='long double' size-in-bits='128' id='e095c704'/>
- <enum-decl name='zfs_nicenum_format' id='29cf1969'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_NICENUM_1024' value='0'/>
- <enumerator name='ZFS_NICENUM_BYTES' value='1'/>
- <enumerator name='ZFS_NICENUM_TIME' value='2'/>
- <enumerator name='ZFS_NICENUM_RAW' value='3'/>
- <enumerator name='ZFS_NICENUM_RAWTIME' value='4'/>
- </enum-decl>
- <function-decl name='powl' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e095c704'/>
- <parameter type-id='e095c704'/>
- <return type-id='e095c704'/>
- </function-decl>
- <function-decl name='floor' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='a0eb0f08'/>
- <return type-id='a0eb0f08'/>
- </function-decl>
- <function-decl name='zfs_isnumber' mangled-name='zfs_isnumber' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_isnumber'>
- <parameter type-id='80f4b756' name='str'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_nicenum_format' mangled-name='zfs_nicenum_format' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_nicenum_format'>
- <parameter type-id='9c313c2d' name='num'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='buflen'/>
- <parameter type-id='29cf1969' name='format'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_nicetime' mangled-name='zfs_nicetime' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_nicetime'>
- <parameter type-id='9c313c2d' name='num'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='buflen'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfs_niceraw' mangled-name='zfs_niceraw' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_niceraw'>
- <parameter type-id='9c313c2d' name='num'/>
- <parameter type-id='26a90f95' name='buf'/>
- <parameter type-id='b59d7dce' name='buflen'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='lib/libzutil/zutil_pool.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='853fd5dc' size-in-bits='32768' id='b505fc2f'>
- <subrange length='64' type-id='7359adad' id='b10be967'/>
- </array-type-def>
- <type-decl name='float' size-in-bits='32' id='a6c45d85'/>
- <class-decl name='ddt_stat' size-in-bits='512' is-struct='yes' visibility='default' id='65242dfe'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='dds_blocks' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='dds_lsize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='dds_psize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='dds_dsize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='dds_ref_blocks' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='dds_ref_lsize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='dds_ref_psize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='dds_ref_dsize' type-id='9c313c2d' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='ddt_stat_t' type-id='65242dfe' id='853fd5dc'/>
- <class-decl name='ddt_histogram' size-in-bits='32768' is-struct='yes' visibility='default' id='bc2b3086'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='ddh_stat' type-id='b505fc2f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='ddt_histogram_t' type-id='bc2b3086' id='2d7fe832'/>
- <qualified-type-def type-id='2d7fe832' const='yes' id='ec92d602'/>
- <pointer-type-def type-id='ec92d602' size-in-bits='64' id='932720f8'/>
- <qualified-type-def type-id='853fd5dc' const='yes' id='764c298c'/>
- <pointer-type-def type-id='764c298c' size-in-bits='64' id='dfe59052'/>
- <qualified-type-def type-id='a9c79a1f' const='yes' id='cd087e36'/>
- <pointer-type-def type-id='cd087e36' size-in-bits='64' id='e05e8614'/>
- <function-decl name='nanosleep' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='e05e8614'/>
- <parameter type-id='3d83ba87'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_dump_ddt' mangled-name='zpool_dump_ddt' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_dump_ddt'>
- <parameter type-id='dfe59052' name='dds_total'/>
- <parameter type-id='932720f8' name='ddh'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fsleep' mangled-name='fsleep' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fsleep'>
- <parameter type-id='a6c45d85' name='sec'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zpool_getenv_int' mangled-name='zpool_getenv_int' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_getenv_int'>
- <parameter type-id='80f4b756' name='env'/>
- <parameter type-id='95e97e5e' name='default_val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/avl/avl.c' language='LANG_C99'>
- <function-decl name='avl_last' mangled-name='avl_last' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_last'>
- <parameter type-id='a3681dea' name='tree'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='avl_nearest' mangled-name='avl_nearest' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_nearest'>
- <parameter type-id='a3681dea' name='tree'/>
- <parameter type-id='fba6cb51' name='where'/>
- <parameter type-id='95e97e5e' name='direction'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='avl_insert_here' mangled-name='avl_insert_here' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_insert_here'>
- <parameter type-id='a3681dea' name='tree'/>
- <parameter type-id='eaa32e2f' name='new_data'/>
- <parameter type-id='eaa32e2f' name='here'/>
- <parameter type-id='95e97e5e' name='direction'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_update_lt' mangled-name='avl_update_lt' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_update_lt'>
- <parameter type-id='a3681dea' name='t'/>
- <parameter type-id='eaa32e2f' name='obj'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='avl_update_gt' mangled-name='avl_update_gt' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_update_gt'>
- <parameter type-id='a3681dea' name='t'/>
- <parameter type-id='eaa32e2f' name='obj'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='avl_update' mangled-name='avl_update' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_update'>
- <parameter type-id='a3681dea' name='t'/>
- <parameter type-id='eaa32e2f' name='obj'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='avl_swap' mangled-name='avl_swap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_swap'>
- <parameter type-id='a3681dea' name='tree1'/>
- <parameter type-id='a3681dea' name='tree2'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='avl_is_empty' mangled-name='avl_is_empty' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='avl_is_empty'>
- <parameter type-id='a3681dea' name='tree'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/cityhash.c' language='LANG_C99'>
- <function-decl name='cityhash1' mangled-name='cityhash1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash1'>
- <parameter type-id='9c313c2d' name='w'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='cityhash2' mangled-name='cityhash2' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash2'>
- <parameter type-id='9c313c2d' name='w1'/>
- <parameter type-id='9c313c2d' name='w2'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='cityhash3' mangled-name='cityhash3' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash3'>
- <parameter type-id='9c313c2d' name='w1'/>
- <parameter type-id='9c313c2d' name='w2'/>
- <parameter type-id='9c313c2d' name='w3'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='cityhash4' mangled-name='cityhash4' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='cityhash4'>
- <parameter type-id='9c313c2d' name='w1'/>
- <parameter type-id='9c313c2d' name='w2'/>
- <parameter type-id='9c313c2d' name='w3'/>
- <parameter type-id='9c313c2d' name='w4'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='21056' id='fd43354e'>
- <subrange length='47' type-id='7359adad' id='8f8900fe'/>
- </array-type-def>
- <enum-decl name='zfeature_flags' id='6db816a4'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFEATURE_FLAG_READONLY_COMPAT' value='1'/>
- <enumerator name='ZFEATURE_FLAG_MOS' value='2'/>
- <enumerator name='ZFEATURE_FLAG_ACTIVATE_ON_ENABLE' value='4'/>
- <enumerator name='ZFEATURE_FLAG_PER_DATASET' value='8'/>
- <enumerator name='ZFEATURE_FLAG_NO_UPGRADE' value='16'/>
- </enum-decl>
- <typedef-decl name='zfeature_flags_t' type-id='6db816a4' id='fc329033'/>
- <enum-decl name='zfeature_type' id='c4fa2355'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFEATURE_TYPE_BOOLEAN' value='0'/>
- <enumerator name='ZFEATURE_TYPE_UINT64_ARRAY' value='1'/>
- <enumerator name='ZFEATURE_NUM_TYPES' value='2'/>
- </enum-decl>
- <typedef-decl name='zfeature_type_t' type-id='c4fa2355' id='732d2bb2'/>
- <class-decl name='zfeature_info' size-in-bits='448' is-struct='yes' visibility='default' id='1178d146'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='fi_feature' type-id='d6618c78' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='fi_uname' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='fi_guid' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='fi_desc' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='fi_flags' type-id='fc329033' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='288'>
- <var-decl name='fi_zfs_mod_supported' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='fi_type' type-id='732d2bb2' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='fi_depends' type-id='1acff326' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfeature_info_t' type-id='1178d146' id='83f29ca2'/>
- <typedef-decl name='__free_fn_t' type-id='b7f9d8e6' id='3ff5e51e'/>
- <class-decl name='dirent' size-in-bits='2240' is-struct='yes' visibility='default' id='611586a1'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='d_ino' type-id='71288a47' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='d_off' type-id='724e4de6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='d_reclen' type-id='8efea9e5' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='144'>
- <var-decl name='d_type' type-id='002ac4a6' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='152'>
- <var-decl name='d_name' type-id='d1617432' visibility='default'/>
- </data-member>
- </class-decl>
- <class-decl name='zfs_mod_supported_features' size-in-bits='128' is-struct='yes' visibility='default' id='3eee3342'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='tree' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='all_features' type-id='c19b74c3' visibility='default'/>
- </data-member>
- </class-decl>
- <qualified-type-def type-id='d6618c78' const='yes' id='81a65028'/>
- <pointer-type-def type-id='81a65028' size-in-bits='64' id='1acff326'/>
- <qualified-type-def type-id='3eee3342' const='yes' id='0c1d5bbb'/>
- <pointer-type-def type-id='0c1d5bbb' size-in-bits='64' id='a3372543'/>
- <pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
- <qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
- <pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
- <var-decl name='spa_feature_table' type-id='fd43354e' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
- <var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
- <function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='f09217ba'/>
- </function-decl>
- <function-decl name='tsearch' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='63e171df'/>
- <parameter type-id='aba7edd8'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='tfind' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='7acd98a2'/>
- <parameter type-id='aba7edd8'/>
- <return type-id='eaa32e2f'/>
- </function-decl>
- <function-decl name='tdestroy' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='3ff5e51e'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zfeature_is_valid_guid' mangled-name='zfeature_is_valid_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_is_valid_guid'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfeature_depends_on' mangled-name='zfeature_depends_on' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_depends_on'>
- <parameter type-id='d6618c78' name='fid'/>
- <parameter type-id='d6618c78' name='check'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_mod_supported' mangled-name='zfs_mod_supported' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_mod_supported'>
- <parameter type-id='80f4b756' name='scope'/>
- <parameter type-id='80f4b756' name='name'/>
- <parameter type-id='a3372543' name='sfeatures'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_comutil.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='b99c00c9' size-in-bits='2624' id='5ce15418'>
- <subrange length='41' type-id='7359adad' id='cb834f44'/>
- </array-type-def>
- <pointer-type-def type-id='8f92235e' size-in-bits='64' id='90421557'/>
- <function-decl name='nvpair_value_uint32' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='dace003f'/>
- <parameter type-id='90421557'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <var-decl name='zfs_history_event_names' type-id='5ce15418' mangled-name='zfs_history_event_names' visibility='default' elf-symbol-id='zfs_history_event_names'/>
- <function-decl name='strpbrk' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <return type-id='26a90f95'/>
- </function-decl>
- <function-decl name='zfs_allocatable_devs' mangled-name='zfs_allocatable_devs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_allocatable_devs'>
- <parameter type-id='5ce45b60' name='nv'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_special_devs' mangled-name='zfs_special_devs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_special_devs'>
- <parameter type-id='5ce45b60' name='nv'/>
- <parameter type-id='80f4b756' name='type'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_zpl_version_map' mangled-name='zfs_zpl_version_map' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_zpl_version_map'>
- <parameter type-id='95e97e5e' name='spa_version'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_spa_version_map' mangled-name='zfs_spa_version_map' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_spa_version_map'>
- <parameter type-id='95e97e5e' name='zpl_version'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_dataset_name_hidden' mangled-name='zfs_dataset_name_hidden' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_dataset_name_hidden'>
- <parameter type-id='80f4b756' name='name'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_deleg.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='fa1870fd' size-in-bits='4352' id='55f84f08'>
- <subrange length='34' type-id='7359adad' id='6a6a7e00'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='fa1870fd' size-in-bits='infinite' id='7c00e69d'>
- <subrange length='infinite' id='031f2035'/>
- </array-type-def>
- <enum-decl name='zfs_deleg_who_type_t' naming-typedef-id='36d4bd5a' id='b5fa5816'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_DELEG_WHO_UNKNOWN' value='0'/>
- <enumerator name='ZFS_DELEG_USER' value='117'/>
- <enumerator name='ZFS_DELEG_USER_SETS' value='85'/>
- <enumerator name='ZFS_DELEG_GROUP' value='103'/>
- <enumerator name='ZFS_DELEG_GROUP_SETS' value='71'/>
- <enumerator name='ZFS_DELEG_EVERYONE' value='101'/>
- <enumerator name='ZFS_DELEG_EVERYONE_SETS' value='69'/>
- <enumerator name='ZFS_DELEG_CREATE' value='99'/>
- <enumerator name='ZFS_DELEG_CREATE_SETS' value='67'/>
- <enumerator name='ZFS_DELEG_NAMED_SET' value='115'/>
- <enumerator name='ZFS_DELEG_NAMED_SET_SETS' value='83'/>
- </enum-decl>
- <typedef-decl name='zfs_deleg_who_type_t' type-id='b5fa5816' id='36d4bd5a'/>
- <enum-decl name='zfs_deleg_note_t' naming-typedef-id='4613c173' id='729d4547'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZFS_DELEG_NOTE_CREATE' value='0'/>
- <enumerator name='ZFS_DELEG_NOTE_DESTROY' value='1'/>
- <enumerator name='ZFS_DELEG_NOTE_SNAPSHOT' value='2'/>
- <enumerator name='ZFS_DELEG_NOTE_ROLLBACK' value='3'/>
- <enumerator name='ZFS_DELEG_NOTE_CLONE' value='4'/>
- <enumerator name='ZFS_DELEG_NOTE_PROMOTE' value='5'/>
- <enumerator name='ZFS_DELEG_NOTE_RENAME' value='6'/>
- <enumerator name='ZFS_DELEG_NOTE_SEND' value='7'/>
- <enumerator name='ZFS_DELEG_NOTE_SEND_RAW' value='8'/>
- <enumerator name='ZFS_DELEG_NOTE_RECEIVE' value='9'/>
- <enumerator name='ZFS_DELEG_NOTE_ALLOW' value='10'/>
- <enumerator name='ZFS_DELEG_NOTE_USERPROP' value='11'/>
- <enumerator name='ZFS_DELEG_NOTE_MOUNT' value='12'/>
- <enumerator name='ZFS_DELEG_NOTE_SHARE' value='13'/>
- <enumerator name='ZFS_DELEG_NOTE_USERQUOTA' value='14'/>
- <enumerator name='ZFS_DELEG_NOTE_GROUPQUOTA' value='15'/>
- <enumerator name='ZFS_DELEG_NOTE_USERUSED' value='16'/>
- <enumerator name='ZFS_DELEG_NOTE_GROUPUSED' value='17'/>
- <enumerator name='ZFS_DELEG_NOTE_USEROBJQUOTA' value='18'/>
- <enumerator name='ZFS_DELEG_NOTE_GROUPOBJQUOTA' value='19'/>
- <enumerator name='ZFS_DELEG_NOTE_USEROBJUSED' value='20'/>
- <enumerator name='ZFS_DELEG_NOTE_GROUPOBJUSED' value='21'/>
- <enumerator name='ZFS_DELEG_NOTE_HOLD' value='22'/>
- <enumerator name='ZFS_DELEG_NOTE_RELEASE' value='23'/>
- <enumerator name='ZFS_DELEG_NOTE_DIFF' value='24'/>
- <enumerator name='ZFS_DELEG_NOTE_BOOKMARK' value='25'/>
- <enumerator name='ZFS_DELEG_NOTE_LOAD_KEY' value='26'/>
- <enumerator name='ZFS_DELEG_NOTE_CHANGE_KEY' value='27'/>
- <enumerator name='ZFS_DELEG_NOTE_PROJECTUSED' value='28'/>
- <enumerator name='ZFS_DELEG_NOTE_PROJECTQUOTA' value='29'/>
- <enumerator name='ZFS_DELEG_NOTE_PROJECTOBJUSED' value='30'/>
- <enumerator name='ZFS_DELEG_NOTE_PROJECTOBJQUOTA' value='31'/>
- <enumerator name='ZFS_DELEG_NOTE_NONE' value='32'/>
- </enum-decl>
- <typedef-decl name='zfs_deleg_note_t' type-id='729d4547' id='4613c173'/>
- <class-decl name='zfs_deleg_perm_tab' size-in-bits='128' is-struct='yes' visibility='default' id='5aa05c1f'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='z_perm' type-id='80f4b756' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='z_note' type-id='4613c173' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_deleg_perm_tab_t' type-id='5aa05c1f' id='f3f851ad'/>
- <qualified-type-def type-id='f3f851ad' const='yes' id='fa1870fd'/>
- <var-decl name='zfs_deleg_perm_tab' type-id='7c00e69d' mangled-name='zfs_deleg_perm_tab' visibility='default' elf-symbol-id='zfs_deleg_perm_tab'/>
- <function-decl name='permset_namecheck' mangled-name='permset_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='permset_namecheck'>
- <parameter type-id='80f4b756'/>
- <parameter type-id='053457bd'/>
- <parameter type-id='26a90f95'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_delegatable' mangled-name='zfs_prop_delegatable' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_delegatable'>
- <parameter type-id='58603c44'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_deleg_canonicalize_perm' mangled-name='zfs_deleg_canonicalize_perm' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_deleg_canonicalize_perm'>
- <parameter type-id='80f4b756' name='perm'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_deleg_verify_nvlist' mangled-name='zfs_deleg_verify_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_deleg_verify_nvlist'>
- <parameter type-id='5ce45b60' name='nvp'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_deleg_whokey' mangled-name='zfs_deleg_whokey' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_deleg_whokey'>
- <parameter type-id='26a90f95' name='attr'/>
- <parameter type-id='36d4bd5a' name='type'/>
- <parameter type-id='a84c031d' name='inheritchr'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='48b5725f'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='9c313c2d' size-in-bits='512' id='c5d13f42'>
- <subrange length='8' type-id='7359adad' id='56e0c0b1'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='90dbb6d6' size-in-bits='2048' id='16582e69'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='8240361c' size-in-bits='1024' id='481f90b1'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='7c1ab40c' size-in-bits='512' id='cbd91ec1'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <array-type-def dimensions='1' type-id='6d059eaa' size-in-bits='1024' id='729b6ebb'>
- <subrange length='4' type-id='7359adad' id='16fe7105'/>
- </array-type-def>
- <enum-decl name='zio_byteorder_t' naming-typedef-id='595a65ec' id='fc861be0'>
- <underlying-type type-id='9cac1fee'/>
- <enumerator name='ZIO_CHECKSUM_NATIVE' value='0'/>
- <enumerator name='ZIO_CHECKSUM_BYTESWAP' value='1'/>
- </enum-decl>
- <typedef-decl name='zio_byteorder_t' type-id='fc861be0' id='595a65ec'/>
- <class-decl name='zio_abd_checksum_data' size-in-bits='256' is-struct='yes' visibility='default' id='4bf4b004'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='acd_byteorder' type-id='595a65ec' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='acd_ctx' type-id='0f7df99e' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='acd_zcp' type-id='c24fc2ee' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='acd_private' type-id='eaa32e2f' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zio_abd_checksum_data_t' type-id='4bf4b004' id='74e39470'/>
- <typedef-decl name='zio_abd_checksum_init_t' type-id='a5444274' id='029a8ebe'/>
- <typedef-decl name='zio_abd_checksum_fini_t' type-id='a5444274' id='d6fd5c6c'/>
- <typedef-decl name='zio_abd_checksum_iter_t' type-id='f4a1892e' id='cefa0f4a'/>
- <class-decl name='zio_abd_checksum_func' size-in-bits='192' is-struct='yes' visibility='default' id='aa14691a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='acf_init' type-id='0bcca125' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='acf_fini' type-id='bfe36153' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='acf_iter' type-id='1e276399' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zio_abd_checksum_func_t' type-id='3f8e8d11' id='c2eb138a'/>
- <class-decl name='zfs_fletcher_superscalar' size-in-bits='256' is-struct='yes' visibility='default' id='28efb250'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='v' type-id='85c64d26' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_fletcher_superscalar_t' type-id='28efb250' id='6d059eaa'/>
- <class-decl name='zfs_fletcher_sse' size-in-bits='128' is-struct='yes' visibility='default' id='acd4019a'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='v' type-id='c1c22e6c' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_fletcher_sse_t' type-id='acd4019a' id='7c1ab40c'/>
- <class-decl name='zfs_fletcher_avx' size-in-bits='256' is-struct='yes' visibility='default' id='8c208dfa'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='v' type-id='85c64d26' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_fletcher_avx_t' type-id='8c208dfa' id='8240361c'/>
- <class-decl name='zfs_fletcher_avx512' size-in-bits='512' is-struct='yes' visibility='default' id='c6d0c382'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='v' type-id='c5d13f42' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='zfs_fletcher_avx512_t' type-id='c6d0c382' id='90dbb6d6'/>
- <union-decl name='fletcher_4_ctx' size-in-bits='2048' visibility='default' id='1f951ade'>
- <data-member access='public'>
- <var-decl name='scalar' type-id='39730d0b' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='superscalar' type-id='729b6ebb' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='sse' type-id='cbd91ec1' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='avx' type-id='481f90b1' visibility='default'/>
- </data-member>
- <data-member access='public'>
- <var-decl name='avx512' type-id='16582e69' visibility='default'/>
- </data-member>
- </union-decl>
- <typedef-decl name='fletcher_4_ctx_t' type-id='1f951ade' id='4b675395'/>
- <qualified-type-def type-id='aa14691a' const='yes' id='3f8e8d11'/>
- <pointer-type-def type-id='4b675395' size-in-bits='64' id='0f7df99e'/>
- <qualified-type-def type-id='8f92235e' volatile='yes' id='430e0681'/>
- <pointer-type-def type-id='430e0681' size-in-bits='64' id='3a147f31'/>
- <pointer-type-def type-id='74e39470' size-in-bits='64' id='eefe7427'/>
- <pointer-type-def type-id='d6fd5c6c' size-in-bits='64' id='bfe36153'/>
- <pointer-type-def type-id='029a8ebe' size-in-bits='64' id='0bcca125'/>
- <pointer-type-def type-id='cefa0f4a' size-in-bits='64' id='1e276399'/>
- <var-decl name='fletcher_4_abd_ops' type-id='c2eb138a' mangled-name='fletcher_4_abd_ops' visibility='default' elf-symbol-id='fletcher_4_abd_ops'/>
- <function-decl name='atomic_swap_32' mangled-name='atomic_swap_32' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='atomic_swap_32'>
- <parameter type-id='3a147f31'/>
- <parameter type-id='8f92235e'/>
- <return type-id='8f92235e'/>
- </function-decl>
- <function-decl name='membar_producer' mangled-name='membar_producer' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='membar_producer'>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_init' mangled-name='fletcher_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_init'>
- <parameter type-id='c24fc2ee' name='zcp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_2_incremental_native' mangled-name='fletcher_2_incremental_native' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_2_incremental_native'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='b59d7dce' name='size'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fletcher_2_native' mangled-name='fletcher_2_native' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_2_native'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='9c313c2d' name='size'/>
- <parameter type-id='eaa32e2f' name='ctx_template'/>
- <parameter type-id='c24fc2ee' name='zcp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_2_incremental_byteswap' mangled-name='fletcher_2_incremental_byteswap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_2_incremental_byteswap'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='b59d7dce' name='size'/>
- <parameter type-id='eaa32e2f' name='data'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fletcher_2_byteswap' mangled-name='fletcher_2_byteswap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_2_byteswap'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='9c313c2d' name='size'/>
- <parameter type-id='eaa32e2f' name='ctx_template'/>
- <parameter type-id='c24fc2ee' name='zcp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_4_impl_set' mangled-name='fletcher_4_impl_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_impl_set'>
- <parameter type-id='80f4b756' name='val'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='fletcher_4_native' mangled-name='fletcher_4_native' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_native'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='9c313c2d' name='size'/>
- <parameter type-id='eaa32e2f' name='ctx_template'/>
- <parameter type-id='c24fc2ee' name='zcp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='fletcher_4_byteswap' mangled-name='fletcher_4_byteswap' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='fletcher_4_byteswap'>
- <parameter type-id='eaa32e2f' name='buf'/>
- <parameter type-id='9c313c2d' name='size'/>
- <parameter type-id='eaa32e2f' name='ctx_template'/>
- <parameter type-id='c24fc2ee' name='zcp'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-type size-in-bits='64' id='f4a1892e'>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='b59d7dce'/>
- <parameter type-id='eaa32e2f'/>
- <return type-id='95e97e5e'/>
- </function-type>
- <function-type size-in-bits='64' id='a5444274'>
- <parameter type-id='eefe7427'/>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher_avx512.c' language='LANG_C99'>
- <typedef-decl name='fletcher_4_init_f' type-id='173aa527' id='b9ae1656'/>
- <typedef-decl name='fletcher_4_fini_f' type-id='0ad5b8a8' id='c4c1f4fc'/>
- <typedef-decl name='fletcher_4_compute_f' type-id='38147eff' id='ad1dc4cb'/>
- <class-decl name='fletcher_4_func' size-in-bits='1024' is-struct='yes' visibility='default' id='57f479a0'>
- <data-member access='public' layout-offset-in-bits='0'>
- <var-decl name='init_native' type-id='b9ae1656' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='64'>
- <var-decl name='fini_native' type-id='c4c1f4fc' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='128'>
- <var-decl name='compute_native' type-id='ad1dc4cb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='192'>
- <var-decl name='init_byteswap' type-id='b9ae1656' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='256'>
- <var-decl name='fini_byteswap' type-id='c4c1f4fc' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='320'>
- <var-decl name='compute_byteswap' type-id='ad1dc4cb' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='384'>
- <var-decl name='valid' type-id='297d38bc' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='448'>
- <var-decl name='uses_fpu' type-id='c19b74c3' visibility='default'/>
- </data-member>
- <data-member access='public' layout-offset-in-bits='512'>
- <var-decl name='name' type-id='80f4b756' visibility='default'/>
- </data-member>
- </class-decl>
- <typedef-decl name='fletcher_4_ops_t' type-id='57f479a0' id='eba91718'/>
- <qualified-type-def type-id='eba91718' const='yes' id='9eeabdc8'/>
- <pointer-type-def type-id='e9e61702' size-in-bits='64' id='297d38bc'/>
- <pointer-type-def type-id='fe40251b' size-in-bits='64' id='173aa527'/>
- <pointer-type-def type-id='17fb1f83' size-in-bits='64' id='38147eff'/>
- <pointer-type-def type-id='fb39e25e' size-in-bits='64' id='0ad5b8a8'/>
- <var-decl name='fletcher_4_avx512f_ops' type-id='9eeabdc8' mangled-name='fletcher_4_avx512f_ops' visibility='default' elf-symbol-id='fletcher_4_avx512f_ops'/>
- <var-decl name='fletcher_4_avx512bw_ops' type-id='9eeabdc8' mangled-name='fletcher_4_avx512bw_ops' visibility='default' elf-symbol-id='fletcher_4_avx512bw_ops'/>
- <function-type size-in-bits='64' id='e9e61702'>
- <return type-id='c19b74c3'/>
- </function-type>
- <function-type size-in-bits='64' id='fe40251b'>
- <parameter type-id='0f7df99e'/>
- <return type-id='48b5725f'/>
- </function-type>
- <function-type size-in-bits='64' id='17fb1f83'>
- <parameter type-id='0f7df99e'/>
- <parameter type-id='eaa32e2f'/>
- <parameter type-id='9c313c2d'/>
- <return type-id='48b5725f'/>
- </function-type>
- <function-type size-in-bits='64' id='fb39e25e'>
- <parameter type-id='0f7df99e'/>
- <parameter type-id='c24fc2ee'/>
- <return type-id='48b5725f'/>
- </function-type>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher_intel.c' language='LANG_C99'>
- <var-decl name='fletcher_4_avx2_ops' type-id='9eeabdc8' mangled-name='fletcher_4_avx2_ops' visibility='default' elf-symbol-id='fletcher_4_avx2_ops'/>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher_sse.c' language='LANG_C99'>
- <var-decl name='fletcher_4_sse2_ops' type-id='9eeabdc8' mangled-name='fletcher_4_sse2_ops' visibility='default' elf-symbol-id='fletcher_4_sse2_ops'/>
- <var-decl name='fletcher_4_ssse3_ops' type-id='9eeabdc8' mangled-name='fletcher_4_ssse3_ops' visibility='default' elf-symbol-id='fletcher_4_ssse3_ops'/>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher_superscalar.c' language='LANG_C99'>
- <var-decl name='fletcher_4_superscalar_ops' type-id='9eeabdc8' mangled-name='fletcher_4_superscalar_ops' visibility='default' elf-symbol-id='fletcher_4_superscalar_ops'/>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_fletcher_superscalar4.c' language='LANG_C99'>
- <var-decl name='fletcher_4_superscalar4_ops' type-id='9eeabdc8' mangled-name='fletcher_4_superscalar4_ops' visibility='default' elf-symbol-id='fletcher_4_superscalar4_ops'/>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_namecheck.c' language='LANG_C99'>
- <var-decl name='zfs_max_dataset_nesting' type-id='95e97e5e' mangled-name='zfs_max_dataset_nesting' visibility='default' elf-symbol-id='zfs_max_dataset_nesting'/>
- <function-decl name='get_dataset_depth' mangled-name='get_dataset_depth' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_dataset_depth'>
- <parameter type-id='80f4b756' name='path'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_component_namecheck' mangled-name='zfs_component_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_component_namecheck'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='053457bd' name='why'/>
- <parameter type-id='26a90f95' name='what'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='dataset_namecheck' mangled-name='dataset_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dataset_namecheck'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='053457bd' name='why'/>
- <parameter type-id='26a90f95' name='what'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='bookmark_namecheck' mangled-name='bookmark_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='bookmark_namecheck'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='053457bd' name='why'/>
- <parameter type-id='26a90f95' name='what'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='snapshot_namecheck' mangled-name='snapshot_namecheck' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='snapshot_namecheck'>
- <parameter type-id='80f4b756' name='path'/>
- <parameter type-id='053457bd' name='why'/>
- <parameter type-id='26a90f95' name='what'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_prop.c' language='LANG_C99'>
- <array-type-def dimensions='1' type-id='b99c00c9' size-in-bits='768' id='bcc77e38'>
- <subrange length='12' type-id='7359adad' id='84827bdc'/>
- </array-type-def>
- <pointer-type-def type-id='3eee3342' size-in-bits='64' id='73f8e240'/>
- <var-decl name='zfs_userquota_prop_prefixes' type-id='bcc77e38' mangled-name='zfs_userquota_prop_prefixes' visibility='default' elf-symbol-id='zfs_userquota_prop_prefixes'/>
- <function-decl name='zfs_mod_list_supported' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='80f4b756'/>
- <return type-id='73f8e240'/>
- </function-decl>
- <function-decl name='zfs_mod_list_supported_free' visibility='default' binding='global' size-in-bits='64'>
- <parameter type-id='73f8e240'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_register_impl' mangled-name='zprop_register_impl' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_impl'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='31429eff'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='999701cc'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='c8bc397b'/>
- <parameter type-id='a3372543'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_register_string' mangled-name='zprop_register_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_string'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='999701cc'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='a3372543'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_register_number' mangled-name='zprop_register_number' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_number'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='999701cc'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='a3372543'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_register_index' mangled-name='zprop_register_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_index'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='999701cc'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c8bc397b'/>
- <parameter type-id='a3372543'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_register_hidden' mangled-name='zprop_register_hidden' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_register_hidden'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='31429eff'/>
- <parameter type-id='999701cc'/>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='80f4b756'/>
- <parameter type-id='c19b74c3'/>
- <parameter type-id='a3372543'/>
- <return type-id='48b5725f'/>
- </function-decl>
- <function-decl name='zprop_index_to_string' mangled-name='zprop_index_to_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_index_to_string'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='7d3cd834'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zprop_random_value' mangled-name='zprop_random_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_random_value'>
- <parameter type-id='95e97e5e'/>
- <parameter type-id='9c313c2d'/>
- <parameter type-id='2e45de5d'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zprop_valid_char' mangled-name='zprop_valid_char' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_valid_char'>
- <parameter type-id='a84c031d'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_string_to_index' mangled-name='zfs_prop_string_to_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_string_to_index'>
- <parameter type-id='58603c44' name='prop'/>
- <parameter type-id='80f4b756' name='string'/>
- <parameter type-id='5d6479ae' name='index'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_random_value' mangled-name='zfs_prop_random_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_random_value'>
- <parameter type-id='58603c44' name='prop'/>
- <parameter type-id='9c313c2d' name='seed'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zfs_prop_visible' mangled-name='zfs_prop_visible' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_visible'>
- <parameter type-id='58603c44' name='prop'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='zfs_prop_values' mangled-name='zfs_prop_values' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_values'>
- <parameter type-id='58603c44' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_prop_is_string' mangled-name='zfs_prop_is_string' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_is_string'>
- <parameter type-id='58603c44' name='prop'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zfs_prop_column_name' mangled-name='zfs_prop_column_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_column_name'>
- <parameter type-id='58603c44' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zfs_prop_align_right' mangled-name='zfs_prop_align_right' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_prop_align_right'>
- <parameter type-id='58603c44' name='prop'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zfs_valstr.c' language='LANG_C99'>
- <function-decl name='zfs_valstr_zio_flag' mangled-name='zfs_valstr_zio_flag' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_flag'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_flag_bits' mangled-name='zfs_valstr_zio_flag_bits' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_flag_bits'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_flag_pairs' mangled-name='zfs_valstr_zio_flag_pairs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_flag_pairs'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_stage' mangled-name='zfs_valstr_zio_stage' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_stage'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_stage_bits' mangled-name='zfs_valstr_zio_stage_bits' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_stage_bits'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_stage_pairs' mangled-name='zfs_valstr_zio_stage_pairs' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_stage_pairs'>
- <parameter type-id='9c313c2d' name='bits'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_type' mangled-name='zfs_valstr_zio_type' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_type'>
- <parameter type-id='95e97e5e' name='v'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- <function-decl name='zfs_valstr_zio_priority' mangled-name='zfs_valstr_zio_priority' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_valstr_zio_priority'>
- <parameter type-id='95e97e5e' name='v'/>
- <parameter type-id='26a90f95' name='out'/>
- <parameter type-id='b59d7dce' name='outlen'/>
- <return type-id='b59d7dce'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zpool_prop.c' language='LANG_C99'>
- <function-decl name='zpool_prop_string_to_index' mangled-name='zpool_prop_string_to_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_string_to_index'>
- <parameter type-id='5d0c23fb' name='prop'/>
- <parameter type-id='80f4b756' name='string'/>
- <parameter type-id='5d6479ae' name='index'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='zpool_prop_random_value' mangled-name='zpool_prop_random_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_random_value'>
- <parameter type-id='5d0c23fb' name='prop'/>
- <parameter type-id='9c313c2d' name='seed'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='zpool_prop_values' mangled-name='zpool_prop_values' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_values'>
- <parameter type-id='5d0c23fb' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_prop_column_name' mangled-name='zpool_prop_column_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_column_name'>
- <parameter type-id='5d0c23fb' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='zpool_prop_align_right' mangled-name='zpool_prop_align_right' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_prop_align_right'>
- <parameter type-id='5d0c23fb' name='prop'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- <function-decl name='vdev_prop_get_table' mangled-name='vdev_prop_get_table' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_get_table'>
- <return type-id='76c8174b'/>
- </function-decl>
- <function-decl name='vdev_prop_string_to_index' mangled-name='vdev_prop_string_to_index' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_string_to_index'>
- <parameter type-id='5aa5c90c' name='prop'/>
- <parameter type-id='80f4b756' name='string'/>
- <parameter type-id='5d6479ae' name='index'/>
- <return type-id='95e97e5e'/>
- </function-decl>
- <function-decl name='vdev_prop_random_value' mangled-name='vdev_prop_random_value' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_random_value'>
- <parameter type-id='5aa5c90c' name='prop'/>
- <parameter type-id='9c313c2d' name='seed'/>
- <return type-id='9c313c2d'/>
- </function-decl>
- <function-decl name='vdev_prop_values' mangled-name='vdev_prop_values' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_values'>
- <parameter type-id='5aa5c90c' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='vdev_prop_column_name' mangled-name='vdev_prop_column_name' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_column_name'>
- <parameter type-id='5aa5c90c' name='prop'/>
- <return type-id='80f4b756'/>
- </function-decl>
- <function-decl name='vdev_prop_align_right' mangled-name='vdev_prop_align_right' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vdev_prop_align_right'>
- <parameter type-id='5aa5c90c' name='prop'/>
- <return type-id='c19b74c3'/>
- </function-decl>
- </abi-instr>
- <abi-instr address-size='64' path='module/zcommon/zprop_common.c' language='LANG_C99'>
- <function-decl name='__ctype_tolower_loc' visibility='default' binding='global' size-in-bits='64'>
- <return type-id='24f95ba5'/>
- </function-decl>
- </abi-instr>
-</abi-corpus>
diff --git a/lib/libzfs/libzfs.pc.in b/lib/libzfs/libzfs.pc.in
deleted file mode 100644
index afe5635ae633..000000000000
--- a/lib/libzfs/libzfs.pc.in
+++ /dev/null
@@ -1,14 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libzfs
-Description: LibZFS library
-Version: @VERSION@
-URL: https://github.com/openzfs/zfs
-Requires: libzfs_core
-Requires.private: @LIBCRYPTO_PC@ @ZLIB_PC@
-Cflags: -I${includedir}/libzfs -I${includedir}/libspl
-Libs: -L${libdir} -lzfs -lnvpair
-Libs.private: -luutil -lm -pthread
diff --git a/lib/libzfs/libzfs.suppr b/lib/libzfs/libzfs.suppr
deleted file mode 100644
index d55b5b728116..000000000000
--- a/lib/libzfs/libzfs.suppr
+++ /dev/null
@@ -1,13 +0,0 @@
-[suppress_type]
- name = FILE*
-
-[suppress_type]
- type_kind = typedef
- name = SHA256_CTX
-
-[suppress_type]
- type_kind = typedef
- name = SHA2_CTX
-
-[suppress_variable]
- name = zfs_deleg_perm_tab
diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c
deleted file mode 100644
index d290d949f4b2..000000000000
--- a/lib/libzfs/libzfs_changelist.c
+++ /dev/null
@@ -1,805 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- * Portions Copyright 2007 Ramprakash Jelari
- * Copyright (c) 2014, 2020 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright (c) 2018 Datto Inc.
- */
-
-#include <libintl.h>
-#include <libuutil.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <zone.h>
-
-#include <libzfs.h>
-
-#include "libzfs_impl.h"
-
-/*
- * Structure to keep track of dataset state. Before changing the 'sharenfs' or
- * 'mountpoint' property, we record whether the filesystem was previously
- * mounted/shared. This prior state dictates whether we remount/reshare the
- * dataset after the property has been changed.
- *
- * The interface consists of the following sequence of functions:
- *
- * changelist_gather()
- * changelist_prefix()
- * < change property >
- * changelist_postfix()
- * changelist_free()
- *
- * Other interfaces:
- *
- * changelist_remove() - remove a node from a gathered list
- * changelist_rename() - renames all datasets appropriately when doing a rename
- * changelist_unshare() - unshares all the nodes in a given changelist
- * changelist_haszonedchild() - check if there is any child exported to
- * a local zone
- */
-typedef struct prop_changenode {
- zfs_handle_t *cn_handle;
- int cn_shared;
- int cn_mounted;
- int cn_zoned;
- boolean_t cn_needpost; /* is postfix() needed? */
- uu_avl_node_t cn_treenode;
-} prop_changenode_t;
-
-struct prop_changelist {
- zfs_prop_t cl_prop;
- zfs_prop_t cl_realprop;
- zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
- uu_avl_pool_t *cl_pool;
- uu_avl_t *cl_tree;
- boolean_t cl_waslegacy;
- boolean_t cl_allchildren;
- boolean_t cl_alldependents;
- int cl_mflags; /* Mount flags */
- int cl_gflags; /* Gather request flags */
- boolean_t cl_haszonedchild;
-};
-
-/*
- * If the property is 'mountpoint', go through and unmount filesystems as
- * necessary. We don't do the same for 'sharenfs', because we can just re-share
- * with different options without interrupting service. We do handle 'sharesmb'
- * since there may be old resource names that need to be removed.
- */
-int
-changelist_prefix(prop_changelist_t *clp)
-{
- prop_changenode_t *cn;
- uu_avl_walk_t *walk;
- int ret = 0;
- const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
- boolean_t commit_smb_shares = B_FALSE;
-
- if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
- clp->cl_prop != ZFS_PROP_SHARESMB)
- return (0);
-
- /*
- * If CL_GATHER_DONT_UNMOUNT is set, don't want to unmount/unshare and
- * later (re)mount/(re)share the filesystem in postfix phase, so we
- * return from here. If filesystem is mounted or unmounted, leave it
- * as it is.
- */
- if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
- return (0);
-
- if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
- return (-1);
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
-
- /* if a previous loop failed, set the remaining to false */
- if (ret == -1) {
- cn->cn_needpost = B_FALSE;
- continue;
- }
-
- /*
- * If we are in the global zone, but this dataset is exported
- * to a local zone, do nothing.
- */
- if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
- continue;
-
- if (!ZFS_IS_VOLUME(cn->cn_handle)) {
- /*
- * Do the property specific processing.
- */
- switch (clp->cl_prop) {
- case ZFS_PROP_MOUNTPOINT:
- if (zfs_unmount(cn->cn_handle, NULL,
- clp->cl_mflags) != 0) {
- ret = -1;
- cn->cn_needpost = B_FALSE;
- }
- break;
- case ZFS_PROP_SHARESMB:
- (void) zfs_unshare(cn->cn_handle, NULL,
- smb);
- commit_smb_shares = B_TRUE;
- break;
-
- default:
- break;
- }
- }
- }
-
- if (commit_smb_shares)
- zfs_commit_shares(smb);
- uu_avl_walk_end(walk);
-
- if (ret == -1)
- (void) changelist_postfix(clp);
-
- return (ret);
-}
-
-/*
- * If the property is 'mountpoint' or 'sharenfs', go through and remount and/or
- * reshare the filesystems as necessary. In changelist_gather() we recorded
- * whether the filesystem was previously shared or mounted. The action we take
- * depends on the previous state, and whether the value was previously 'legacy'.
- * For non-legacy properties, we always remount/reshare the filesystem,
- * if CL_GATHER_DONT_UNMOUNT is not set.
- */
-int
-changelist_postfix(prop_changelist_t *clp)
-{
- prop_changenode_t *cn;
- uu_avl_walk_t *walk;
- char shareopts[ZFS_MAXPROPLEN];
- boolean_t commit_smb_shares = B_FALSE;
- boolean_t commit_nfs_shares = B_FALSE;
-
- /*
- * If CL_GATHER_DONT_UNMOUNT is set, it means we don't want to (un)mount
- * or (re/un)share the filesystem, so we return from here. If filesystem
- * is mounted or unmounted, leave it as it is.
- */
- if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
- return (0);
-
- /*
- * If we're changing the mountpoint, attempt to destroy the underlying
- * mountpoint. All other datasets will have inherited from this dataset
- * (in which case their mountpoints exist in the filesystem in the new
- * location), or have explicit mountpoints set (in which case they won't
- * be in the changelist).
- */
- if ((cn = uu_avl_last(clp->cl_tree)) == NULL)
- return (0);
-
- if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
- !(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT))
- remove_mountpoint(cn->cn_handle);
-
- /*
- * We walk the datasets in reverse, because we want to mount any parent
- * datasets before mounting the children. We walk all datasets even if
- * there are errors.
- */
- if ((walk = uu_avl_walk_start(clp->cl_tree,
- UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL)
- return (-1);
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
-
- boolean_t sharenfs;
- boolean_t sharesmb;
- boolean_t mounted;
- boolean_t needs_key;
-
- /*
- * If we are in the global zone, but this dataset is exported
- * to a local zone, do nothing.
- */
- if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
- continue;
-
- /* Only do post-processing if it's required */
- if (!cn->cn_needpost)
- continue;
- cn->cn_needpost = B_FALSE;
-
- zfs_refresh_properties(cn->cn_handle);
-
- if (ZFS_IS_VOLUME(cn->cn_handle))
- continue;
-
- /*
- * Remount if previously mounted or mountpoint was legacy,
- * or sharenfs or sharesmb property is set.
- */
- sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
- shareopts, sizeof (shareopts), NULL, NULL, 0,
- B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
-
- sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB,
- shareopts, sizeof (shareopts), NULL, NULL, 0,
- B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
-
- needs_key = (zfs_prop_get_int(cn->cn_handle,
- ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE);
-
- mounted = zfs_is_mounted(cn->cn_handle, NULL);
-
- if (!mounted && !needs_key && (cn->cn_mounted ||
- (((clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
- clp->cl_prop == clp->cl_realprop) ||
- sharenfs || sharesmb || clp->cl_waslegacy) &&
- (zfs_prop_get_int(cn->cn_handle,
- ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_ON)))) {
-
- if (zfs_mount(cn->cn_handle, NULL, 0) == 0)
- mounted = TRUE;
- }
-
- /*
- * If the file system is mounted we always re-share even
- * if the filesystem is currently shared, so that we can
- * adopt any new options.
- */
- const enum sa_protocol nfs[] =
- {SA_PROTOCOL_NFS, SA_NO_PROTOCOL};
- if (sharenfs && mounted) {
- zfs_share(cn->cn_handle, nfs);
- commit_nfs_shares = B_TRUE;
- } else if (cn->cn_shared || clp->cl_waslegacy) {
- zfs_unshare(cn->cn_handle, NULL, nfs);
- commit_nfs_shares = B_TRUE;
- }
- const enum sa_protocol smb[] =
- {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
- if (sharesmb && mounted) {
- zfs_share(cn->cn_handle, smb);
- commit_smb_shares = B_TRUE;
- } else if (cn->cn_shared || clp->cl_waslegacy) {
- zfs_unshare(cn->cn_handle, NULL, smb);
- commit_smb_shares = B_TRUE;
- }
- }
-
- enum sa_protocol proto[SA_PROTOCOL_COUNT + 1], *p = proto;
- if (commit_nfs_shares)
- *p++ = SA_PROTOCOL_NFS;
- if (commit_smb_shares)
- *p++ = SA_PROTOCOL_SMB;
- *p++ = SA_NO_PROTOCOL;
- zfs_commit_shares(proto);
- uu_avl_walk_end(walk);
-
- return (0);
-}
-
-/*
- * Is this "dataset" a child of "parent"?
- */
-static boolean_t
-isa_child_of(const char *dataset, const char *parent)
-{
- int len;
-
- len = strlen(parent);
-
- if (strncmp(dataset, parent, len) == 0 &&
- (dataset[len] == '@' || dataset[len] == '/' ||
- dataset[len] == '\0'))
- return (B_TRUE);
- else
- return (B_FALSE);
-
-}
-
-/*
- * If we rename a filesystem, child filesystem handles are no longer valid
- * since we identify each dataset by its name in the ZFS namespace. As a
- * result, we have to go through and fix up all the names appropriately. We
- * could do this automatically if libzfs kept track of all open handles, but
- * this is a lot less work.
- */
-void
-changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
-{
- prop_changenode_t *cn;
- uu_avl_walk_t *walk;
- char newname[ZFS_MAX_DATASET_NAME_LEN];
-
- if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
- return;
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
- /*
- * Do not rename a clone that's not in the source hierarchy.
- */
- if (!isa_child_of(cn->cn_handle->zfs_name, src))
- continue;
-
- /*
- * Destroy the previous mountpoint if needed.
- */
- remove_mountpoint(cn->cn_handle);
-
- (void) strlcpy(newname, dst, sizeof (newname));
- (void) strlcat(newname, cn->cn_handle->zfs_name + strlen(src),
- sizeof (newname));
-
- (void) strlcpy(cn->cn_handle->zfs_name, newname,
- sizeof (cn->cn_handle->zfs_name));
- }
-
- uu_avl_walk_end(walk);
-}
-
-/*
- * Given a gathered changelist for the 'sharenfs' or 'sharesmb' property,
- * unshare all the datasets in the list.
- */
-int
-changelist_unshare(prop_changelist_t *clp, const enum sa_protocol *proto)
-{
- prop_changenode_t *cn;
- uu_avl_walk_t *walk;
- int ret = 0;
-
- if (clp->cl_prop != ZFS_PROP_SHARENFS &&
- clp->cl_prop != ZFS_PROP_SHARESMB)
- return (0);
-
- if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
- return (-1);
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
- if (zfs_unshare(cn->cn_handle, NULL, proto) != 0)
- ret = -1;
- }
-
- for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
- sa_commit_shares(*p);
- uu_avl_walk_end(walk);
-
- return (ret);
-}
-
-/*
- * Check if there is any child exported to a local zone in a given changelist.
- * This information has already been recorded while gathering the changelist
- * via changelist_gather().
- */
-int
-changelist_haszonedchild(prop_changelist_t *clp)
-{
- return (clp->cl_haszonedchild);
-}
-
-/*
- * Remove a node from a gathered list.
- */
-void
-changelist_remove(prop_changelist_t *clp, const char *name)
-{
- prop_changenode_t *cn;
- uu_avl_walk_t *walk;
-
- if ((walk = uu_avl_walk_start(clp->cl_tree, UU_WALK_ROBUST)) == NULL)
- return;
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
- if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
- uu_avl_remove(clp->cl_tree, cn);
- zfs_close(cn->cn_handle);
- free(cn);
- uu_avl_walk_end(walk);
- return;
- }
- }
-
- uu_avl_walk_end(walk);
-}
-
-/*
- * Release any memory associated with a changelist.
- */
-void
-changelist_free(prop_changelist_t *clp)
-{
- prop_changenode_t *cn;
-
- if (clp->cl_tree) {
- uu_avl_walk_t *walk;
-
- if ((walk = uu_avl_walk_start(clp->cl_tree,
- UU_WALK_ROBUST)) == NULL)
- return;
-
- while ((cn = uu_avl_walk_next(walk)) != NULL) {
- uu_avl_remove(clp->cl_tree, cn);
- zfs_close(cn->cn_handle);
- free(cn);
- }
-
- uu_avl_walk_end(walk);
- uu_avl_destroy(clp->cl_tree);
- }
- if (clp->cl_pool)
- uu_avl_pool_destroy(clp->cl_pool);
-
- free(clp);
-}
-
-/*
- * Add one dataset to changelist
- */
-static int
-changelist_add_mounted(zfs_handle_t *zhp, void *data)
-{
- prop_changelist_t *clp = data;
- prop_changenode_t *cn;
- uu_avl_index_t idx;
-
- ASSERT3U(clp->cl_prop, ==, ZFS_PROP_MOUNTPOINT);
-
- cn = zfs_alloc(zfs_get_handle(zhp), sizeof (prop_changenode_t));
- cn->cn_handle = zhp;
- cn->cn_mounted = zfs_is_mounted(zhp, NULL);
- ASSERT3U(cn->cn_mounted, ==, B_TRUE);
- cn->cn_shared = zfs_is_shared(zhp, NULL, NULL);
- cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
- cn->cn_needpost = B_TRUE;
-
- /* Indicate if any child is exported to a local zone. */
- if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
- clp->cl_haszonedchild = B_TRUE;
-
- uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
-
- if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
- uu_avl_insert(clp->cl_tree, cn, idx);
- } else {
- free(cn);
- zfs_close(zhp);
- }
-
- return (0);
-}
-
-static int
-change_one(zfs_handle_t *zhp, void *data)
-{
- prop_changelist_t *clp = data;
- char property[ZFS_MAXPROPLEN];
- char where[64];
- prop_changenode_t *cn = NULL;
- zprop_source_t sourcetype = ZPROP_SRC_NONE;
- zprop_source_t share_sourcetype = ZPROP_SRC_NONE;
- int ret = 0;
-
- /*
- * We only want to unmount/unshare those filesystems that may inherit
- * from the target filesystem. If we find any filesystem with a
- * locally set mountpoint, we ignore any children since changing the
- * property will not affect them. If this is a rename, we iterate
- * over all children regardless, since we need them unmounted in
- * order to do the rename. Also, if this is a volume and we're doing
- * a rename, then always add it to the changelist.
- */
-
- if (!(ZFS_IS_VOLUME(zhp) && clp->cl_realprop == ZFS_PROP_NAME) &&
- zfs_prop_get(zhp, clp->cl_prop, property,
- sizeof (property), &sourcetype, where, sizeof (where),
- B_FALSE) != 0) {
- goto out;
- }
-
- /*
- * If we are "watching" sharenfs or sharesmb
- * then check out the companion property which is tracked
- * in cl_shareprop
- */
- if (clp->cl_shareprop != ZPROP_INVAL &&
- zfs_prop_get(zhp, clp->cl_shareprop, property,
- sizeof (property), &share_sourcetype, where, sizeof (where),
- B_FALSE) != 0) {
- goto out;
- }
-
- if (clp->cl_alldependents || clp->cl_allchildren ||
- sourcetype == ZPROP_SRC_DEFAULT ||
- sourcetype == ZPROP_SRC_INHERITED ||
- (clp->cl_shareprop != ZPROP_INVAL &&
- (share_sourcetype == ZPROP_SRC_DEFAULT ||
- share_sourcetype == ZPROP_SRC_INHERITED))) {
- cn = zfs_alloc(zfs_get_handle(zhp), sizeof (prop_changenode_t));
- cn->cn_handle = zhp;
- cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
- zfs_is_mounted(zhp, NULL);
- cn->cn_shared = zfs_is_shared(zhp, NULL, NULL);
- cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
- cn->cn_needpost = B_TRUE;
-
- /* Indicate if any child is exported to a local zone. */
- if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
- clp->cl_haszonedchild = B_TRUE;
-
- uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
-
- uu_avl_index_t idx;
-
- if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
- uu_avl_insert(clp->cl_tree, cn, idx);
- } else {
- free(cn);
- cn = NULL;
- }
-
- if (!clp->cl_alldependents) {
- if (clp->cl_prop != ZFS_PROP_MOUNTPOINT) {
- ret = zfs_iter_filesystems_v2(zhp, 0,
- change_one, data);
- } else {
- ret = zfs_iter_children_v2(zhp, 0, change_one,
- data);
- }
- }
-
- /*
- * If we added the handle to the changelist, we will re-use it
- * later so return without closing it.
- */
- if (cn != NULL)
- return (ret);
- }
-
-out:
- zfs_close(zhp);
- return (ret);
-}
-
-static int
-compare_props(const void *a, const void *b, zfs_prop_t prop)
-{
- const prop_changenode_t *ca = a;
- const prop_changenode_t *cb = b;
-
- char propa[MAXPATHLEN];
- char propb[MAXPATHLEN];
-
- boolean_t haspropa, haspropb;
-
- haspropa = (zfs_prop_get(ca->cn_handle, prop, propa, sizeof (propa),
- NULL, NULL, 0, B_FALSE) == 0);
- haspropb = (zfs_prop_get(cb->cn_handle, prop, propb, sizeof (propb),
- NULL, NULL, 0, B_FALSE) == 0);
-
- if (!haspropa && haspropb)
- return (-1);
- else if (haspropa && !haspropb)
- return (1);
- else if (!haspropa && !haspropb)
- return (0);
- else
- return (strcmp(propb, propa));
-}
-
-static int
-compare_mountpoints(const void *a, const void *b, void *unused)
-{
- /*
- * When unsharing or unmounting filesystems, we need to do it in
- * mountpoint order. This allows the user to have a mountpoint
- * hierarchy that is different from the dataset hierarchy, and still
- * allow it to be changed.
- */
- (void) unused;
- return (compare_props(a, b, ZFS_PROP_MOUNTPOINT));
-}
-
-static int
-compare_dataset_names(const void *a, const void *b, void *unused)
-{
- (void) unused;
- return (compare_props(a, b, ZFS_PROP_NAME));
-}
-
-/*
- * Given a ZFS handle and a property, construct a complete list of datasets
- * that need to be modified as part of this process. For anything but the
- * 'mountpoint' and 'sharenfs' properties, this just returns an empty list.
- * Otherwise, we iterate over all children and look for any datasets that
- * inherit the property. For each such dataset, we add it to the list and
- * mark whether it was shared beforehand.
- */
-prop_changelist_t *
-changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
- int mnt_flags)
-{
- prop_changelist_t *clp;
- prop_changenode_t *cn;
- zfs_handle_t *temp;
- char property[ZFS_MAXPROPLEN];
- boolean_t legacy = B_FALSE;
-
- clp = zfs_alloc(zhp->zfs_hdl, sizeof (prop_changelist_t));
-
- /*
- * For mountpoint-related tasks, we want to sort everything by
- * mountpoint, so that we mount and unmount them in the appropriate
- * order, regardless of their position in the hierarchy.
- */
- if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
- prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
- prop == ZFS_PROP_SHARESMB) {
-
- if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
- property, sizeof (property),
- NULL, NULL, 0, B_FALSE) == 0 &&
- (strcmp(property, "legacy") == 0 ||
- strcmp(property, "none") == 0)) {
- legacy = B_TRUE;
- }
- }
-
- clp->cl_pool = uu_avl_pool_create("changelist_pool",
- sizeof (prop_changenode_t),
- offsetof(prop_changenode_t, cn_treenode),
- legacy ? compare_dataset_names : compare_mountpoints, 0);
- if (clp->cl_pool == NULL) {
- assert(uu_error() == UU_ERROR_NO_MEMORY);
- (void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
- changelist_free(clp);
- return (NULL);
- }
-
- clp->cl_tree = uu_avl_create(clp->cl_pool, NULL, UU_DEFAULT);
- clp->cl_gflags = gather_flags;
- clp->cl_mflags = mnt_flags;
-
- if (clp->cl_tree == NULL) {
- assert(uu_error() == UU_ERROR_NO_MEMORY);
- (void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error");
- changelist_free(clp);
- return (NULL);
- }
-
- /*
- * If this is a rename or the 'zoned' property, we pretend we're
- * changing the mountpoint and flag it so we can catch all children in
- * change_one().
- *
- * Flag cl_alldependents to catch all children plus the dependents
- * (clones) that are not in the hierarchy.
- */
- if (prop == ZFS_PROP_NAME) {
- clp->cl_prop = ZFS_PROP_MOUNTPOINT;
- clp->cl_alldependents = B_TRUE;
- } else if (prop == ZFS_PROP_ZONED) {
- clp->cl_prop = ZFS_PROP_MOUNTPOINT;
- clp->cl_allchildren = B_TRUE;
- } else if (prop == ZFS_PROP_CANMOUNT) {
- clp->cl_prop = ZFS_PROP_MOUNTPOINT;
- } else if (prop == ZFS_PROP_VOLSIZE) {
- clp->cl_prop = ZFS_PROP_MOUNTPOINT;
- } else {
- clp->cl_prop = prop;
- }
- clp->cl_realprop = prop;
-
- if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
- clp->cl_prop != ZFS_PROP_SHARENFS &&
- clp->cl_prop != ZFS_PROP_SHARESMB)
- return (clp);
-
- /*
- * If watching SHARENFS or SHARESMB then
- * also watch its companion property.
- */
- if (clp->cl_prop == ZFS_PROP_SHARENFS)
- clp->cl_shareprop = ZFS_PROP_SHARESMB;
- else if (clp->cl_prop == ZFS_PROP_SHARESMB)
- clp->cl_shareprop = ZFS_PROP_SHARENFS;
-
- if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
- (clp->cl_gflags & CL_GATHER_ITER_MOUNTED)) {
- /*
- * Instead of iterating through all of the dataset children we
- * gather mounted dataset children from MNTTAB
- */
- if (zfs_iter_mounted(zhp, changelist_add_mounted, clp) != 0) {
- changelist_free(clp);
- return (NULL);
- }
- } else if (clp->cl_alldependents) {
- if (zfs_iter_dependents_v2(zhp, 0, B_TRUE, change_one,
- clp) != 0) {
- changelist_free(clp);
- return (NULL);
- }
- } else if (clp->cl_prop != ZFS_PROP_MOUNTPOINT) {
- if (zfs_iter_filesystems_v2(zhp, 0, change_one, clp) != 0) {
- changelist_free(clp);
- return (NULL);
- }
- } else if (zfs_iter_children_v2(zhp, 0, change_one, clp) != 0) {
- changelist_free(clp);
- return (NULL);
- }
-
- /*
- * We have to re-open ourselves because we auto-close all the handles
- * and can't tell the difference.
- */
- if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp),
- ZFS_TYPE_DATASET)) == NULL) {
- changelist_free(clp);
- return (NULL);
- }
-
- /*
- * Always add ourself to the list. We add ourselves to the end so that
- * we're the last to be unmounted.
- */
- cn = zfs_alloc(zhp->zfs_hdl, sizeof (prop_changenode_t));
- cn->cn_handle = temp;
- cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
- zfs_is_mounted(temp, NULL);
- cn->cn_shared = zfs_is_shared(temp, NULL, NULL);
- cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
- cn->cn_needpost = B_TRUE;
-
- uu_avl_node_init(cn, &cn->cn_treenode, clp->cl_pool);
- uu_avl_index_t idx;
- if (uu_avl_find(clp->cl_tree, cn, NULL, &idx) == NULL) {
- uu_avl_insert(clp->cl_tree, cn, idx);
- } else {
- free(cn);
- zfs_close(temp);
- }
-
- /*
- * If the mountpoint property was previously 'legacy', or 'none',
- * record it as the behavior of changelist_postfix() will be different.
- */
- if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) && legacy) {
- /*
- * do not automatically mount ex-legacy datasets if
- * we specifically set canmount to noauto
- */
- if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) !=
- ZFS_CANMOUNT_NOAUTO)
- clp->cl_waslegacy = B_TRUE;
- }
-
- return (clp);
-}
diff --git a/lib/libzfs/libzfs_config.c b/lib/libzfs/libzfs_config.c
deleted file mode 100644
index 9d704e4303ff..000000000000
--- a/lib/libzfs/libzfs_config.c
+++ /dev/null
@@ -1,455 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * Copyright (c) 2012 by Delphix. All rights reserved.
- * Copyright (c) 2015 by Syneto S.R.L. All rights reserved.
- * Copyright 2016 Nexenta Systems, Inc.
- */
-
-/*
- * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
- * single packed nvlist. While it would be nice to just read in this
- * file from userland, this wouldn't work from a local zone. So we have to have
- * a zpool ioctl to return the complete configuration for all pools. In the
- * global zone, this will be identical to reading the file and unpacking it in
- * userland.
- */
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <libintl.h>
-#include <libuutil.h>
-
-#include "libzfs_impl.h"
-
-typedef struct config_node {
- char *cn_name;
- nvlist_t *cn_config;
- uu_avl_node_t cn_avl;
-} config_node_t;
-
-static int
-config_node_compare(const void *a, const void *b, void *unused)
-{
- (void) unused;
- const config_node_t *ca = (config_node_t *)a;
- const config_node_t *cb = (config_node_t *)b;
-
- int ret = strcmp(ca->cn_name, cb->cn_name);
-
- if (ret < 0)
- return (-1);
- else if (ret > 0)
- return (1);
- else
- return (0);
-}
-
-void
-namespace_clear(libzfs_handle_t *hdl)
-{
- if (hdl->libzfs_ns_avl) {
- config_node_t *cn;
- void *cookie = NULL;
-
- while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
- &cookie)) != NULL) {
- nvlist_free(cn->cn_config);
- free(cn->cn_name);
- free(cn);
- }
-
- uu_avl_destroy(hdl->libzfs_ns_avl);
- hdl->libzfs_ns_avl = NULL;
- }
-
- if (hdl->libzfs_ns_avlpool) {
- uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
- hdl->libzfs_ns_avlpool = NULL;
- }
-}
-
-/*
- * Loads the pool namespace, or re-loads it if the cache has changed.
- */
-static int
-namespace_reload(libzfs_handle_t *hdl)
-{
- nvlist_t *config;
- config_node_t *cn;
- nvpair_t *elem;
- zfs_cmd_t zc = {"\0"};
- void *cookie;
-
- if (hdl->libzfs_ns_gen == 0) {
- /*
- * This is the first time we've accessed the configuration
- * cache. Initialize the AVL tree and then fall through to the
- * common code.
- */
- if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
- sizeof (config_node_t),
- offsetof(config_node_t, cn_avl),
- config_node_compare, UU_DEFAULT)) == NULL)
- return (no_memory(hdl));
-
- if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
- NULL, UU_DEFAULT)) == NULL)
- return (no_memory(hdl));
- }
-
- zcmd_alloc_dst_nvlist(hdl, &zc, 0);
-
- for (;;) {
- zc.zc_cookie = hdl->libzfs_ns_gen;
- if (zfs_ioctl(hdl, ZFS_IOC_POOL_CONFIGS, &zc) != 0) {
- switch (errno) {
- case EEXIST:
- /*
- * The namespace hasn't changed.
- */
- zcmd_free_nvlists(&zc);
- return (0);
-
- case ENOMEM:
- zcmd_expand_dst_nvlist(hdl, &zc);
- break;
-
- default:
- zcmd_free_nvlists(&zc);
- return (zfs_standard_error(hdl, errno,
- dgettext(TEXT_DOMAIN, "failed to read "
- "pool configuration")));
- }
- } else {
- hdl->libzfs_ns_gen = zc.zc_cookie;
- break;
- }
- }
-
- if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
-
- zcmd_free_nvlists(&zc);
-
- /*
- * Clear out any existing configuration information.
- */
- cookie = NULL;
- while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) {
- nvlist_free(cn->cn_config);
- free(cn->cn_name);
- free(cn);
- }
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
- nvlist_t *child;
- uu_avl_index_t where;
-
- cn = zfs_alloc(hdl, sizeof (config_node_t));
- cn->cn_name = zfs_strdup(hdl, nvpair_name(elem));
- child = fnvpair_value_nvlist(elem);
- if (nvlist_dup(child, &cn->cn_config, 0) != 0) {
- free(cn->cn_name);
- free(cn);
- nvlist_free(config);
- return (no_memory(hdl));
- }
- verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
- == NULL);
-
- uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
- }
-
- nvlist_free(config);
- return (0);
-}
-
-/*
- * Retrieve the configuration for the given pool. The configuration is an nvlist
- * describing the vdevs, as well as the statistics associated with each one.
- */
-nvlist_t *
-zpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig)
-{
- if (oldconfig)
- *oldconfig = zhp->zpool_old_config;
- return (zhp->zpool_config);
-}
-
-/*
- * Retrieves a list of enabled features and their refcounts and caches it in
- * the pool handle.
- */
-nvlist_t *
-zpool_get_features(zpool_handle_t *zhp)
-{
- nvlist_t *config, *features;
-
- config = zpool_get_config(zhp, NULL);
-
- if (config == NULL || !nvlist_exists(config,
- ZPOOL_CONFIG_FEATURE_STATS)) {
- int error;
- boolean_t missing = B_FALSE;
-
- error = zpool_refresh_stats(zhp, &missing);
-
- if (error != 0 || missing)
- return (NULL);
-
- config = zpool_get_config(zhp, NULL);
- }
-
- if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
- &features) != 0)
- return (NULL);
-
- return (features);
-}
-
-/*
- * Refresh the vdev statistics associated with the given pool. This is used in
- * iostat to show configuration changes and determine the delta from the last
- * time the function was called. This function can fail, in case the pool has
- * been destroyed.
- */
-int
-zpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing)
-{
- zfs_cmd_t zc = {"\0"};
- int error;
- nvlist_t *config;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- *missing = B_FALSE;
- (void) strcpy(zc.zc_name, zhp->zpool_name);
-
- if (zhp->zpool_config_size == 0)
- zhp->zpool_config_size = 1 << 16;
-
- zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size);
-
- for (;;) {
- if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_STATS,
- &zc) == 0) {
- /*
- * The real error is returned in the zc_cookie field.
- */
- error = zc.zc_cookie;
- break;
- }
-
- if (errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
- else {
- zcmd_free_nvlists(&zc);
- if (errno == ENOENT || errno == EINVAL)
- *missing = B_TRUE;
- zhp->zpool_state = POOL_STATE_UNAVAIL;
- return (0);
- }
- }
-
- if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
-
- zcmd_free_nvlists(&zc);
-
- zhp->zpool_config_size = zc.zc_nvlist_dst_size;
-
- if (zhp->zpool_config != NULL) {
- nvlist_free(zhp->zpool_old_config);
-
- zhp->zpool_old_config = zhp->zpool_config;
- }
-
- zhp->zpool_config = config;
- if (error)
- zhp->zpool_state = POOL_STATE_UNAVAIL;
- else
- zhp->zpool_state = POOL_STATE_ACTIVE;
-
- return (0);
-}
-
-/*
- * Copies the pool config and state from szhp to dzhp. szhp and dzhp must
- * represent the same pool. Used by pool_list_refresh() to avoid another
- * round-trip into the kernel to get stats already collected earlier in the
- * function.
- */
-void
-zpool_refresh_stats_from_handle(zpool_handle_t *dzhp, zpool_handle_t *szhp)
-{
- VERIFY0(strcmp(dzhp->zpool_name, szhp->zpool_name));
- nvlist_free(dzhp->zpool_old_config);
- dzhp->zpool_old_config = dzhp->zpool_config;
- dzhp->zpool_config = fnvlist_dup(szhp->zpool_config);
- dzhp->zpool_config_size = szhp->zpool_config_size;
- dzhp->zpool_state = szhp->zpool_state;
-}
-
-/*
- * The following environment variables are undocumented
- * and should be used for testing purposes only:
- *
- * __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists
- * __ZFS_POOL_RESTRICT - iterate only over the pools it lists
- *
- * This function returns B_TRUE if the pool should be skipped
- * during iteration.
- */
-boolean_t
-zpool_skip_pool(const char *poolname)
-{
- static boolean_t initialized = B_FALSE;
- static const char *exclude = NULL;
- static const char *restricted = NULL;
-
- const char *cur, *end;
- int len;
- int namelen = strlen(poolname);
-
- if (!initialized) {
- initialized = B_TRUE;
- exclude = getenv("__ZFS_POOL_EXCLUDE");
- restricted = getenv("__ZFS_POOL_RESTRICT");
- }
-
- if (exclude != NULL) {
- cur = exclude;
- do {
- end = strchr(cur, ' ');
- len = (NULL == end) ? strlen(cur) : (end - cur);
- if (len == namelen && 0 == strncmp(cur, poolname, len))
- return (B_TRUE);
- cur += (len + 1);
- } while (NULL != end);
- }
-
- if (NULL == restricted)
- return (B_FALSE);
-
- cur = restricted;
- do {
- end = strchr(cur, ' ');
- len = (NULL == end) ? strlen(cur) : (end - cur);
-
- if (len == namelen && 0 == strncmp(cur, poolname, len)) {
- return (B_FALSE);
- }
-
- cur += (len + 1);
- } while (NULL != end);
-
- return (B_TRUE);
-}
-
-/*
- * Iterate over all pools in the system.
- */
-int
-zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
-{
- config_node_t *cn;
- zpool_handle_t *zhp;
- int ret;
-
- /*
- * If someone makes a recursive call to zpool_iter(), we want to avoid
- * refreshing the namespace because that will invalidate the parent
- * context. We allow recursive calls, but simply re-use the same
- * namespace AVL tree.
- */
- if (!hdl->libzfs_pool_iter && namespace_reload(hdl) != 0)
- return (-1);
-
- hdl->libzfs_pool_iter++;
- for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
- cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
-
- if (zpool_skip_pool(cn->cn_name))
- continue;
-
- if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) {
- hdl->libzfs_pool_iter--;
- return (-1);
- }
-
- if (zhp == NULL)
- continue;
-
- if ((ret = func(zhp, data)) != 0) {
- hdl->libzfs_pool_iter--;
- return (ret);
- }
- }
- hdl->libzfs_pool_iter--;
-
- return (0);
-}
-
-/*
- * Iterate over root datasets, calling the given function for each. The zfs
- * handle passed each time must be explicitly closed by the callback.
- */
-int
-zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
-{
- config_node_t *cn;
- zfs_handle_t *zhp;
- int ret;
-
- if (namespace_reload(hdl) != 0)
- return (-1);
-
- for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
- cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
-
- if (zpool_skip_pool(cn->cn_name))
- continue;
-
- if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL)
- continue;
-
- if ((ret = func(zhp, data)) != 0)
- return (ret);
- }
-
- return (0);
-}
diff --git a/lib/libzfs/libzfs_crypto.c b/lib/libzfs/libzfs_crypto.c
deleted file mode 100644
index b34a44c30eb4..000000000000
--- a/lib/libzfs/libzfs_crypto.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * 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
- */
-
-/*
- * Copyright (c) 2017, Datto, Inc. All rights reserved.
- * Copyright 2020 Joyent, Inc.
- */
-
-#include <sys/zfs_context.h>
-#include <sys/fs/zfs.h>
-#include <sys/dsl_crypt.h>
-#include <libintl.h>
-#include <termios.h>
-#include <signal.h>
-#include <errno.h>
-#include <openssl/evp.h>
-#if LIBFETCH_DYNAMIC
-#include <dlfcn.h>
-#endif
-#if LIBFETCH_IS_FETCH
-#include <sys/param.h>
-#include <stdio.h>
-#include <fetch.h>
-#elif LIBFETCH_IS_LIBCURL
-#include <curl/curl.h>
-#endif
-#include <libzfs.h>
-#include <libzutil.h>
-#include "libzfs_impl.h"
-#include "zfeature_common.h"
-
-/*
- * User keys are used to decrypt the master encryption keys of a dataset. This
- * indirection allows a user to change his / her access key without having to
- * re-encrypt the entire dataset. User keys can be provided in one of several
- * ways. Raw keys are simply given to the kernel as is. Similarly, hex keys
- * are converted to binary and passed into the kernel. Password based keys are
- * a bit more complicated. Passwords alone do not provide suitable entropy for
- * encryption and may be too short or too long to be used. In order to derive
- * a more appropriate key we use a PBKDF2 function. This function is designed
- * to take a (relatively) long time to calculate in order to discourage
- * attackers from guessing from a list of common passwords. PBKDF2 requires
- * 2 additional parameters. The first is the number of iterations to run, which
- * will ultimately determine how long it takes to derive the resulting key from
- * the password. The second parameter is a salt that is randomly generated for
- * each dataset. The salt is used to "tweak" PBKDF2 such that a group of
- * attackers cannot reasonably generate a table of commonly known passwords to
- * their output keys and expect it work for all past and future PBKDF2 users.
- * We store the salt as a hidden property of the dataset (although it is
- * technically ok if the salt is known to the attacker).
- */
-
-#define MIN_PASSPHRASE_LEN 8
-#define MAX_PASSPHRASE_LEN 512
-#define MAX_KEY_PROMPT_ATTEMPTS 3
-
-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 }
-};
-
-static int
-pkcs11_get_urandom(uint8_t *buf, size_t bytes)
-{
- int rand;
- ssize_t bytes_read = 0;
-
- rand = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
-
- if (rand < 0)
- return (rand);
-
- while (bytes_read < bytes) {
- ssize_t rc = read(rand, buf + bytes_read, bytes - bytes_read);
- if (rc < 0)
- break;
- bytes_read += rc;
- }
-
- (void) close(rand);
-
- return (bytes_read);
-}
-
-static int
-zfs_prop_parse_keylocation(libzfs_handle_t *restrict hdl, const char *str,
- zfs_keylocation_t *restrict locp, char **restrict schemep)
-{
- *locp = ZFS_KEYLOCATION_NONE;
- *schemep = NULL;
-
- if (strcmp("prompt", str) == 0) {
- *locp = ZFS_KEYLOCATION_PROMPT;
- return (0);
- }
-
- regmatch_t pmatch[2];
-
- if (regexec(&hdl->libzfs_urire, str, ARRAY_SIZE(pmatch),
- pmatch, 0) == 0) {
- size_t scheme_len;
-
- if (pmatch[1].rm_so == -1) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid URI"));
- return (EINVAL);
- }
-
- scheme_len = pmatch[1].rm_eo - pmatch[1].rm_so;
-
- *schemep = calloc(1, scheme_len + 1);
- if (*schemep == NULL) {
- int ret = errno;
-
- errno = 0;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid URI"));
- return (ret);
- }
-
- (void) memcpy(*schemep, str + pmatch[1].rm_so, scheme_len);
- *locp = ZFS_KEYLOCATION_URI;
- return (0);
- }
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Invalid keylocation"));
- return (EINVAL);
-}
-
-static int
-hex_key_to_raw(char *hex, int hexlen, uint8_t *out)
-{
- int ret, i;
- unsigned int c;
-
- for (i = 0; i < hexlen; i += 2) {
- if (!isxdigit(hex[i]) || !isxdigit(hex[i + 1])) {
- ret = EINVAL;
- goto error;
- }
-
- ret = sscanf(&hex[i], "%02x", &c);
- if (ret != 1) {
- ret = EINVAL;
- goto error;
- }
-
- out[i / 2] = c;
- }
-
- return (0);
-
-error:
- return (ret);
-}
-
-
-static void
-catch_signal(int sig)
-{
- caught_interrupt = sig;
-}
-
-static const char *
-get_format_prompt_string(zfs_keyformat_t format)
-{
- switch (format) {
- case ZFS_KEYFORMAT_RAW:
- return ("raw key");
- case ZFS_KEYFORMAT_HEX:
- return ("hex key");
- case ZFS_KEYFORMAT_PASSPHRASE:
- return ("passphrase");
- default:
- /* shouldn't happen */
- return (NULL);
- }
-}
-
-/* do basic validation of the key material */
-static int
-validate_key(libzfs_handle_t *hdl, zfs_keyformat_t keyformat,
- const char *key, size_t keylen, boolean_t do_verify)
-{
- switch (keyformat) {
- case ZFS_KEYFORMAT_RAW:
- /* verify the key length is correct */
- if (keylen < WRAPPING_KEY_LEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Raw key too short (expected %u)."),
- WRAPPING_KEY_LEN);
- return (EINVAL);
- }
-
- if (keylen > WRAPPING_KEY_LEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Raw key too long (expected %u)."),
- WRAPPING_KEY_LEN);
- return (EINVAL);
- }
- break;
- case ZFS_KEYFORMAT_HEX:
- /* verify the key length is correct */
- if (keylen < WRAPPING_KEY_LEN * 2) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Hex key too short (expected %u)."),
- WRAPPING_KEY_LEN * 2);
- return (EINVAL);
- }
-
- if (keylen > WRAPPING_KEY_LEN * 2) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Hex key too long (expected %u)."),
- WRAPPING_KEY_LEN * 2);
- return (EINVAL);
- }
-
- /* check for invalid hex digits */
- for (size_t i = 0; i < WRAPPING_KEY_LEN * 2; i++) {
- if (!isxdigit(key[i])) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid hex character detected."));
- return (EINVAL);
- }
- }
- break;
- case ZFS_KEYFORMAT_PASSPHRASE:
- /*
- * Verify the length is within bounds when setting a new key,
- * but not when loading an existing key.
- */
- if (!do_verify)
- break;
- if (keylen > MAX_PASSPHRASE_LEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Passphrase too long (max %u)."),
- MAX_PASSPHRASE_LEN);
- return (EINVAL);
- }
-
- if (keylen < MIN_PASSPHRASE_LEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Passphrase too short (min %u)."),
- MIN_PASSPHRASE_LEN);
- return (EINVAL);
- }
- break;
- default:
- /* can't happen, checked above */
- break;
- }
-
- return (0);
-}
-
-static int
-libzfs_getpassphrase(zfs_keyformat_t keyformat, boolean_t is_reenter,
- boolean_t new_key, const char *fsname,
- char **restrict res, size_t *restrict reslen)
-{
- FILE *f = stdin;
- size_t buflen = 0;
- ssize_t bytes;
- int ret = 0;
- struct termios old_term, new_term;
- struct sigaction act, osigint, osigtstp;
-
- *res = NULL;
- *reslen = 0;
-
- /*
- * handle SIGINT and ignore SIGSTP. This is necessary to
- * restore the state of the terminal.
- */
- caught_interrupt = 0;
- act.sa_flags = 0;
- (void) sigemptyset(&act.sa_mask);
- act.sa_handler = catch_signal;
-
- (void) sigaction(SIGINT, &act, &osigint);
- act.sa_handler = SIG_IGN;
- (void) sigaction(SIGTSTP, &act, &osigtstp);
-
- (void) printf("%s %s%s",
- is_reenter ? "Re-enter" : "Enter",
- new_key ? "new " : "",
- get_format_prompt_string(keyformat));
- if (fsname != NULL)
- (void) printf(" for '%s'", fsname);
- (void) fputc(':', stdout);
- (void) fflush(stdout);
-
- /* disable the terminal echo for key input */
- (void) tcgetattr(fileno(f), &old_term);
-
- new_term = old_term;
- new_term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
-
- ret = tcsetattr(fileno(f), TCSAFLUSH, &new_term);
- if (ret != 0) {
- ret = errno;
- errno = 0;
- goto out;
- }
-
- bytes = getline(res, &buflen, f);
- if (bytes < 0) {
- ret = errno;
- errno = 0;
- goto out;
- }
-
- /* trim the ending newline if it exists */
- if (bytes > 0 && (*res)[bytes - 1] == '\n') {
- (*res)[bytes - 1] = '\0';
- bytes--;
- }
-
- *reslen = bytes;
-
-out:
- /* reset the terminal */
- (void) tcsetattr(fileno(f), TCSAFLUSH, &old_term);
- (void) sigaction(SIGINT, &osigint, NULL);
- (void) sigaction(SIGTSTP, &osigtstp, NULL);
-
- /* if we caught a signal, re-throw it now */
- if (caught_interrupt != 0)
- (void) kill(getpid(), caught_interrupt);
-
- /* print the newline that was not echo'd */
- (void) printf("\n");
-
- return (ret);
-}
-
-static int
-get_key_interactive(libzfs_handle_t *restrict hdl, const char *fsname,
- zfs_keyformat_t keyformat, boolean_t confirm_key, boolean_t newkey,
- uint8_t **restrict outbuf, size_t *restrict len_out)
-{
- char *buf = NULL, *buf2 = NULL;
- size_t buflen = 0, buf2len = 0;
- int ret = 0;
-
- ASSERT(isatty(fileno(stdin)));
-
- /* raw keys cannot be entered on the terminal */
- if (keyformat == ZFS_KEYFORMAT_RAW) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Cannot enter raw keys on the terminal"));
- goto out;
- }
-
- /* prompt for the key */
- if ((ret = libzfs_getpassphrase(keyformat, B_FALSE, newkey, fsname,
- &buf, &buflen)) != 0) {
- free(buf);
- buf = NULL;
- buflen = 0;
- goto out;
- }
-
- if (!confirm_key)
- goto out;
-
- if ((ret = validate_key(hdl, keyformat, buf, buflen, confirm_key)) !=
- 0) {
- free(buf);
- return (ret);
- }
-
- ret = libzfs_getpassphrase(keyformat, B_TRUE, newkey, fsname, &buf2,
- &buf2len);
- if (ret != 0) {
- free(buf);
- free(buf2);
- buf = buf2 = NULL;
- buflen = buf2len = 0;
- goto out;
- }
-
- if (buflen != buf2len || strcmp(buf, buf2) != 0) {
- free(buf);
- buf = NULL;
- buflen = 0;
-
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Provided keys do not match."));
- }
-
- free(buf2);
-
-out:
- *outbuf = (uint8_t *)buf;
- *len_out = buflen;
- return (ret);
-}
-
-static int
-get_key_material_raw(FILE *fd, zfs_keyformat_t keyformat,
- uint8_t **buf, size_t *len_out)
-{
- int ret = 0;
- size_t buflen = 0;
-
- *len_out = 0;
-
- /* read the key material */
- if (keyformat != ZFS_KEYFORMAT_RAW) {
- ssize_t bytes;
-
- bytes = getline((char **)buf, &buflen, fd);
- if (bytes < 0) {
- ret = errno;
- errno = 0;
- goto out;
- }
-
- /* trim the ending newline if it exists */
- if (bytes > 0 && (*buf)[bytes - 1] == '\n') {
- (*buf)[bytes - 1] = '\0';
- bytes--;
- }
-
- *len_out = bytes;
- } else {
- size_t n;
-
- /*
- * Raw keys may have newline characters in them and so can't
- * use getline(). Here we attempt to read 33 bytes so that we
- * can properly check the key length (the file should only have
- * 32 bytes).
- */
- *buf = malloc((WRAPPING_KEY_LEN + 1) * sizeof (uint8_t));
- if (*buf == NULL) {
- ret = ENOMEM;
- goto out;
- }
-
- n = fread(*buf, 1, WRAPPING_KEY_LEN + 1, fd);
- if (n == 0 || ferror(fd)) {
- /* size errors are handled by the calling function */
- free(*buf);
- *buf = NULL;
- ret = errno;
- errno = 0;
- goto out;
- }
-
- *len_out = n;
- }
-out:
- return (ret);
-}
-
-static int
-get_key_material_file(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)
-{
- (void) fsname, (void) newkey;
- FILE *f = NULL;
- int ret = 0;
-
- if (strlen(uri) < 7)
- return (EINVAL);
-
- if ((f = fopen(uri + 7, "re")) == NULL) {
- ret = errno;
- errno = 0;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to open key material file: %s"), zfs_strerror(ret));
- return (ret);
- }
-
- ret = get_key_material_raw(f, keyformat, buf, len_out);
-
- (void) fclose(f);
-
- 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)
-{
- (void) fsname, (void) newkey;
- 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;
-#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"),
- zfs_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, zfs_strerror(ret));
- free(path);
- goto end;
- }
- (void) unlink(path);
- free(path);
-
-kfdok:
- if ((key = fdopen(kfd, "r+")) == NULL) {
- ret = errno;
- (void) close(kfd);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Couldn't reopen temporary file: %s"), zfs_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
- * to B_TRUE if the user is providing the key material interactively, allowing
- * for re-entry attempts.
- */
-static int
-get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey,
- zfs_keyformat_t keyformat, const char *keylocation, const char *fsname,
- uint8_t **km_out, size_t *kmlen_out, boolean_t *can_retry_out)
-{
- int ret;
- zfs_keylocation_t keyloc = ZFS_KEYLOCATION_NONE;
- uint8_t *km = NULL;
- size_t kmlen = 0;
- char *uri_scheme = NULL;
- zfs_uri_handler_t *handler = NULL;
- boolean_t can_retry = B_FALSE;
-
- /* verify and parse the keylocation */
- ret = zfs_prop_parse_keylocation(hdl, keylocation, &keyloc,
- &uri_scheme);
- if (ret != 0)
- goto error;
-
- /* open the appropriate file descriptor */
- switch (keyloc) {
- case ZFS_KEYLOCATION_PROMPT:
- if (isatty(fileno(stdin))) {
- can_retry = keyformat != ZFS_KEYFORMAT_RAW;
- ret = get_key_interactive(hdl, fsname, keyformat,
- do_verify, newkey, &km, &kmlen);
- } else {
- /* fetch the key material into the buffer */
- ret = get_key_material_raw(stdin, keyformat, &km,
- &kmlen);
- }
-
- if (ret != 0)
- goto error;
-
- break;
- case ZFS_KEYLOCATION_URI:
- ret = ENOTSUP;
-
- for (handler = uri_handlers; handler->zuh_scheme != NULL;
- handler++) {
- if (strcmp(handler->zuh_scheme, uri_scheme) != 0)
- continue;
-
- if ((ret = handler->zuh_handler(hdl, keylocation,
- fsname, keyformat, newkey, &km, &kmlen)) != 0)
- goto error;
-
- break;
- }
-
- if (ret == ENOTSUP) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "URI scheme is not supported"));
- goto error;
- }
-
- break;
- default:
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid keylocation."));
- goto error;
- }
-
- if ((ret = validate_key(hdl, keyformat, (const char *)km, kmlen,
- do_verify)) != 0)
- goto error;
-
- *km_out = km;
- *kmlen_out = kmlen;
- if (can_retry_out != NULL)
- *can_retry_out = can_retry;
-
- free(uri_scheme);
- return (0);
-
-error:
- free(km);
-
- *km_out = NULL;
- *kmlen_out = 0;
-
- if (can_retry_out != NULL)
- *can_retry_out = can_retry;
-
- free(uri_scheme);
- return (ret);
-}
-
-static int
-derive_key(libzfs_handle_t *hdl, zfs_keyformat_t format, uint64_t iters,
- uint8_t *key_material, uint64_t salt,
- uint8_t **key_out)
-{
- int ret;
- uint8_t *key;
-
- *key_out = NULL;
-
- key = zfs_alloc(hdl, WRAPPING_KEY_LEN);
-
- switch (format) {
- case ZFS_KEYFORMAT_RAW:
- memcpy(key, key_material, WRAPPING_KEY_LEN);
- break;
- case ZFS_KEYFORMAT_HEX:
- ret = hex_key_to_raw((char *)key_material,
- WRAPPING_KEY_LEN * 2, key);
- if (ret != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid hex key provided."));
- goto error;
- }
- break;
- case ZFS_KEYFORMAT_PASSPHRASE:
- salt = LE_64(salt);
-
- ret = PKCS5_PBKDF2_HMAC_SHA1((char *)key_material,
- strlen((char *)key_material), ((uint8_t *)&salt),
- sizeof (uint64_t), iters, WRAPPING_KEY_LEN, key);
- if (ret != 1) {
- ret = EIO;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to generate key from passphrase."));
- goto error;
- }
- break;
- default:
- ret = EINVAL;
- goto error;
- }
-
- *key_out = key;
- return (0);
-
-error:
- free(key);
-
- *key_out = NULL;
- return (ret);
-}
-
-static boolean_t
-encryption_feature_is_enabled(zpool_handle_t *zph)
-{
- nvlist_t *features;
- uint64_t feat_refcount;
-
- /* check that features can be enabled */
- if (zpool_get_prop_int(zph, ZPOOL_PROP_VERSION, NULL)
- < SPA_VERSION_FEATURES)
- return (B_FALSE);
-
- /* check for crypto feature */
- features = zpool_get_features(zph);
- if (!features || nvlist_lookup_uint64(features,
- spa_feature_table[SPA_FEATURE_ENCRYPTION].fi_guid,
- &feat_refcount) != 0)
- return (B_FALSE);
-
- return (B_TRUE);
-}
-
-static int
-populate_create_encryption_params_nvlists(libzfs_handle_t *hdl,
- zfs_handle_t *zhp, boolean_t newkey, zfs_keyformat_t keyformat,
- const char *keylocation, nvlist_t *props, uint8_t **wkeydata,
- uint_t *wkeylen)
-{
- int ret;
- uint64_t iters = 0, salt = 0;
- uint8_t *key_material = NULL;
- size_t key_material_len = 0;
- uint8_t *key_data = NULL;
- const char *fsname = (zhp) ? zfs_get_name(zhp) : NULL;
-
- /* get key material from keyformat and keylocation */
- ret = get_key_material(hdl, B_TRUE, newkey, keyformat, keylocation,
- fsname, &key_material, &key_material_len, NULL);
- if (ret != 0)
- goto error;
-
- /* passphrase formats require a salt and pbkdf2 iters property */
- if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
- /* always generate a new salt */
- ret = pkcs11_get_urandom((uint8_t *)&salt, sizeof (uint64_t));
- if (ret != sizeof (uint64_t)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to generate salt."));
- goto error;
- }
-
- ret = nvlist_add_uint64(props,
- zfs_prop_to_name(ZFS_PROP_PBKDF2_SALT), salt);
- if (ret != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to add salt to properties."));
- goto error;
- }
-
- /*
- * If not otherwise specified, use the default number of
- * pbkdf2 iterations. If specified, we have already checked
- * that the given value is greater than MIN_PBKDF2_ITERATIONS
- * during zfs_valid_proplist().
- */
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
- if (ret == ENOENT) {
- iters = DEFAULT_PBKDF2_ITERATIONS;
- ret = nvlist_add_uint64(props,
- zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), iters);
- if (ret != 0)
- goto error;
- } else if (ret != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to get pbkdf2 iterations."));
- goto error;
- }
- } else {
- /* check that pbkdf2iters was not specified by the user */
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
- if (ret == 0) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Cannot specify pbkdf2iters with a non-passphrase "
- "keyformat."));
- goto error;
- }
- }
-
- /* derive a key from the key material */
- ret = derive_key(hdl, keyformat, iters, key_material, salt, &key_data);
- if (ret != 0)
- goto error;
-
- free(key_material);
-
- *wkeydata = key_data;
- *wkeylen = WRAPPING_KEY_LEN;
- return (0);
-
-error:
- if (key_material != NULL)
- free(key_material);
- if (key_data != NULL)
- free(key_data);
-
- *wkeydata = NULL;
- *wkeylen = 0;
- return (ret);
-}
-
-static boolean_t
-proplist_has_encryption_props(nvlist_t *props)
-{
- int ret;
- uint64_t intval;
- const char *strval;
-
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_ENCRYPTION), &intval);
- if (ret == 0 && intval != ZIO_CRYPT_OFF)
- return (B_TRUE);
-
- ret = nvlist_lookup_string(props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &strval);
- if (ret == 0 && strcmp(strval, "none") != 0)
- return (B_TRUE);
-
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &intval);
- if (ret == 0)
- return (B_TRUE);
-
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &intval);
- if (ret == 0)
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-int
-zfs_crypto_get_encryption_root(zfs_handle_t *zhp, boolean_t *is_encroot,
- char *buf)
-{
- int ret;
- char prop_encroot[MAXNAMELEN];
-
- /* if the dataset isn't encrypted, just return */
- if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) == ZIO_CRYPT_OFF) {
- *is_encroot = B_FALSE;
- if (buf != NULL)
- buf[0] = '\0';
- return (0);
- }
-
- ret = zfs_prop_get(zhp, ZFS_PROP_ENCRYPTION_ROOT, prop_encroot,
- sizeof (prop_encroot), NULL, NULL, 0, B_TRUE);
- if (ret != 0) {
- *is_encroot = B_FALSE;
- if (buf != NULL)
- buf[0] = '\0';
- return (ret);
- }
-
- *is_encroot = strcmp(prop_encroot, zfs_get_name(zhp)) == 0;
- if (buf != NULL)
- strcpy(buf, prop_encroot);
-
- return (0);
-}
-
-int
-zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
- nvlist_t *pool_props, boolean_t stdin_available, uint8_t **wkeydata_out,
- uint_t *wkeylen_out)
-{
- int ret;
- char errbuf[ERRBUFLEN];
- uint64_t crypt = ZIO_CRYPT_INHERIT, pcrypt = ZIO_CRYPT_INHERIT;
- uint64_t keyformat = ZFS_KEYFORMAT_NONE;
- const char *keylocation = NULL;
- zfs_handle_t *pzhp = NULL;
- uint8_t *wkeydata = NULL;
- uint_t wkeylen = 0;
- boolean_t local_crypt = B_TRUE;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Encryption create error"));
-
- /* lookup crypt from props */
- ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_ENCRYPTION), &crypt);
- if (ret != 0)
- local_crypt = B_FALSE;
-
- /* lookup key location and format from props */
- (void) nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat);
- (void) nvlist_lookup_string(props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
-
- if (parent_name != NULL) {
- /* get a reference to parent dataset */
- pzhp = make_dataset_handle(hdl, parent_name);
- if (pzhp == NULL) {
- ret = ENOENT;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to lookup parent."));
- goto out;
- }
-
- /* Lookup parent's crypt */
- pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);
-
- /* Params require the encryption feature */
- if (!encryption_feature_is_enabled(pzhp->zpool_hdl)) {
- if (proplist_has_encryption_props(props)) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Encryption feature not enabled."));
- goto out;
- }
-
- ret = 0;
- goto out;
- }
- } else {
- /*
- * special case for root dataset where encryption feature
- * feature won't be on disk yet
- */
- if (!nvlist_exists(pool_props, "feature@encryption")) {
- if (proplist_has_encryption_props(props)) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Encryption feature not enabled."));
- goto out;
- }
-
- ret = 0;
- goto out;
- }
-
- pcrypt = ZIO_CRYPT_OFF;
- }
-
- /* Get the inherited encryption property if we don't have it locally */
- if (!local_crypt)
- crypt = pcrypt;
-
- /*
- * At this point crypt should be the actual encryption value. If
- * encryption is off just verify that no encryption properties have
- * been specified and return.
- */
- if (crypt == ZIO_CRYPT_OFF) {
- if (proplist_has_encryption_props(props)) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Encryption must be turned on to set encryption "
- "properties."));
- goto out;
- }
-
- ret = 0;
- goto out;
- }
-
- /*
- * If we have a parent crypt it is valid to specify encryption alone.
- * This will result in a child that is encrypted with the chosen
- * encryption suite that will also inherit the parent's key. If
- * the parent is not encrypted we need an encryption suite provided.
- */
- if (pcrypt == ZIO_CRYPT_OFF && keylocation == NULL &&
- keyformat == ZFS_KEYFORMAT_NONE) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Keyformat required for new encryption root."));
- goto out;
- }
-
- /*
- * Specifying a keylocation implies this will be a new encryption root.
- * Check that a keyformat is also specified.
- */
- if (keylocation != NULL && keyformat == ZFS_KEYFORMAT_NONE) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Keyformat required for new encryption root."));
- goto out;
- }
-
- /* default to prompt if no keylocation is specified */
- if (keyformat != ZFS_KEYFORMAT_NONE && keylocation == NULL) {
- keylocation = (char *)"prompt";
- ret = nvlist_add_string(props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), keylocation);
- if (ret != 0)
- goto out;
- }
-
- /*
- * If a local key is provided, this dataset will be a new
- * encryption root. Populate the encryption params.
- */
- if (keylocation != NULL) {
- /*
- * 'zfs recv -o keylocation=prompt' won't work because stdin
- * is being used by the send stream, so we disallow it.
- */
- if (!stdin_available && strcmp(keylocation, "prompt") == 0) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Cannot use "
- "'prompt' keylocation because stdin is in use."));
- goto out;
- }
-
- ret = populate_create_encryption_params_nvlists(hdl, NULL,
- B_TRUE, keyformat, keylocation, props, &wkeydata,
- &wkeylen);
- if (ret != 0)
- goto out;
- }
-
- if (pzhp != NULL)
- zfs_close(pzhp);
-
- *wkeydata_out = wkeydata;
- *wkeylen_out = wkeylen;
- return (0);
-
-out:
- if (pzhp != NULL)
- zfs_close(pzhp);
- if (wkeydata != NULL)
- free(wkeydata);
-
- *wkeydata_out = NULL;
- *wkeylen_out = 0;
- return (ret);
-}
-
-int
-zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
- char *parent_name, nvlist_t *props)
-{
- (void) origin_zhp, (void) parent_name;
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Encryption clone error"));
-
- /*
- * No encryption properties should be specified. They will all be
- * inherited from the origin dataset.
- */
- if (nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYFORMAT)) ||
- nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION)) ||
- nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION)) ||
- nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS))) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Encryption properties must inherit from origin dataset."));
- return (EINVAL);
- }
-
- return (0);
-}
-
-typedef struct loadkeys_cbdata {
- uint64_t cb_numfailed;
- uint64_t cb_numattempted;
-} loadkey_cbdata_t;
-
-static int
-load_keys_cb(zfs_handle_t *zhp, void *arg)
-{
- int ret;
- boolean_t is_encroot;
- loadkey_cbdata_t *cb = arg;
- uint64_t keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
-
- /* only attempt to load keys for encryption roots */
- ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
- if (ret != 0 || !is_encroot)
- goto out;
-
- /* don't attempt to load already loaded keys */
- if (keystatus == ZFS_KEYSTATUS_AVAILABLE)
- goto out;
-
- /* Attempt to load the key. Record status in cb. */
- cb->cb_numattempted++;
-
- ret = zfs_crypto_load_key(zhp, B_FALSE, NULL);
- if (ret)
- cb->cb_numfailed++;
-
-out:
- (void) zfs_iter_filesystems_v2(zhp, 0, load_keys_cb, cb);
- zfs_close(zhp);
-
- /* always return 0, since this function is best effort */
- return (0);
-}
-
-/*
- * This function is best effort. It attempts to load all the keys for the given
- * filesystem and all of its children.
- */
-int
-zfs_crypto_attempt_load_keys(libzfs_handle_t *hdl, const char *fsname)
-{
- int ret;
- zfs_handle_t *zhp = NULL;
- loadkey_cbdata_t cb = { 0 };
-
- zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL) {
- ret = ENOENT;
- goto error;
- }
-
- ret = load_keys_cb(zfs_handle_dup(zhp), &cb);
- if (ret)
- goto error;
-
- (void) printf(gettext("%llu / %llu keys successfully loaded\n"),
- (u_longlong_t)(cb.cb_numattempted - cb.cb_numfailed),
- (u_longlong_t)cb.cb_numattempted);
-
- if (cb.cb_numfailed != 0) {
- ret = -1;
- goto error;
- }
-
- zfs_close(zhp);
- return (0);
-
-error:
- if (zhp != NULL)
- zfs_close(zhp);
- return (ret);
-}
-
-int
-zfs_crypto_load_key(zfs_handle_t *zhp, boolean_t noop,
- const char *alt_keylocation)
-{
- int ret, attempts = 0;
- char errbuf[ERRBUFLEN];
- uint64_t keystatus, iters = 0, salt = 0;
- uint64_t keyformat = ZFS_KEYFORMAT_NONE;
- char prop_keylocation[MAXNAMELEN];
- char prop_encroot[MAXNAMELEN];
- const char *keylocation = NULL;
- uint8_t *key_material = NULL, *key_data = NULL;
- size_t key_material_len;
- boolean_t is_encroot, can_retry = B_FALSE, correctible = B_FALSE;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Key load error"));
-
- /* check that encryption is enabled for the pool */
- if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Encryption feature not enabled."));
- ret = EINVAL;
- goto error;
- }
-
- /* Fetch the keyformat. Check that the dataset is encrypted. */
- keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT);
- if (keyformat == ZFS_KEYFORMAT_NONE) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' is not encrypted."), zfs_get_name(zhp));
- ret = EINVAL;
- goto error;
- }
-
- /*
- * Fetch the key location. Check that we are working with an
- * encryption root.
- */
- ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Failed to get encryption root for '%s'."),
- zfs_get_name(zhp));
- goto error;
- } else if (!is_encroot) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Keys must be loaded for encryption root of '%s' (%s)."),
- zfs_get_name(zhp), prop_encroot);
- ret = EINVAL;
- goto error;
- }
-
- /*
- * if the caller has elected to override the keylocation property
- * use that instead
- */
- if (alt_keylocation != NULL) {
- keylocation = alt_keylocation;
- } else {
- ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION, prop_keylocation,
- sizeof (prop_keylocation), NULL, NULL, 0, B_TRUE);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Failed to get keylocation for '%s'."),
- zfs_get_name(zhp));
- goto error;
- }
-
- keylocation = prop_keylocation;
- }
-
- /* check that the key is unloaded unless this is a noop */
- if (!noop) {
- keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
- if (keystatus == ZFS_KEYSTATUS_AVAILABLE) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key already loaded for '%s'."), zfs_get_name(zhp));
- ret = EEXIST;
- goto error;
- }
- }
-
- /* passphrase formats require a salt and pbkdf2_iters property */
- if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
- salt = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_SALT);
- iters = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_ITERS);
- }
-
-try_again:
- /* fetching and deriving the key are correctable errors. set the flag */
- correctible = B_TRUE;
-
- /* get key material from key format and location */
- ret = get_key_material(zhp->zfs_hdl, B_FALSE, B_FALSE, keyformat,
- keylocation, zfs_get_name(zhp), &key_material, &key_material_len,
- &can_retry);
- if (ret != 0)
- goto error;
-
- /* derive a key from the key material */
- ret = derive_key(zhp->zfs_hdl, keyformat, iters, key_material, salt,
- &key_data);
- if (ret != 0)
- goto error;
-
- correctible = B_FALSE;
-
- /* pass the wrapping key and noop flag to the ioctl */
- ret = lzc_load_key(zhp->zfs_name, noop, key_data, WRAPPING_KEY_LEN);
- if (ret != 0) {
- switch (ret) {
- case EPERM:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Permission denied."));
- break;
- case EINVAL:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Invalid parameters provided for dataset %s."),
- zfs_get_name(zhp));
- break;
- case EEXIST:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key already loaded for '%s'."), zfs_get_name(zhp));
- break;
- case EBUSY:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' is busy."), zfs_get_name(zhp));
- break;
- case EACCES:
- correctible = B_TRUE;
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Incorrect key provided for '%s'."),
- zfs_get_name(zhp));
- break;
- case ZFS_ERR_CRYPTO_NOTSUP:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' uses an unsupported encryption suite."),
- zfs_get_name(zhp));
- break;
- }
- goto error;
- }
-
- free(key_material);
- free(key_data);
-
- return (0);
-
-error:
- zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
- if (key_material != NULL) {
- free(key_material);
- key_material = NULL;
- }
- if (key_data != NULL) {
- free(key_data);
- key_data = NULL;
- }
-
- /*
- * Here we decide if it is ok to allow the user to retry entering their
- * key. The can_retry flag will be set if the user is entering their
- * key from an interactive prompt. The correctable flag will only be
- * set if an error that occurred could be corrected by retrying. Both
- * flags are needed to allow the user to attempt key entry again
- */
- attempts++;
- if (can_retry && correctible && attempts < MAX_KEY_PROMPT_ATTEMPTS)
- goto try_again;
-
- return (ret);
-}
-
-int
-zfs_crypto_unload_key(zfs_handle_t *zhp)
-{
- int ret;
- char errbuf[ERRBUFLEN];
- char prop_encroot[MAXNAMELEN];
- uint64_t keystatus, keyformat;
- boolean_t is_encroot;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Key unload error"));
-
- /* check that encryption is enabled for the pool */
- if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Encryption feature not enabled."));
- ret = EINVAL;
- goto error;
- }
-
- /* Fetch the keyformat. Check that the dataset is encrypted. */
- keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT);
- if (keyformat == ZFS_KEYFORMAT_NONE) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' is not encrypted."), zfs_get_name(zhp));
- ret = EINVAL;
- goto error;
- }
-
- /*
- * Fetch the key location. Check that we are working with an
- * encryption root.
- */
- ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Failed to get encryption root for '%s'."),
- zfs_get_name(zhp));
- goto error;
- } else if (!is_encroot) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Keys must be unloaded for encryption root of '%s' (%s)."),
- zfs_get_name(zhp), prop_encroot);
- ret = EINVAL;
- goto error;
- }
-
- /* check that the key is loaded */
- keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
- if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key already unloaded for '%s'."), zfs_get_name(zhp));
- ret = EACCES;
- goto error;
- }
-
- /* call the ioctl */
- ret = lzc_unload_key(zhp->zfs_name);
-
- if (ret != 0) {
- switch (ret) {
- case EPERM:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Permission denied."));
- break;
- case EACCES:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key already unloaded for '%s'."),
- zfs_get_name(zhp));
- break;
- case EBUSY:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' is busy."), zfs_get_name(zhp));
- break;
- }
- zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
- }
-
- return (ret);
-
-error:
- zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
- return (ret);
-}
-
-static int
-zfs_crypto_verify_rewrap_nvlist(zfs_handle_t *zhp, nvlist_t *props,
- nvlist_t **props_out, char *errbuf)
-{
- int ret;
- nvpair_t *elem = NULL;
- zfs_prop_t prop;
- nvlist_t *new_props = NULL;
-
- new_props = fnvlist_alloc();
-
- /*
- * loop through all provided properties, we should only have
- * keyformat, keylocation and pbkdf2iters. The actual validation of
- * values is done by zfs_valid_proplist().
- */
- while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
- const char *propname = nvpair_name(elem);
- prop = zfs_name_to_prop(propname);
-
- switch (prop) {
- case ZFS_PROP_PBKDF2_ITERS:
- case ZFS_PROP_KEYFORMAT:
- case ZFS_PROP_KEYLOCATION:
- break;
- default:
- ret = EINVAL;
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Only keyformat, keylocation and pbkdf2iters may "
- "be set with this command."));
- goto error;
- }
- }
-
- new_props = zfs_valid_proplist(zhp->zfs_hdl, zhp->zfs_type, props,
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED), NULL, zhp->zpool_hdl,
- B_TRUE, errbuf);
- if (new_props == NULL) {
- ret = EINVAL;
- goto error;
- }
-
- *props_out = new_props;
- return (0);
-
-error:
- nvlist_free(new_props);
- *props_out = NULL;
- return (ret);
-}
-
-int
-zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
-{
- int ret;
- char errbuf[ERRBUFLEN];
- boolean_t is_encroot;
- nvlist_t *props = NULL;
- uint8_t *wkeydata = NULL;
- uint_t wkeylen = 0;
- dcp_cmd_t cmd = (inheritkey) ? DCP_CMD_INHERIT : DCP_CMD_NEW_KEY;
- uint64_t crypt, pcrypt, keystatus, pkeystatus;
- uint64_t keyformat = ZFS_KEYFORMAT_NONE;
- zfs_handle_t *pzhp = NULL;
- const char *keylocation = NULL;
- char origin_name[MAXNAMELEN];
- char prop_keylocation[MAXNAMELEN];
- char parent_name[ZFS_MAX_DATASET_NAME_LEN];
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Key change error"));
-
- /* check that encryption is enabled for the pool */
- if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Encryption feature not enabled."));
- ret = EINVAL;
- goto error;
- }
-
- /* get crypt from dataset */
- crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
- if (crypt == ZIO_CRYPT_OFF) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Dataset not encrypted."));
- ret = EINVAL;
- goto error;
- }
-
- /* get the encryption root of the dataset */
- ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Failed to get encryption root for '%s'."),
- zfs_get_name(zhp));
- goto error;
- }
-
- /* Clones use their origin's key and cannot rewrap it */
- ret = zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin_name,
- sizeof (origin_name), NULL, NULL, 0, B_TRUE);
- if (ret == 0 && strcmp(origin_name, "") != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Keys cannot be changed on clones."));
- ret = EINVAL;
- goto error;
- }
-
- /*
- * If the user wants to use the inheritkey variant of this function
- * we don't need to collect any crypto arguments.
- */
- if (!inheritkey) {
- /* validate the provided properties */
- ret = zfs_crypto_verify_rewrap_nvlist(zhp, raw_props, &props,
- errbuf);
- if (ret != 0)
- goto error;
-
- /*
- * Load keyformat and keylocation from the nvlist. Fetch from
- * the dataset properties if not specified.
- */
- (void) nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat);
- (void) nvlist_lookup_string(props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
-
- if (is_encroot) {
- /*
- * If this is already an encryption root, just keep
- * any properties not set by the user.
- */
- if (keyformat == ZFS_KEYFORMAT_NONE) {
- keyformat = zfs_prop_get_int(zhp,
- ZFS_PROP_KEYFORMAT);
- ret = nvlist_add_uint64(props,
- zfs_prop_to_name(ZFS_PROP_KEYFORMAT),
- keyformat);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl,
- dgettext(TEXT_DOMAIN, "Failed to "
- "get existing keyformat "
- "property."));
- goto error;
- }
- }
-
- if (keylocation == NULL) {
- ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
- prop_keylocation, sizeof (prop_keylocation),
- NULL, NULL, 0, B_TRUE);
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl,
- dgettext(TEXT_DOMAIN, "Failed to "
- "get existing keylocation "
- "property."));
- goto error;
- }
-
- keylocation = prop_keylocation;
- }
- } else {
- /* need a new key for non-encryption roots */
- if (keyformat == ZFS_KEYFORMAT_NONE) {
- ret = EINVAL;
- zfs_error_aux(zhp->zfs_hdl,
- dgettext(TEXT_DOMAIN, "Keyformat required "
- "for new encryption root."));
- goto error;
- }
-
- /* default to prompt if no keylocation is specified */
- if (keylocation == NULL) {
- keylocation = "prompt";
- ret = nvlist_add_string(props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
- keylocation);
- if (ret != 0)
- goto error;
- }
- }
-
- /* fetch the new wrapping key and associated properties */
- ret = populate_create_encryption_params_nvlists(zhp->zfs_hdl,
- zhp, B_TRUE, keyformat, keylocation, props, &wkeydata,
- &wkeylen);
- if (ret != 0)
- goto error;
- } else {
- /* check that zhp is an encryption root */
- if (!is_encroot) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key inheritting can only be performed on "
- "encryption roots."));
- ret = EINVAL;
- goto error;
- }
-
- /* get the parent's name */
- ret = zfs_parent_name(zhp, parent_name, sizeof (parent_name));
- if (ret != 0) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Root dataset cannot inherit key."));
- ret = EINVAL;
- goto error;
- }
-
- /* get a handle to the parent */
- pzhp = make_dataset_handle(zhp->zfs_hdl, parent_name);
- if (pzhp == NULL) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Failed to lookup parent."));
- ret = ENOENT;
- goto error;
- }
-
- /* parent must be encrypted */
- pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);
- if (pcrypt == ZIO_CRYPT_OFF) {
- zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Parent must be encrypted."));
- ret = EINVAL;
- goto error;
- }
-
- /* check that the parent's key is loaded */
- pkeystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS);
- if (pkeystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
- zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Parent key must be loaded."));
- ret = EACCES;
- goto error;
- }
- }
-
- /* check that the key is loaded */
- keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
- if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key must be loaded."));
- ret = EACCES;
- goto error;
- }
-
- /* call the ioctl */
- ret = lzc_change_key(zhp->zfs_name, cmd, props, wkeydata, wkeylen);
- if (ret != 0) {
- switch (ret) {
- case EPERM:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Permission denied."));
- break;
- case EINVAL:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Invalid properties for key change."));
- break;
- case EACCES:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "Key is not currently loaded."));
- break;
- }
- zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
- }
-
- if (pzhp != NULL)
- zfs_close(pzhp);
- if (props != NULL)
- nvlist_free(props);
- if (wkeydata != NULL)
- free(wkeydata);
-
- return (ret);
-
-error:
- if (pzhp != NULL)
- zfs_close(pzhp);
- if (props != NULL)
- nvlist_free(props);
- if (wkeydata != NULL)
- free(wkeydata);
-
- zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
- return (ret);
-}
-
-boolean_t
-zfs_is_encrypted(zfs_handle_t *zhp)
-{
- uint8_t flags = zhp->zfs_dmustats.dds_flags;
-
- if (flags & DDS_FLAG_HAS_ENCRYPTED)
- return ((flags & DDS_FLAG_ENCRYPTED) != 0);
-
- return (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF);
-}
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
deleted file mode 100644
index e1b91fc47291..000000000000
--- a/lib/libzfs/libzfs_dataset.c
+++ /dev/null
@@ -1,5675 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2019 Joyent, Inc.
- * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
- * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
- * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
- * Copyright (c) 2013 Martin Matuska. All rights reserved.
- * Copyright (c) 2013 Steven Hartland. All rights reserved.
- * Copyright 2017 Nexenta Systems, Inc.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright 2017-2018 RackTop Systems.
- * Copyright (c) 2019 Datto Inc.
- * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
- * Copyright (c) 2021 Matt Fiddaman
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stddef.h>
-#include <zone.h>
-#include <fcntl.h>
-#include <sys/mntent.h>
-#include <sys/mount.h>
-#include <pwd.h>
-#include <grp.h>
-#ifdef HAVE_IDMAP
-#include <idmap.h>
-#include <aclutils.h>
-#include <directory.h>
-#endif /* HAVE_IDMAP */
-
-#include <sys/dnode.h>
-#include <sys/spa.h>
-#include <sys/zap.h>
-#include <sys/dsl_crypt.h>
-#include <libzfs.h>
-#include <libzutil.h>
-
-#include "zfs_namecheck.h"
-#include "zfs_prop.h"
-#include "libzfs_impl.h"
-#include "zfs_deleg.h"
-
-static __thread struct passwd gpwd;
-static __thread struct group ggrp;
-static __thread char rpbuf[2048];
-
-static int userquota_propname_decode(const char *propname, boolean_t zoned,
- zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
-
-/*
- * Given a single type (not a mask of types), return the type in a human
- * readable form.
- */
-const char *
-zfs_type_to_name(zfs_type_t type)
-{
- switch (type) {
- case ZFS_TYPE_FILESYSTEM:
- return (dgettext(TEXT_DOMAIN, "filesystem"));
- case ZFS_TYPE_SNAPSHOT:
- return (dgettext(TEXT_DOMAIN, "snapshot"));
- case ZFS_TYPE_VOLUME:
- return (dgettext(TEXT_DOMAIN, "volume"));
- case ZFS_TYPE_POOL:
- return (dgettext(TEXT_DOMAIN, "pool"));
- case ZFS_TYPE_BOOKMARK:
- return (dgettext(TEXT_DOMAIN, "bookmark"));
- default:
- assert(!"unhandled zfs_type_t");
- }
-
- return (NULL);
-}
-
-/*
- * Validate a ZFS path. This is used even before trying to open the dataset, to
- * provide a more meaningful error message. We call zfs_error_aux() to
- * explain exactly why the name was not valid.
- */
-int
-zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
- boolean_t modifying)
-{
- namecheck_err_t why;
- char what;
-
- if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
- if (hdl != NULL)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshot delimiter '@' is not expected here"));
- return (0);
- }
-
- if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
- if (hdl != NULL)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "missing '@' delimiter in snapshot name"));
- return (0);
- }
-
- if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) {
- if (hdl != NULL)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "bookmark delimiter '#' is not expected here"));
- return (0);
- }
-
- if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) {
- if (hdl != NULL)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "missing '#' delimiter in bookmark name"));
- return (0);
- }
-
- if (modifying && strchr(path, '%') != NULL) {
- if (hdl != NULL)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid character %c in name"), '%');
- return (0);
- }
-
- if (entity_namecheck(path, &why, &what) != 0) {
- if (hdl != NULL) {
- switch (why) {
- case NAME_ERR_TOOLONG:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "name is too long"));
- break;
-
- case NAME_ERR_LEADING_SLASH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "leading slash in name"));
- break;
-
- case NAME_ERR_EMPTY_COMPONENT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "empty component or misplaced '@'"
- " or '#' delimiter in name"));
- break;
-
- case NAME_ERR_TRAILING_SLASH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "trailing slash in name"));
- break;
-
- case NAME_ERR_INVALCHAR:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "invalid character "
- "'%c' in name"), what);
- break;
-
- case NAME_ERR_MULTIPLE_DELIMITERS:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "multiple '@' and/or '#' delimiters in "
- "name"));
- break;
-
- case NAME_ERR_NOLETTER:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool doesn't begin with a letter"));
- break;
-
- case NAME_ERR_RESERVED:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "name is reserved"));
- break;
-
- case NAME_ERR_DISKLIKE:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "reserved disk name"));
- break;
-
- case NAME_ERR_SELF_REF:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "self reference, '.' is found in name"));
- break;
-
- case NAME_ERR_PARENT_REF:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "parent reference, '..' is found in name"));
- break;
-
- default:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "(%d) not defined"), why);
- break;
- }
- }
-
- return (0);
- }
-
- return (-1);
-}
-
-int
-zfs_name_valid(const char *name, zfs_type_t type)
-{
- if (type == ZFS_TYPE_POOL)
- return (zpool_name_valid(NULL, B_FALSE, name));
- return (zfs_validate_name(NULL, name, type, B_FALSE));
-}
-
-/*
- * This function takes the raw DSL properties, and filters out the user-defined
- * properties into a separate nvlist.
- */
-static nvlist_t *
-process_user_props(zfs_handle_t *zhp, nvlist_t *props)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvpair_t *elem;
- nvlist_t *nvl;
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
- (void) no_memory(hdl);
- return (NULL);
- }
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
- if (!zfs_prop_user(nvpair_name(elem)))
- continue;
-
- nvlist_t *propval = fnvpair_value_nvlist(elem);
- if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
- nvlist_free(nvl);
- (void) no_memory(hdl);
- return (NULL);
- }
- }
-
- return (nvl);
-}
-
-static zpool_handle_t *
-zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- zpool_handle_t *zph;
-
- if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
- if (hdl->libzfs_pool_handles != NULL)
- zph->zpool_next = hdl->libzfs_pool_handles;
- hdl->libzfs_pool_handles = zph;
- }
- return (zph);
-}
-
-static zpool_handle_t *
-zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- zpool_handle_t *zph = hdl->libzfs_pool_handles;
-
- while ((zph != NULL) &&
- (strncmp(pool_name, zpool_get_name(zph), len) != 0))
- zph = zph->zpool_next;
- return (zph);
-}
-
-/*
- * Returns a handle to the pool that contains the provided dataset.
- * If a handle to that pool already exists then that handle is returned.
- * Otherwise, a new handle is created and added to the list of handles.
- */
-static zpool_handle_t *
-zpool_handle(zfs_handle_t *zhp)
-{
- char *pool_name;
- int len;
- zpool_handle_t *zph;
-
- len = strcspn(zhp->zfs_name, "/@#") + 1;
- pool_name = zfs_alloc(zhp->zfs_hdl, len);
- (void) strlcpy(pool_name, zhp->zfs_name, len);
-
- zph = zpool_find_handle(zhp, pool_name, len);
- if (zph == NULL)
- zph = zpool_add_handle(zhp, pool_name);
-
- free(pool_name);
- return (zph);
-}
-
-void
-zpool_free_handles(libzfs_handle_t *hdl)
-{
- zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
-
- while (zph != NULL) {
- next = zph->zpool_next;
- zpool_close(zph);
- zph = next;
- }
- hdl->libzfs_pool_handles = NULL;
-}
-
-/*
- * Utility function to gather stats (objset and zpl) for the given object.
- */
-static int
-get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
-
- (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
-
- while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, zc) != 0) {
- if (errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, zc);
- else
- return (-1);
- }
- return (0);
-}
-
-/*
- * Utility function to get the received properties of the given object.
- */
-static int
-get_recvd_props_ioctl(zfs_handle_t *zhp)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvlist_t *recvdprops;
- zfs_cmd_t zc = {"\0"};
- int err;
-
- zcmd_alloc_dst_nvlist(hdl, &zc, 0);
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
- if (errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
- else {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
- }
-
- err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
- zcmd_free_nvlists(&zc);
- if (err != 0)
- return (-1);
-
- nvlist_free(zhp->zfs_recvd_props);
- zhp->zfs_recvd_props = recvdprops;
-
- return (0);
-}
-
-static int
-put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
-{
- nvlist_t *allprops, *userprops;
-
- zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */
-
- if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) {
- return (-1);
- }
-
- /*
- * XXX Why do we store the user props separately, in addition to
- * storing them in zfs_props?
- */
- if ((userprops = process_user_props(zhp, allprops)) == NULL) {
- nvlist_free(allprops);
- return (-1);
- }
-
- nvlist_free(zhp->zfs_props);
- nvlist_free(zhp->zfs_user_props);
-
- zhp->zfs_props = allprops;
- zhp->zfs_user_props = userprops;
-
- return (0);
-}
-
-static int
-get_stats(zfs_handle_t *zhp)
-{
- int rc = 0;
- zfs_cmd_t zc = {"\0"};
-
- zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
-
- if (get_stats_ioctl(zhp, &zc) != 0)
- rc = -1;
- else if (put_stats_zhdl(zhp, &zc) != 0)
- rc = -1;
- zcmd_free_nvlists(&zc);
- return (rc);
-}
-
-/*
- * Refresh the properties currently stored in the handle.
- */
-void
-zfs_refresh_properties(zfs_handle_t *zhp)
-{
- (void) get_stats(zhp);
-}
-
-/*
- * Makes a handle from the given dataset name. Used by zfs_open() and
- * zfs_iter_* to create child handles on the fly.
- */
-static int
-make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
-{
- if (put_stats_zhdl(zhp, zc) != 0)
- return (-1);
-
- /*
- * We've managed to open the dataset and gather statistics. Determine
- * the high-level type.
- */
- if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
- zhp->zfs_head_type = ZFS_TYPE_VOLUME;
- } else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) {
- zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
- } else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) {
- errno = EINVAL;
- return (-1);
- } else if (zhp->zfs_dmustats.dds_inconsistent) {
- errno = EBUSY;
- return (-1);
- } else {
- abort();
- }
-
- if (zhp->zfs_dmustats.dds_is_snapshot)
- zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
- else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
- zhp->zfs_type = ZFS_TYPE_VOLUME;
- else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
- zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
- else
- abort(); /* we should never see any other types */
-
- if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
- return (-1);
-
- return (0);
-}
-
-zfs_handle_t *
-make_dataset_handle(libzfs_handle_t *hdl, const char *path)
-{
- zfs_cmd_t zc = {"\0"};
-
- zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
-
- if (zhp == NULL)
- return (NULL);
-
- zhp->zfs_hdl = hdl;
- (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
- zcmd_alloc_dst_nvlist(hdl, &zc, 0);
-
- if (get_stats_ioctl(zhp, &zc) == -1) {
- zcmd_free_nvlists(&zc);
- free(zhp);
- return (NULL);
- }
- if (make_dataset_handle_common(zhp, &zc) == -1) {
- free(zhp);
- zhp = NULL;
- }
- zcmd_free_nvlists(&zc);
- return (zhp);
-}
-
-zfs_handle_t *
-make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
-{
- zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
-
- if (zhp == NULL)
- return (NULL);
-
- zhp->zfs_hdl = hdl;
- (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
- if (make_dataset_handle_common(zhp, zc) == -1) {
- free(zhp);
- return (NULL);
- }
- return (zhp);
-}
-
-zfs_handle_t *
-make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
-{
- zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
-
- if (zhp == NULL)
- return (NULL);
-
- zhp->zfs_hdl = pzhp->zfs_hdl;
- (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
- zhp->zfs_head_type = pzhp->zfs_type;
- zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
- zhp->zpool_hdl = zpool_handle(zhp);
-
- if (zc->zc_objset_stats.dds_creation_txg != 0) {
- /* structure assignment */
- zhp->zfs_dmustats = zc->zc_objset_stats;
- } else {
- if (get_stats_ioctl(zhp, zc) == -1) {
- zcmd_free_nvlists(zc);
- free(zhp);
- return (NULL);
- }
- if (make_dataset_handle_common(zhp, zc) == -1) {
- zcmd_free_nvlists(zc);
- free(zhp);
- return (NULL);
- }
- }
-
- if (zhp->zfs_dmustats.dds_is_snapshot ||
- strchr(zc->zc_name, '@') != NULL)
- zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
- else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
- zhp->zfs_type = ZFS_TYPE_VOLUME;
- else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
- zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
-
- return (zhp);
-}
-
-zfs_handle_t *
-zfs_handle_dup(zfs_handle_t *zhp_orig)
-{
- zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
-
- if (zhp == NULL)
- return (NULL);
-
- zhp->zfs_hdl = zhp_orig->zfs_hdl;
- zhp->zpool_hdl = zhp_orig->zpool_hdl;
- (void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
- sizeof (zhp->zfs_name));
- zhp->zfs_type = zhp_orig->zfs_type;
- zhp->zfs_head_type = zhp_orig->zfs_head_type;
- zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
- if (zhp_orig->zfs_props != NULL) {
- if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
- (void) no_memory(zhp->zfs_hdl);
- zfs_close(zhp);
- return (NULL);
- }
- }
- if (zhp_orig->zfs_user_props != NULL) {
- if (nvlist_dup(zhp_orig->zfs_user_props,
- &zhp->zfs_user_props, 0) != 0) {
- (void) no_memory(zhp->zfs_hdl);
- zfs_close(zhp);
- return (NULL);
- }
- }
- if (zhp_orig->zfs_recvd_props != NULL) {
- if (nvlist_dup(zhp_orig->zfs_recvd_props,
- &zhp->zfs_recvd_props, 0)) {
- (void) no_memory(zhp->zfs_hdl);
- zfs_close(zhp);
- return (NULL);
- }
- }
- zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
- if (zhp_orig->zfs_mntopts != NULL) {
- zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
- zhp_orig->zfs_mntopts);
- }
- zhp->zfs_props_table = zhp_orig->zfs_props_table;
- return (zhp);
-}
-
-boolean_t
-zfs_bookmark_exists(const char *path)
-{
- nvlist_t *bmarks;
- nvlist_t *props;
- char fsname[ZFS_MAX_DATASET_NAME_LEN];
- char *bmark_name;
- char *pound;
- int err;
- boolean_t rv;
-
- (void) strlcpy(fsname, path, sizeof (fsname));
- pound = strchr(fsname, '#');
- if (pound == NULL)
- return (B_FALSE);
-
- *pound = '\0';
- bmark_name = pound + 1;
- props = fnvlist_alloc();
- err = lzc_get_bookmarks(fsname, props, &bmarks);
- nvlist_free(props);
- if (err != 0) {
- nvlist_free(bmarks);
- return (B_FALSE);
- }
-
- rv = nvlist_exists(bmarks, bmark_name);
- nvlist_free(bmarks);
- return (rv);
-}
-
-zfs_handle_t *
-make_bookmark_handle(zfs_handle_t *parent, const char *path,
- nvlist_t *bmark_props)
-{
- zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
-
- if (zhp == NULL)
- return (NULL);
-
- /* Fill in the name. */
- zhp->zfs_hdl = parent->zfs_hdl;
- (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
-
- /* Set the property lists. */
- if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) {
- free(zhp);
- return (NULL);
- }
-
- /* Set the types. */
- zhp->zfs_head_type = parent->zfs_head_type;
- zhp->zfs_type = ZFS_TYPE_BOOKMARK;
-
- if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) {
- nvlist_free(zhp->zfs_props);
- free(zhp);
- return (NULL);
- }
-
- return (zhp);
-}
-
-struct zfs_open_bookmarks_cb_data {
- const char *path;
- zfs_handle_t *zhp;
-};
-
-static int
-zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data)
-{
- struct zfs_open_bookmarks_cb_data *dp = data;
-
- /*
- * Is it the one we are looking for?
- */
- if (strcmp(dp->path, zfs_get_name(zhp)) == 0) {
- /*
- * We found it. Save it and let the caller know we are done.
- */
- dp->zhp = zhp;
- return (EEXIST);
- }
-
- /*
- * Not found. Close the handle and ask for another one.
- */
- zfs_close(zhp);
- return (0);
-}
-
-/*
- * Opens the given snapshot, bookmark, filesystem, or volume. The 'types'
- * argument is a mask of acceptable types. The function will print an
- * appropriate error message and return NULL if it can't be opened.
- */
-zfs_handle_t *
-zfs_open(libzfs_handle_t *hdl, const char *path, int types)
-{
- zfs_handle_t *zhp;
- char errbuf[ERRBUFLEN];
- char *bookp;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
-
- /*
- * Validate the name before we even try to open it.
- */
- if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
- (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- errno = EINVAL;
- return (NULL);
- }
-
- /*
- * Bookmarks needs to be handled separately.
- */
- bookp = strchr(path, '#');
- if (bookp == NULL) {
- /*
- * Try to get stats for the dataset, which will tell us if it
- * exists.
- */
- errno = 0;
- if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
- (void) zfs_standard_error(hdl, errno, errbuf);
- return (NULL);
- }
- } else {
- char dsname[ZFS_MAX_DATASET_NAME_LEN];
- zfs_handle_t *pzhp;
- struct zfs_open_bookmarks_cb_data cb_data = {path, NULL};
-
- /*
- * We need to cut out '#' and everything after '#'
- * to get the parent dataset name only.
- */
- assert(bookp - path < sizeof (dsname));
- (void) strlcpy(dsname, path,
- MIN(sizeof (dsname), bookp - path + 1));
-
- /*
- * Create handle for the parent dataset.
- */
- errno = 0;
- if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) {
- (void) zfs_standard_error(hdl, errno, errbuf);
- return (NULL);
- }
-
- /*
- * Iterate bookmarks to find the right one.
- */
- errno = 0;
- if ((zfs_iter_bookmarks_v2(pzhp, 0, zfs_open_bookmarks_cb,
- &cb_data) == 0) && (cb_data.zhp == NULL)) {
- (void) zfs_error(hdl, EZFS_NOENT, errbuf);
- zfs_close(pzhp);
- errno = ENOENT;
- return (NULL);
- }
- if (cb_data.zhp == NULL) {
- (void) zfs_standard_error(hdl, errno, errbuf);
- zfs_close(pzhp);
- return (NULL);
- }
- zhp = cb_data.zhp;
-
- /*
- * Cleanup.
- */
- zfs_close(pzhp);
- }
-
- if (!(types & zhp->zfs_type)) {
- (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
- zfs_close(zhp);
- errno = EINVAL;
- return (NULL);
- }
-
- return (zhp);
-}
-
-/*
- * Release a ZFS handle. Nothing to do but free the associated memory.
- */
-void
-zfs_close(zfs_handle_t *zhp)
-{
- if (zhp->zfs_mntopts)
- free(zhp->zfs_mntopts);
- nvlist_free(zhp->zfs_props);
- nvlist_free(zhp->zfs_user_props);
- nvlist_free(zhp->zfs_recvd_props);
- free(zhp);
-}
-
-typedef struct mnttab_node {
- struct mnttab mtn_mt;
- avl_node_t mtn_node;
-} mnttab_node_t;
-
-static int
-libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
-{
- const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
- const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
- int rv;
-
- rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
-
- return (TREE_ISIGN(rv));
-}
-
-void
-libzfs_mnttab_init(libzfs_handle_t *hdl)
-{
- pthread_mutex_init(&hdl->libzfs_mnttab_cache_lock, NULL);
- assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
- avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
- sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
-}
-
-static int
-libzfs_mnttab_update(libzfs_handle_t *hdl)
-{
- FILE *mnttab;
- struct mnttab entry;
-
- if ((mnttab = fopen(MNTTAB, "re")) == NULL)
- return (ENOENT);
-
- while (getmntent(mnttab, &entry) == 0) {
- mnttab_node_t *mtn;
- avl_index_t where;
-
- if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
- continue;
-
- mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
- mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
- mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
- mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
- mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
-
- /* Exclude duplicate mounts */
- if (avl_find(&hdl->libzfs_mnttab_cache, mtn, &where) != NULL) {
- free(mtn->mtn_mt.mnt_special);
- free(mtn->mtn_mt.mnt_mountp);
- free(mtn->mtn_mt.mnt_fstype);
- free(mtn->mtn_mt.mnt_mntopts);
- free(mtn);
- continue;
- }
-
- avl_add(&hdl->libzfs_mnttab_cache, mtn);
- }
-
- (void) fclose(mnttab);
- return (0);
-}
-
-void
-libzfs_mnttab_fini(libzfs_handle_t *hdl)
-{
- void *cookie = NULL;
- mnttab_node_t *mtn;
-
- while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
- != NULL) {
- free(mtn->mtn_mt.mnt_special);
- free(mtn->mtn_mt.mnt_mountp);
- free(mtn->mtn_mt.mnt_fstype);
- free(mtn->mtn_mt.mnt_mntopts);
- free(mtn);
- }
- avl_destroy(&hdl->libzfs_mnttab_cache);
- (void) pthread_mutex_destroy(&hdl->libzfs_mnttab_cache_lock);
-}
-
-void
-libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
-{
- hdl->libzfs_mnttab_enable = enable;
-}
-
-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;
-
- if (!hdl->libzfs_mnttab_enable) {
- struct mnttab srch = { 0 };
-
- if (avl_numnodes(&hdl->libzfs_mnttab_cache))
- libzfs_mnttab_fini(hdl);
-
- if ((mnttab = fopen(MNTTAB, "re")) == NULL)
- return (ENOENT);
-
- srch.mnt_special = (char *)fsname;
- srch.mnt_fstype = (char *)MNTTYPE_ZFS;
- ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0;
- (void) fclose(mnttab);
- return (ret);
- }
-
- pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
- if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) {
- int error;
-
- if ((error = libzfs_mnttab_update(hdl)) != 0) {
- pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
- return (error);
- }
- }
-
- find.mtn_mt.mnt_special = (char *)fsname;
- mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
- if (mtn) {
- *entry = mtn->mtn_mt;
- ret = 0;
- }
- pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
- return (ret);
-}
-
-void
-libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
- const char *mountp, const char *mntopts)
-{
- mnttab_node_t *mtn;
-
- pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
- if (avl_numnodes(&hdl->libzfs_mnttab_cache) != 0) {
- mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
- mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
- mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
- mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
- mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
- /*
- * Another thread may have already added this entry
- * via libzfs_mnttab_update. If so we should skip it.
- */
- if (avl_find(&hdl->libzfs_mnttab_cache, mtn, NULL) != NULL) {
- free(mtn->mtn_mt.mnt_special);
- free(mtn->mtn_mt.mnt_mountp);
- free(mtn->mtn_mt.mnt_fstype);
- free(mtn->mtn_mt.mnt_mntopts);
- free(mtn);
- } else {
- avl_add(&hdl->libzfs_mnttab_cache, mtn);
- }
- }
- pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
-}
-
-void
-libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
-{
- mnttab_node_t find;
- mnttab_node_t *ret;
-
- pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
- find.mtn_mt.mnt_special = (char *)fsname;
- if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
- != NULL) {
- avl_remove(&hdl->libzfs_mnttab_cache, ret);
- free(ret->mtn_mt.mnt_special);
- free(ret->mtn_mt.mnt_mountp);
- free(ret->mtn_mt.mnt_fstype);
- free(ret->mtn_mt.mnt_mntopts);
- free(ret);
- }
- pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
-}
-
-int
-zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
-{
- zpool_handle_t *zpool_handle = zhp->zpool_hdl;
-
- if (zpool_handle == NULL)
- return (-1);
-
- *spa_version = zpool_get_prop_int(zpool_handle,
- ZPOOL_PROP_VERSION, NULL);
- return (0);
-}
-
-/*
- * The choice of reservation property depends on the SPA version.
- */
-static int
-zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
-{
- int spa_version;
-
- if (zfs_spa_version(zhp, &spa_version) < 0)
- return (-1);
-
- if (spa_version >= SPA_VERSION_REFRESERVATION)
- *resv_prop = ZFS_PROP_REFRESERVATION;
- else
- *resv_prop = ZFS_PROP_RESERVATION;
-
- return (0);
-}
-
-/*
- * Given an nvlist of properties to set, validates that they are correct, and
- * parses any numeric properties (index, boolean, etc) if they are specified as
- * strings.
- */
-nvlist_t *
-zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
- uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl,
- boolean_t key_params_ok, const char *errbuf)
-{
- nvpair_t *elem;
- uint64_t intval;
- const char *strval;
- zfs_prop_t prop;
- nvlist_t *ret;
- int chosen_normal = -1;
- int chosen_utf = -1;
-
- if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
- (void) no_memory(hdl);
- return (NULL);
- }
-
- /*
- * Make sure this property is valid and applies to this type.
- */
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
- const char *propname = nvpair_name(elem);
-
- prop = zfs_name_to_prop(propname);
- if (prop == ZPROP_USERPROP && zfs_prop_user(propname)) {
- /*
- * This is a user property: make sure it's a
- * string, and that it's less than ZAP_MAXNAMELEN.
- */
- if (nvpair_type(elem) != DATA_TYPE_STRING) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a string"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property name '%s' is too long"),
- propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- (void) nvpair_value_string(elem, &strval);
- if (nvlist_add_string(ret, propname, strval) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
- continue;
- }
-
- /*
- * Currently, only user properties can be modified on
- * snapshots.
- */
- if (type == ZFS_TYPE_SNAPSHOT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "this property can not be modified for snapshots"));
- (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
- goto error;
- }
-
- if (prop == ZPROP_USERPROP && zfs_prop_userquota(propname)) {
- zfs_userquota_prop_t uqtype;
- char *newpropname = NULL;
- char domain[128];
- uint64_t rid;
- uint64_t valary[3];
- int rc;
-
- if (userquota_propname_decode(propname, zoned,
- &uqtype, domain, sizeof (domain), &rid) != 0) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN,
- "'%s' has an invalid user/group name"),
- propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (uqtype != ZFS_PROP_USERQUOTA &&
- uqtype != ZFS_PROP_GROUPQUOTA &&
- uqtype != ZFS_PROP_USEROBJQUOTA &&
- uqtype != ZFS_PROP_GROUPOBJQUOTA &&
- uqtype != ZFS_PROP_PROJECTQUOTA &&
- uqtype != ZFS_PROP_PROJECTOBJQUOTA) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "'%s' is readonly"),
- propname);
- (void) zfs_error(hdl, EZFS_PROPREADONLY,
- errbuf);
- goto error;
- }
-
- if (nvpair_type(elem) == DATA_TYPE_STRING) {
- (void) nvpair_value_string(elem, &strval);
- if (strcmp(strval, "none") == 0) {
- intval = 0;
- } else if (zfs_nicestrtonum(hdl,
- strval, &intval) != 0) {
- (void) zfs_error(hdl,
- EZFS_BADPROP, errbuf);
- goto error;
- }
- } else if (nvpair_type(elem) ==
- DATA_TYPE_UINT64) {
- (void) nvpair_value_uint64(elem, &intval);
- if (intval == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "use 'none' to disable "
- "{user|group|project}quota"));
- goto error;
- }
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a number"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- /*
- * Encode the prop name as
- * userquota@<hex-rid>-domain, to make it easy
- * for the kernel to decode.
- */
- rc = asprintf(&newpropname, "%s%llx-%s",
- zfs_userquota_prop_prefixes[uqtype],
- (longlong_t)rid, domain);
- if (rc == -1 || newpropname == NULL) {
- (void) no_memory(hdl);
- goto error;
- }
-
- valary[0] = uqtype;
- valary[1] = rid;
- valary[2] = intval;
- if (nvlist_add_uint64_array(ret, newpropname,
- valary, 3) != 0) {
- free(newpropname);
- (void) no_memory(hdl);
- goto error;
- }
- free(newpropname);
- continue;
- } else if (prop == ZPROP_USERPROP &&
- zfs_prop_written(propname)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is readonly"),
- propname);
- (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
- goto error;
- }
-
- if (prop == ZPROP_INVAL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property '%s'"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (!zfs_prop_valid_for_type(prop, type, B_FALSE)) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "'%s' does not "
- "apply to datasets of this type"), propname);
- (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
- goto error;
- }
-
- if (zfs_prop_readonly(prop) &&
- !(zfs_prop_setonce(prop) && zhp == NULL) &&
- !(zfs_prop_encryption_key_param(prop) && key_params_ok)) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "'%s' is readonly"),
- propname);
- (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
- goto error;
- }
-
- if (zprop_parse_value(hdl, elem, prop, type, ret,
- &strval, &intval, errbuf) != 0)
- goto error;
-
- /*
- * Perform some additional checks for specific properties.
- */
- switch (prop) {
- case ZFS_PROP_VERSION:
- {
- int version;
-
- if (zhp == NULL)
- break;
- version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
- if (intval < version) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Can not downgrade; already at version %u"),
- version);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- }
-
- case ZFS_PROP_VOLBLOCKSIZE:
- case ZFS_PROP_RECORDSIZE:
- {
- int maxbs = SPA_MAXBLOCKSIZE;
- char buf[64];
-
- if (zpool_hdl != NULL) {
- maxbs = zpool_get_prop_int(zpool_hdl,
- ZPOOL_PROP_MAXBLOCKSIZE, NULL);
- }
- /*
- * The value must be a power of two between
- * SPA_MINBLOCKSIZE and maxbs.
- */
- if (intval < SPA_MINBLOCKSIZE ||
- intval > maxbs || !ISP2(intval)) {
- zfs_nicebytes(maxbs, buf, sizeof (buf));
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be power of 2 from 512B "
- "to %s"), propname, buf);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- }
-
- case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
- {
- int maxbs = SPA_MAXBLOCKSIZE;
- char buf[64];
-
- if (intval > SPA_MAXBLOCKSIZE) {
- zfs_nicebytes(maxbs, buf, sizeof (buf));
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid '%s' property: must be between "
- "zero and %s"),
- propname, buf);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- }
-
- case ZFS_PROP_MLSLABEL:
- {
-#ifdef HAVE_MLSLABEL
- /*
- * Verify the mlslabel string and convert to
- * internal hex label string.
- */
-
- m_label_t *new_sl;
- char *hex = NULL; /* internal label string */
-
- /* Default value is already OK. */
- if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
- break;
-
- /* Verify the label can be converted to binary form */
- if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
- (str_to_label(strval, &new_sl, MAC_LABEL,
- L_NO_CORRECTION, NULL) == -1)) {
- goto badlabel;
- }
-
- /* Now translate to hex internal label string */
- if (label_to_str(new_sl, &hex, M_INTERNAL,
- DEF_NAMES) != 0) {
- if (hex)
- free(hex);
- goto badlabel;
- }
- m_label_free(new_sl);
-
- /* If string is already in internal form, we're done. */
- if (strcmp(strval, hex) == 0) {
- free(hex);
- break;
- }
-
- /* Replace the label string with the internal form. */
- (void) nvlist_remove(ret, zfs_prop_to_name(prop),
- DATA_TYPE_STRING);
- fnvlist_add_string(ret, zfs_prop_to_name(prop), hex);
- free(hex);
-
- break;
-
-badlabel:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid mlslabel '%s'"), strval);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- m_label_free(new_sl); /* OK if null */
- goto error;
-#else
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "mlslabels are unsupported"));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
-#endif /* HAVE_MLSLABEL */
- }
-
- case ZFS_PROP_MOUNTPOINT:
- {
- namecheck_err_t why;
-
- if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
- strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
- break;
-
- if (mountpoint_namecheck(strval, &why)) {
- switch (why) {
- case NAME_ERR_LEADING_SLASH:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN,
- "'%s' must be an absolute path, "
- "'none', or 'legacy'"), propname);
- break;
- case NAME_ERR_TOOLONG:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN,
- "component of '%s' is too long"),
- propname);
- break;
-
- default:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN,
- "(%d) not defined"),
- why);
- break;
- }
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- zfs_fallthrough;
- }
-
- case ZFS_PROP_SHARESMB:
- case ZFS_PROP_SHARENFS:
- /*
- * For the mountpoint and sharenfs or sharesmb
- * properties, check if it can be set in a
- * global/non-global zone based on
- * the zoned property value:
- *
- * global zone non-global zone
- * --------------------------------------------------
- * zoned=on mountpoint (no) mountpoint (yes)
- * sharenfs (no) sharenfs (no)
- * sharesmb (no) sharesmb (no)
- *
- * zoned=off mountpoint (yes) N/A
- * sharenfs (yes)
- * sharesmb (yes)
- */
- if (zoned) {
- if (getzoneid() == GLOBAL_ZONEID) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' cannot be set on "
- "dataset in a non-global zone"),
- propname);
- (void) zfs_error(hdl, EZFS_ZONED,
- errbuf);
- goto error;
- } else if (prop == ZFS_PROP_SHARENFS ||
- prop == ZFS_PROP_SHARESMB) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' cannot be set in "
- "a non-global zone"), propname);
- (void) zfs_error(hdl, EZFS_ZONED,
- errbuf);
- goto error;
- }
- } else if (getzoneid() != GLOBAL_ZONEID) {
- /*
- * If zoned property is 'off', this must be in
- * a global zone. If not, something is wrong.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' cannot be set while dataset "
- "'zoned' property is set"), propname);
- (void) zfs_error(hdl, EZFS_ZONED, errbuf);
- goto error;
- }
-
- /*
- * At this point, it is legitimate to set the
- * property. Now we want to make sure that the
- * property value is valid if it is sharenfs.
- */
- if ((prop == ZFS_PROP_SHARENFS ||
- prop == ZFS_PROP_SHARESMB) &&
- strcmp(strval, "on") != 0 &&
- strcmp(strval, "off") != 0) {
- enum sa_protocol proto;
-
- if (prop == ZFS_PROP_SHARESMB)
- proto = SA_PROTOCOL_SMB;
- else
- proto = SA_PROTOCOL_NFS;
-
- if (sa_validate_shareopts(strval, proto) !=
- SA_OK) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' cannot be set to invalid "
- "options"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
- }
-
- break;
-
- case ZFS_PROP_KEYLOCATION:
- if (!zfs_prop_valid_keylocation(strval, B_FALSE)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid keylocation"));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (zhp != NULL) {
- uint64_t crypt =
- zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
-
- if (crypt == ZIO_CRYPT_OFF &&
- strcmp(strval, "none") != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "keylocation must be 'none' "
- "for unencrypted datasets"));
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- } else if (crypt != ZIO_CRYPT_OFF &&
- strcmp(strval, "none") == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "keylocation must not be 'none' "
- "for encrypted datasets"));
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
- }
- break;
-
- case ZFS_PROP_PBKDF2_ITERS:
- if (intval < MIN_PBKDF2_ITERATIONS) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "minimum pbkdf2 iterations is %u"),
- MIN_PBKDF2_ITERATIONS);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
-
- case ZFS_PROP_UTF8ONLY:
- chosen_utf = (int)intval;
- break;
-
- case ZFS_PROP_NORMALIZE:
- chosen_normal = (int)intval;
- break;
-
- default:
- break;
- }
-
- /*
- * For changes to existing volumes, we have some additional
- * checks to enforce.
- */
- if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
- uint64_t blocksize = zfs_prop_get_int(zhp,
- ZFS_PROP_VOLBLOCKSIZE);
- char buf[64];
-
- switch (prop) {
- case ZFS_PROP_VOLSIZE:
- if (intval % blocksize != 0) {
- zfs_nicebytes(blocksize, buf,
- sizeof (buf));
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a multiple of "
- "volume block size (%s)"),
- propname, buf);
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
-
- if (intval == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' cannot be zero"),
- propname);
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
- break;
-
- default:
- break;
- }
- }
-
- /* check encryption properties */
- if (zhp != NULL) {
- int64_t crypt = zfs_prop_get_int(zhp,
- ZFS_PROP_ENCRYPTION);
-
- switch (prop) {
- case ZFS_PROP_COPIES:
- if (crypt != ZIO_CRYPT_OFF && intval > 2) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encrypted datasets cannot have "
- "3 copies"));
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
- break;
- default:
- break;
- }
- }
- }
-
- /*
- * If normalization was chosen, but no UTF8 choice was made,
- * enforce rejection of non-UTF8 names.
- *
- * If normalization was chosen, but rejecting non-UTF8 names
- * was explicitly not chosen, it is an error.
- *
- * If utf8only was turned off, but the parent has normalization,
- * turn off normalization.
- */
- if (chosen_normal > 0 && chosen_utf < 0) {
- if (nvlist_add_uint64(ret,
- zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
- } else if (chosen_normal > 0 && chosen_utf == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be set 'on' if normalization chosen"),
- zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- } else if (chosen_normal < 0 && chosen_utf == 0) {
- if (nvlist_add_uint64(ret,
- zfs_prop_to_name(ZFS_PROP_NORMALIZE), 0) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
- }
- return (ret);
-
-error:
- nvlist_free(ret);
- return (NULL);
-}
-
-static int
-zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
-{
- uint64_t old_volsize;
- uint64_t new_volsize;
- uint64_t old_reservation;
- uint64_t new_reservation;
- zfs_prop_t resv_prop;
- nvlist_t *props;
- zpool_handle_t *zph = zpool_handle(zhp);
-
- /*
- * If this is an existing volume, and someone is setting the volsize,
- * make sure that it matches the reservation, or add it if necessary.
- */
- old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
- if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
- return (-1);
- old_reservation = zfs_prop_get_int(zhp, resv_prop);
-
- props = fnvlist_alloc();
- fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
- zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
-
- if ((zvol_volsize_to_reservation(zph, old_volsize, props) !=
- old_reservation) || nvlist_exists(nvl,
- zfs_prop_to_name(resv_prop))) {
- fnvlist_free(props);
- return (0);
- }
- if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
- &new_volsize) != 0) {
- fnvlist_free(props);
- return (-1);
- }
- new_reservation = zvol_volsize_to_reservation(zph, new_volsize, props);
- fnvlist_free(props);
-
- if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
- new_reservation) != 0) {
- (void) no_memory(zhp->zfs_hdl);
- return (-1);
- }
- return (1);
-}
-
-/*
- * Helper for 'zfs {set|clone} refreservation=auto'. Must be called after
- * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinel value.
- * Return codes must match zfs_add_synthetic_resv().
- */
-static int
-zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
-{
- uint64_t volsize;
- uint64_t resvsize;
- zfs_prop_t prop;
- nvlist_t *props;
-
- if (!ZFS_IS_VOLUME(zhp)) {
- return (0);
- }
-
- if (zfs_which_resv_prop(zhp, &prop) != 0) {
- return (-1);
- }
-
- if (prop != ZFS_PROP_REFRESERVATION) {
- return (0);
- }
-
- if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
- /* No value being set, so it can't be "auto" */
- return (0);
- }
- if (resvsize != UINT64_MAX) {
- /* Being set to a value other than "auto" */
- return (0);
- }
-
- props = fnvlist_alloc();
-
- fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
- zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
-
- if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
- &volsize) != 0) {
- volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
- }
-
- resvsize = zvol_volsize_to_reservation(zpool_handle(zhp), volsize,
- props);
- fnvlist_free(props);
-
- (void) nvlist_remove_all(nvl, zfs_prop_to_name(prop));
- if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
- (void) no_memory(zhp->zfs_hdl);
- return (-1);
- }
- return (1);
-}
-
-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);
- }
-}
-
-/*
- * Given a property name and value, set the property for the given dataset.
- */
-int
-zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
-{
- int ret = -1;
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvlist_t *nvl = NULL;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
- zhp->zfs_name);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
- nvlist_add_string(nvl, propname, propval) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
-
- ret = zfs_prop_set_list(zhp, nvl);
-
-error:
- nvlist_free(nvl);
- return (ret);
-}
-
-/*
- * Given an nvlist of property names and values, set the properties for the
- * given dataset.
- */
-int
-zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
-{
- return (zfs_prop_set_list_flags(zhp, props, 0));
-}
-
-/*
- * Given an nvlist of property names, values and flags, set the properties
- * for the given dataset. If ZFS_SET_NOMOUNT is set, it allows to update
- * mountpoint, sharenfs and sharesmb properties without (un/re)mounting
- * and (un/re)sharing the dataset.
- */
-int
-zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
-{
- zfs_cmd_t zc = {"\0"};
- int ret = -1;
- prop_changelist_t **cls = NULL;
- int cl_idx;
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvlist_t *nvl;
- int nvl_len = 0;
- int added_resv = 0;
- zfs_prop_t prop;
- boolean_t nsprop = B_FALSE;
- nvpair_t *elem;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
- zhp->zfs_name);
-
- if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl,
- B_FALSE, errbuf)) == NULL)
- goto error;
-
- /*
- * We have to check for any extra properties which need to be added
- * before computing the length of the nvlist.
- */
- for (elem = nvlist_next_nvpair(nvl, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(nvl, elem)) {
- if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
- (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
- goto error;
- }
- }
-
- if (added_resv != 1 &&
- (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
- goto error;
- }
-
- /*
- * Check how many properties we're setting and allocate an array to
- * store changelist pointers for postfix().
- */
- for (elem = nvlist_next_nvpair(nvl, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(nvl, elem))
- nvl_len++;
- if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
- goto error;
-
- cl_idx = 0;
- for (elem = nvlist_next_nvpair(nvl, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(nvl, elem)) {
-
- prop = zfs_name_to_prop(nvpair_name(elem));
- nsprop |= zfs_is_namespace_prop(prop);
-
- assert(cl_idx < nvl_len);
- /*
- * We don't want to unmount & remount the dataset when changing
- * its canmount property to 'on' or 'noauto'. We only use
- * the changelist logic to unmount when setting canmount=off.
- */
- if (prop != ZFS_PROP_CANMOUNT ||
- (fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
- zfs_is_mounted(zhp, NULL))) {
- cls[cl_idx] = changelist_gather(zhp, prop,
- ((flags & ZFS_SET_NOMOUNT) ?
- CL_GATHER_DONT_UNMOUNT : 0), 0);
- if (cls[cl_idx] == NULL)
- goto error;
- }
-
- if (prop == ZFS_PROP_MOUNTPOINT &&
- changelist_haszonedchild(cls[cl_idx])) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "child dataset with inherited mountpoint is used "
- "in a non-global zone"));
- ret = zfs_error(hdl, EZFS_ZONED, errbuf);
- goto error;
- }
-
- if (cls[cl_idx] != NULL &&
- (ret = changelist_prefix(cls[cl_idx])) != 0)
- goto error;
-
- cl_idx++;
- }
- assert(cl_idx == nvl_len);
-
- /*
- * Execute the corresponding ioctl() to set this list of properties.
- */
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- zcmd_write_src_nvlist(hdl, &zc, nvl);
- zcmd_alloc_dst_nvlist(hdl, &zc, 0);
-
- ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
-
- if (ret != 0) {
- if (zc.zc_nvlist_dst_filled == B_FALSE) {
- (void) zfs_standard_error(hdl, errno, errbuf);
- goto error;
- }
-
- /* Get the list of unset properties back and report them. */
- nvlist_t *errorprops = NULL;
- if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
- goto error;
- for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(errorprops, elem)) {
- prop = zfs_name_to_prop(nvpair_name(elem));
- zfs_setprop_error(hdl, prop, errno, errbuf);
- }
- nvlist_free(errorprops);
-
- if (added_resv && errno == ENOSPC) {
- /* clean up the volsize property we tried to set */
- uint64_t old_volsize = zfs_prop_get_int(zhp,
- ZFS_PROP_VOLSIZE);
- nvlist_free(nvl);
- nvl = NULL;
- zcmd_free_nvlists(&zc);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- goto error;
- if (nvlist_add_uint64(nvl,
- zfs_prop_to_name(ZFS_PROP_VOLSIZE),
- old_volsize) != 0)
- goto error;
- zcmd_write_src_nvlist(hdl, &zc, nvl);
- (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
- }
- } else {
- for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
- if (cls[cl_idx] != NULL) {
- int clp_err = changelist_postfix(cls[cl_idx]);
- if (clp_err != 0)
- ret = clp_err;
- }
- }
-
- if (ret == 0) {
- /*
- * Refresh the statistics so the new property
- * value is reflected.
- */
- (void) get_stats(zhp);
-
- /*
- * Remount the filesystem to propagate the change
- * if one of the options handled by the generic
- * Linux namespace layer has been modified.
- */
- if (nsprop && zfs_is_mounted(zhp, NULL))
- ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
- }
- }
-
-error:
- nvlist_free(nvl);
- zcmd_free_nvlists(&zc);
- if (cls != NULL) {
- for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
- if (cls[cl_idx] != NULL)
- changelist_free(cls[cl_idx]);
- }
- free(cls);
- }
- return (ret);
-}
-
-/*
- * Given a property, inherit the value from the parent dataset, or if received
- * is TRUE, revert to the received value, if any.
- */
-int
-zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
-{
- zfs_cmd_t zc = {"\0"};
- int ret;
- prop_changelist_t *cl;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char errbuf[ERRBUFLEN];
- zfs_prop_t prop;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
-
- zc.zc_cookie = received;
- if ((prop = zfs_name_to_prop(propname)) == ZPROP_USERPROP) {
- /*
- * For user properties, the amount of work we have to do is very
- * small, so just do it here.
- */
- if (!zfs_prop_user(propname)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
-
- 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);
- }
-
- /*
- * Verify that this property is inheritable.
- */
- if (zfs_prop_readonly(prop))
- return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
-
- if (!zfs_prop_inheritable(prop) && !received)
- return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
-
- /*
- * Check to see if the value applies to this type
- */
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
- return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
-
- /*
- * Normalize the name, to get rid of shorthand abbreviations.
- */
- propname = zfs_prop_to_name(prop);
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
-
- if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset is used in a non-global zone"));
- return (zfs_error(hdl, EZFS_ZONED, errbuf));
- }
-
- /*
- * Determine datasets which will be affected by this change, if any.
- */
- if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
- return (-1);
-
- if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "child dataset with inherited mountpoint is used "
- "in a non-global zone"));
- ret = zfs_error(hdl, EZFS_ZONED, errbuf);
- goto error;
- }
-
- if ((ret = changelist_prefix(cl)) != 0)
- goto error;
-
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) {
- changelist_free(cl);
- return (zfs_standard_error(hdl, errno, errbuf));
- } else {
-
- if ((ret = changelist_postfix(cl)) != 0)
- goto error;
-
- /*
- * Refresh the statistics so the new property is reflected.
- */
- (void) get_stats(zhp);
-
- /*
- * Remount the filesystem to propagate the change
- * if one of the options handled by the generic
- * Linux namespace layer has been modified.
- */
- if (zfs_is_namespace_prop(prop) &&
- zfs_is_mounted(zhp, NULL))
- ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
- }
-
-error:
- changelist_free(cl);
- return (ret);
-}
-
-/*
- * True DSL properties are stored in an nvlist. The following two functions
- * extract them appropriately.
- */
-uint64_t
-getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, const char **source)
-{
- nvlist_t *nv;
- uint64_t value;
-
- *source = NULL;
- if (nvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(prop), &nv) == 0) {
- value = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
- (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
- } else {
- verify(!zhp->zfs_props_table ||
- zhp->zfs_props_table[prop] == B_TRUE);
- value = zfs_prop_default_numeric(prop);
- *source = "";
- }
-
- return (value);
-}
-
-static const char *
-getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, const char **source)
-{
- nvlist_t *nv;
- const char *value;
-
- *source = NULL;
- if (nvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(prop), &nv) == 0) {
- value = fnvlist_lookup_string(nv, ZPROP_VALUE);
- (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
- } else {
- verify(!zhp->zfs_props_table ||
- zhp->zfs_props_table[prop] == B_TRUE);
- value = zfs_prop_default_string(prop);
- *source = "";
- }
-
- return (value);
-}
-
-static boolean_t
-zfs_is_recvd_props_mode(zfs_handle_t *zhp)
-{
- return (zhp->zfs_props != NULL &&
- zhp->zfs_props == zhp->zfs_recvd_props);
-}
-
-static void
-zfs_set_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
-{
- *cookie = (uintptr_t)zhp->zfs_props;
- zhp->zfs_props = zhp->zfs_recvd_props;
-}
-
-static void
-zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
-{
- zhp->zfs_props = (nvlist_t *)*cookie;
- *cookie = 0;
-}
-
-/*
- * Internal function for getting a numeric property. Both zfs_prop_get() and
- * zfs_prop_get_int() are built using this interface.
- *
- * Certain properties can be overridden using 'mount -o'. In this case, scan
- * the contents of the /proc/self/mounts entry, searching for the
- * appropriate options. If they differ from the on-disk values, report the
- * current values and mark the source "temporary".
- */
-static int
-get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
- const char **source, uint64_t *val)
-{
- zfs_cmd_t zc = {"\0"};
- nvlist_t *zplprops = NULL;
- struct mnttab mnt;
- const char *mntopt_on = NULL;
- const char *mntopt_off = NULL;
- boolean_t received = zfs_is_recvd_props_mode(zhp);
-
- *source = NULL;
-
- /*
- * If the property is being fetched for a snapshot, check whether
- * the property is valid for the snapshot's head dataset type.
- */
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT &&
- !zfs_prop_valid_for_type(prop, zhp->zfs_head_type, B_TRUE)) {
- *val = zfs_prop_default_numeric(prop);
- return (-1);
- }
-
- switch (prop) {
- case ZFS_PROP_ATIME:
- mntopt_on = MNTOPT_ATIME;
- mntopt_off = MNTOPT_NOATIME;
- break;
-
- case ZFS_PROP_RELATIME:
- mntopt_on = MNTOPT_RELATIME;
- mntopt_off = MNTOPT_NORELATIME;
- break;
-
- case ZFS_PROP_DEVICES:
- mntopt_on = MNTOPT_DEVICES;
- mntopt_off = MNTOPT_NODEVICES;
- break;
-
- case ZFS_PROP_EXEC:
- mntopt_on = MNTOPT_EXEC;
- mntopt_off = MNTOPT_NOEXEC;
- break;
-
- case ZFS_PROP_READONLY:
- mntopt_on = MNTOPT_RO;
- mntopt_off = MNTOPT_RW;
- break;
-
- case ZFS_PROP_SETUID:
- mntopt_on = MNTOPT_SETUID;
- mntopt_off = MNTOPT_NOSETUID;
- break;
-
- case ZFS_PROP_XATTR:
- mntopt_on = MNTOPT_XATTR;
- mntopt_off = MNTOPT_NOXATTR;
- break;
-
- case ZFS_PROP_NBMAND:
- mntopt_on = MNTOPT_NBMAND;
- mntopt_off = MNTOPT_NONBMAND;
- break;
-
- default:
- break;
- }
-
- /*
- * Because looking up the mount options is potentially expensive
- * (iterating over all of /proc/self/mounts), we defer its
- * calculation until we're looking up a property which requires
- * its presence.
- */
- if (!zhp->zfs_mntcheck &&
- (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- struct mnttab entry;
-
- if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)
- zhp->zfs_mntopts = zfs_strdup(hdl,
- entry.mnt_mntopts);
-
- zhp->zfs_mntcheck = B_TRUE;
- }
-
- if (zhp->zfs_mntopts == NULL)
- mnt.mnt_mntopts = (char *)"";
- else
- mnt.mnt_mntopts = zhp->zfs_mntopts;
-
- switch (prop) {
- case ZFS_PROP_ATIME:
- case ZFS_PROP_RELATIME:
- case ZFS_PROP_DEVICES:
- case ZFS_PROP_EXEC:
- case ZFS_PROP_READONLY:
- case ZFS_PROP_SETUID:
-#ifndef __FreeBSD__
- case ZFS_PROP_XATTR:
-#endif
- case ZFS_PROP_NBMAND:
- *val = getprop_uint64(zhp, prop, source);
-
- if (received)
- break;
-
- if (hasmntopt(&mnt, mntopt_on) && !*val) {
- *val = B_TRUE;
- if (src)
- *src = ZPROP_SRC_TEMPORARY;
- } else if (hasmntopt(&mnt, mntopt_off) && *val) {
- *val = B_FALSE;
- if (src)
- *src = ZPROP_SRC_TEMPORARY;
- }
- break;
-
- case ZFS_PROP_CANMOUNT:
- case ZFS_PROP_VOLSIZE:
- case ZFS_PROP_QUOTA:
- case ZFS_PROP_REFQUOTA:
- case ZFS_PROP_RESERVATION:
- case ZFS_PROP_REFRESERVATION:
- case ZFS_PROP_FILESYSTEM_LIMIT:
- case ZFS_PROP_SNAPSHOT_LIMIT:
- case ZFS_PROP_FILESYSTEM_COUNT:
- case ZFS_PROP_SNAPSHOT_COUNT:
- *val = getprop_uint64(zhp, prop, source);
-
- if (*source == NULL) {
- /* not default, must be local */
- *source = zhp->zfs_name;
- }
- break;
-
- case ZFS_PROP_MOUNTED:
- *val = (zhp->zfs_mntopts != NULL);
- break;
-
- case ZFS_PROP_NUMCLONES:
- *val = zhp->zfs_dmustats.dds_num_clones;
- break;
-
- case ZFS_PROP_VERSION:
- case ZFS_PROP_NORMALIZE:
- case ZFS_PROP_UTF8ONLY:
- case ZFS_PROP_CASE:
- case ZFS_PROP_DEFAULTUSERQUOTA:
- case ZFS_PROP_DEFAULTGROUPQUOTA:
- case ZFS_PROP_DEFAULTPROJECTQUOTA:
- case ZFS_PROP_DEFAULTUSEROBJQUOTA:
- case ZFS_PROP_DEFAULTGROUPOBJQUOTA:
- case ZFS_PROP_DEFAULTPROJECTOBJQUOTA:
- zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
- zcmd_free_nvlists(&zc);
- if (prop == ZFS_PROP_VERSION &&
- zhp->zfs_type == ZFS_TYPE_VOLUME)
- *val = zfs_prop_default_numeric(prop);
- return (-1);
- }
- if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
- nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
- val) != 0) {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
- nvlist_free(zplprops);
- zcmd_free_nvlists(&zc);
- break;
-
- case ZFS_PROP_INCONSISTENT:
- *val = zhp->zfs_dmustats.dds_inconsistent;
- break;
-
- case ZFS_PROP_REDACTED:
- *val = zhp->zfs_dmustats.dds_redacted;
- break;
-
- case ZFS_PROP_GUID:
- if (zhp->zfs_dmustats.dds_guid != 0)
- *val = zhp->zfs_dmustats.dds_guid;
- else
- *val = getprop_uint64(zhp, prop, source);
- break;
-
- case ZFS_PROP_CREATETXG:
- /*
- * We can directly read createtxg property from zfs
- * handle for Filesystem, Snapshot and ZVOL types.
- */
- if (((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) ||
- (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) ||
- (zhp->zfs_type == ZFS_TYPE_VOLUME)) &&
- (zhp->zfs_dmustats.dds_creation_txg != 0)) {
- *val = zhp->zfs_dmustats.dds_creation_txg;
- break;
- } else {
- *val = getprop_uint64(zhp, prop, source);
- }
- zfs_fallthrough;
- default:
- switch (zfs_prop_get_type(prop)) {
- case PROP_TYPE_NUMBER:
- case PROP_TYPE_INDEX:
- *val = getprop_uint64(zhp, prop, source);
- /*
- * If we tried to use a default value for a
- * readonly property, it means that it was not
- * present. Note this only applies to "truly"
- * readonly properties, not set-once properties
- * like volblocksize.
- */
- if (zfs_prop_readonly(prop) &&
- !zfs_prop_setonce(prop) &&
- *source != NULL && (*source)[0] == '\0') {
- *source = NULL;
- return (-1);
- }
- break;
-
- case PROP_TYPE_STRING:
- default:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "cannot get non-numeric property"));
- return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
- dgettext(TEXT_DOMAIN, "internal error")));
- }
- }
-
- return (0);
-}
-
-/*
- * Calculate the source type, given the raw source string.
- */
-static void
-get_source(zfs_handle_t *zhp, zprop_source_t *srctype, const char *source,
- char *statbuf, size_t statlen)
-{
- if (statbuf == NULL ||
- srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) {
- return;
- }
-
- if (source == NULL) {
- *srctype = ZPROP_SRC_NONE;
- } else if (source[0] == '\0') {
- *srctype = ZPROP_SRC_DEFAULT;
- } else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
- *srctype = ZPROP_SRC_RECEIVED;
- } else {
- if (strcmp(source, zhp->zfs_name) == 0) {
- *srctype = ZPROP_SRC_LOCAL;
- } else {
- (void) strlcpy(statbuf, source, statlen);
- *srctype = ZPROP_SRC_INHERITED;
- }
- }
-
-}
-
-int
-zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
- size_t proplen, boolean_t literal)
-{
- zfs_prop_t prop;
- int err = 0;
-
- if (zhp->zfs_recvd_props == NULL)
- if (get_recvd_props_ioctl(zhp) != 0)
- return (-1);
-
- prop = zfs_name_to_prop(propname);
-
- if (prop != ZPROP_USERPROP) {
- uintptr_t cookie;
- if (!nvlist_exists(zhp->zfs_recvd_props, propname))
- return (-1);
- zfs_set_recvd_props_mode(zhp, &cookie);
- err = zfs_prop_get(zhp, prop, propbuf, proplen,
- NULL, NULL, 0, literal);
- zfs_unset_recvd_props_mode(zhp, &cookie);
- } else {
- nvlist_t *propval;
- const char *recvdval;
- if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
- propname, &propval) != 0)
- return (-1);
- recvdval = fnvlist_lookup_string(propval, ZPROP_VALUE);
- (void) strlcpy(propbuf, recvdval, proplen);
- }
-
- return (err == 0 ? 0 : -1);
-}
-
-static int
-get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
-{
- nvlist_t *value;
- nvpair_t *pair;
-
- value = zfs_get_clones_nvl(zhp);
- if (value == NULL || nvlist_empty(value))
- return (-1);
-
- propbuf[0] = '\0';
- for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
- pair = nvlist_next_nvpair(value, pair)) {
- if (propbuf[0] != '\0')
- (void) strlcat(propbuf, ",", proplen);
- (void) strlcat(propbuf, nvpair_name(pair), proplen);
- }
-
- return (0);
-}
-
-struct get_clones_arg {
- uint64_t numclones;
- nvlist_t *value;
- const char *origin;
- char buf[ZFS_MAX_DATASET_NAME_LEN];
-};
-
-static int
-get_clones_cb(zfs_handle_t *zhp, void *arg)
-{
- struct get_clones_arg *gca = arg;
-
- if (gca->numclones == 0) {
- zfs_close(zhp);
- return (0);
- }
-
- if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
- NULL, NULL, 0, B_TRUE) != 0)
- goto out;
- if (strcmp(gca->buf, gca->origin) == 0) {
- fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
- gca->numclones--;
- }
-
-out:
- (void) zfs_iter_children_v2(zhp, 0, get_clones_cb, gca);
- zfs_close(zhp);
- return (0);
-}
-
-nvlist_t *
-zfs_get_clones_nvl(zfs_handle_t *zhp)
-{
- nvlist_t *nv, *value;
-
- if (nvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
- struct get_clones_arg gca;
-
- /*
- * if this is a snapshot, then the kernel wasn't able
- * to get the clones. Do it by slowly iterating.
- */
- if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
- return (NULL);
- if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
- return (NULL);
- if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
- nvlist_free(nv);
- return (NULL);
- }
-
- gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
- gca.value = value;
- gca.origin = zhp->zfs_name;
-
- if (gca.numclones != 0) {
- zfs_handle_t *root;
- char pool[ZFS_MAX_DATASET_NAME_LEN];
- char *cp = pool;
-
- /* get the pool name */
- (void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
- (void) strsep(&cp, "/@");
- root = zfs_open(zhp->zfs_hdl, pool,
- ZFS_TYPE_FILESYSTEM);
- if (root == NULL) {
- nvlist_free(nv);
- nvlist_free(value);
- return (NULL);
- }
-
- (void) get_clones_cb(root, &gca);
- }
-
- if (gca.numclones != 0 ||
- nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
- nvlist_add_nvlist(zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
- nvlist_free(nv);
- nvlist_free(value);
- return (NULL);
- }
- nvlist_free(nv);
- nvlist_free(value);
- nv = fnvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_CLONES));
- }
-
- return (fnvlist_lookup_nvlist(nv, ZPROP_VALUE));
-}
-
-static int
-get_rsnaps_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
-{
- nvlist_t *value;
- uint64_t *snaps;
- uint_t nsnaps;
-
- if (nvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &value) != 0)
- return (-1);
- if (nvlist_lookup_uint64_array(value, ZPROP_VALUE, &snaps,
- &nsnaps) != 0)
- return (-1);
- if (nsnaps == 0) {
- /* There's no redaction snapshots; pass a special value back */
- (void) snprintf(propbuf, proplen, "none");
- return (0);
- }
- propbuf[0] = '\0';
- for (int i = 0; i < nsnaps; i++) {
- char buf[128];
- if (propbuf[0] != '\0')
- (void) strlcat(propbuf, ",", proplen);
- (void) snprintf(buf, sizeof (buf), "%llu",
- (u_longlong_t)snaps[i]);
- (void) strlcat(propbuf, buf, proplen);
- }
-
- return (0);
-}
-
-/*
- * Accepts a property and value and checks that the value
- * matches the one found by the channel program. If they are
- * not equal, print both of them.
- */
-static void
-zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
- const char *strval)
-{
- if (!zhp->zfs_hdl->libzfs_prop_debug)
- return;
- int error;
- char *poolname = zhp->zpool_hdl->zpool_name;
- const char *prop_name = zfs_prop_to_name(prop);
- const char *program =
- "args = ...\n"
- "ds = args['dataset']\n"
- "prop = args['property']\n"
- "value, setpoint = zfs.get_prop(ds, prop)\n"
- "return {value=value, setpoint=setpoint}\n";
- nvlist_t *outnvl;
- nvlist_t *retnvl;
- nvlist_t *argnvl = fnvlist_alloc();
-
- fnvlist_add_string(argnvl, "dataset", zhp->zfs_name);
- fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop));
-
- error = lzc_channel_program_nosync(poolname, program,
- 10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl);
-
- if (error == 0) {
- retnvl = fnvlist_lookup_nvlist(outnvl, "return");
- if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) {
- int64_t ans;
- error = nvlist_lookup_int64(retnvl, "value", &ans);
- if (error != 0) {
- (void) fprintf(stderr, "%s: zcp check error: "
- "%u\n", prop_name, error);
- return;
- }
- if (ans != intval) {
- (void) fprintf(stderr, "%s: zfs found %llu, "
- "but zcp found %llu\n", prop_name,
- (u_longlong_t)intval, (u_longlong_t)ans);
- }
- } else {
- const char *str_ans;
- error = nvlist_lookup_string(retnvl, "value", &str_ans);
- if (error != 0) {
- (void) fprintf(stderr, "%s: zcp check error: "
- "%u\n", prop_name, error);
- return;
- }
- if (strcmp(strval, str_ans) != 0) {
- (void) fprintf(stderr,
- "%s: zfs found '%s', but zcp found '%s'\n",
- prop_name, strval, str_ans);
- }
- }
- } else {
- (void) fprintf(stderr, "%s: zcp check failed, channel program "
- "error: %u\n", prop_name, error);
- }
- nvlist_free(argnvl);
- nvlist_free(outnvl);
-}
-
-/*
- * Retrieve a property from the given object. If 'literal' is specified, then
- * numbers are left as exact values. Otherwise, numbers are converted to a
- * human-readable form.
- *
- * Returns 0 on success, or -1 on error.
- */
-int
-zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
- zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
-{
- const char *source = NULL;
- uint64_t val;
- const char *str;
- const char *strval;
- boolean_t received = zfs_is_recvd_props_mode(zhp);
-
- /*
- * Check to see if this property applies to our object
- */
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
- return (-1);
-
- if (received && zfs_prop_readonly(prop))
- return (-1);
-
- if (src)
- *src = ZPROP_SRC_NONE;
-
- switch (prop) {
- case ZFS_PROP_CREATION:
- /*
- * 'creation' is a time_t stored in the statistics. We convert
- * this into a string unless 'literal' is specified.
- */
- {
- val = getprop_uint64(zhp, prop, &source);
- time_t time = (time_t)val;
- struct tm t;
-
- if (literal ||
- localtime_r(&time, &t) == NULL ||
- strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
- &t) == 0)
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- }
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_MOUNTPOINT:
- /*
- * Getting the precise mountpoint can be tricky.
- *
- * - for 'none' or 'legacy', return those values.
- * - for inherited mountpoints, we want to take everything
- * after our ancestor and append it to the inherited value.
- *
- * If the pool has an alternate root, we want to prepend that
- * root to any values we return.
- */
-
- str = getprop_string(zhp, prop, &source);
-
- if (str[0] == '/') {
- char buf[MAXPATHLEN];
- char *root = buf;
- const char *relpath;
-
- /*
- * If we inherit the mountpoint, even from a dataset
- * with a received value, the source will be the path of
- * the dataset we inherit from. If source is
- * ZPROP_SOURCE_VAL_RECVD, the received value is not
- * inherited.
- */
- if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
- relpath = "";
- } else {
- relpath = zhp->zfs_name + strlen(source);
- if (relpath[0] == '/')
- relpath++;
- }
-
- if ((zpool_get_prop(zhp->zpool_hdl,
- ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL,
- B_FALSE)) || (strcmp(root, "-") == 0))
- root[0] = '\0';
- /*
- * Special case an alternate root of '/'. This will
- * avoid having multiple leading slashes in the
- * mountpoint path.
- */
- if (strcmp(root, "/") == 0)
- root++;
-
- /*
- * If the mountpoint is '/' then skip over this
- * if we are obtaining either an alternate root or
- * an inherited mountpoint.
- */
- if (str[1] == '\0' && (root[0] != '\0' ||
- relpath[0] != '\0'))
- str++;
-
- if (relpath[0] == '\0')
- (void) snprintf(propbuf, proplen, "%s%s",
- root, str);
- else
- (void) snprintf(propbuf, proplen, "%s%s%s%s",
- root, str, relpath[0] == '@' ? "" : "/",
- relpath);
- } else {
- /* 'legacy' or 'none' */
- (void) strlcpy(propbuf, str, proplen);
- }
- zcp_check(zhp, prop, 0, propbuf);
- break;
-
- case ZFS_PROP_ORIGIN:
- if (*zhp->zfs_dmustats.dds_origin != '\0') {
- str = (char *)&zhp->zfs_dmustats.dds_origin;
- } else {
- str = getprop_string(zhp, prop, &source);
- }
- if (str == NULL || *str == '\0')
- str = zfs_prop_default_string(prop);
- if (str == NULL)
- return (-1);
- (void) strlcpy(propbuf, str, proplen);
- zcp_check(zhp, prop, 0, str);
- break;
-
- case ZFS_PROP_REDACT_SNAPS:
- if (get_rsnaps_string(zhp, propbuf, proplen) != 0)
- return (-1);
- break;
-
- case ZFS_PROP_CLONES:
- if (get_clones_string(zhp, propbuf, proplen) != 0)
- return (-1);
- break;
-
- case ZFS_PROP_QUOTA:
- case ZFS_PROP_REFQUOTA:
- case ZFS_PROP_RESERVATION:
- case ZFS_PROP_REFRESERVATION:
-
- if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
- return (-1);
- /*
- * If quota or reservation is 0, we translate this into 'none'
- * (unless literal is set), and indicate that it's the default
- * value. Otherwise, we print the number nicely and indicate
- * that its set locally.
- */
- if (val == 0) {
- if (literal)
- (void) strlcpy(propbuf, "0", proplen);
- else
- (void) strlcpy(propbuf, "none", proplen);
- } else {
- if (literal)
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- else
- zfs_nicebytes(val, propbuf, proplen);
- }
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_FILESYSTEM_LIMIT:
- case ZFS_PROP_SNAPSHOT_LIMIT:
- case ZFS_PROP_FILESYSTEM_COUNT:
- case ZFS_PROP_SNAPSHOT_COUNT:
-
- if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
- return (-1);
-
- /*
- * If limit is UINT64_MAX, we translate this into 'none', and
- * indicate that it's the default value. Otherwise, we print
- * the number nicely and indicate that it's set locally.
- */
- if (val == UINT64_MAX) {
- (void) strlcpy(propbuf, "none", proplen);
- } else if (literal) {
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- } else {
- zfs_nicenum(val, propbuf, proplen);
- }
-
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_REFRATIO:
- case ZFS_PROP_COMPRESSRATIO:
- if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
- return (-1);
- if (literal)
- (void) snprintf(propbuf, proplen, "%llu.%02llu",
- (u_longlong_t)(val / 100),
- (u_longlong_t)(val % 100));
- else
- (void) snprintf(propbuf, proplen, "%llu.%02llux",
- (u_longlong_t)(val / 100),
- (u_longlong_t)(val % 100));
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_TYPE:
- switch (zhp->zfs_type) {
- case ZFS_TYPE_FILESYSTEM:
- str = "filesystem";
- break;
- case ZFS_TYPE_VOLUME:
- str = "volume";
- break;
- case ZFS_TYPE_SNAPSHOT:
- str = "snapshot";
- break;
- case ZFS_TYPE_BOOKMARK:
- str = "bookmark";
- break;
- default:
- abort();
- }
- (void) snprintf(propbuf, proplen, "%s", str);
- zcp_check(zhp, prop, 0, propbuf);
- break;
-
- case ZFS_PROP_MOUNTED:
- /*
- * The 'mounted' property is a pseudo-property that described
- * whether the filesystem is currently mounted. Even though
- * it's a boolean value, the typical values of "on" and "off"
- * don't make sense, so we translate to "yes" and "no".
- */
- if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
- src, &source, &val) != 0)
- return (-1);
- if (val)
- (void) strlcpy(propbuf, "yes", proplen);
- else
- (void) strlcpy(propbuf, "no", proplen);
- break;
-
- case ZFS_PROP_NAME:
- /*
- * The 'name' property is a pseudo-property derived from the
- * dataset name. It is presented as a real property to simplify
- * consumers.
- */
- (void) strlcpy(propbuf, zhp->zfs_name, proplen);
- zcp_check(zhp, prop, 0, propbuf);
- break;
-
- case ZFS_PROP_MLSLABEL:
- {
-#ifdef HAVE_MLSLABEL
- m_label_t *new_sl = NULL;
- char *ascii = NULL; /* human readable label */
-
- (void) strlcpy(propbuf,
- getprop_string(zhp, prop, &source), proplen);
-
- if (literal || (strcasecmp(propbuf,
- ZFS_MLSLABEL_DEFAULT) == 0))
- break;
-
- /*
- * Try to translate the internal hex string to
- * human-readable output. If there are any
- * problems just use the hex string.
- */
-
- if (str_to_label(propbuf, &new_sl, MAC_LABEL,
- L_NO_CORRECTION, NULL) == -1) {
- m_label_free(new_sl);
- break;
- }
-
- if (label_to_str(new_sl, &ascii, M_LABEL,
- DEF_NAMES) != 0) {
- if (ascii)
- free(ascii);
- m_label_free(new_sl);
- break;
- }
- m_label_free(new_sl);
-
- (void) strlcpy(propbuf, ascii, proplen);
- free(ascii);
-#else
- (void) strlcpy(propbuf,
- getprop_string(zhp, prop, &source), proplen);
-#endif /* HAVE_MLSLABEL */
- }
- break;
-
- case ZFS_PROP_GUID:
- case ZFS_PROP_KEY_GUID:
- case ZFS_PROP_IVSET_GUID:
- case ZFS_PROP_CREATETXG:
- case ZFS_PROP_OBJSETID:
- case ZFS_PROP_PBKDF2_ITERS:
- /*
- * These properties are stored as numbers, but they are
- * identifiers or counters.
- * We don't want them to be pretty printed, because pretty
- * printing truncates their values making them useless.
- */
- if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
- return (-1);
- (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_REFERENCED:
- case ZFS_PROP_AVAILABLE:
- case ZFS_PROP_USED:
- case ZFS_PROP_USEDSNAP:
- case ZFS_PROP_USEDDS:
- case ZFS_PROP_USEDREFRESERV:
- case ZFS_PROP_USEDCHILD:
- if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
- return (-1);
- if (literal) {
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- } else {
- zfs_nicebytes(val, propbuf, proplen);
- }
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case ZFS_PROP_SNAPSHOTS_CHANGED:
- {
- if ((get_numeric_property(zhp, prop, src, &source,
- &val) != 0) || val == 0) {
- return (-1);
- }
-
- time_t time = (time_t)val;
- struct tm t;
-
- if (literal ||
- localtime_r(&time, &t) == NULL ||
- strftime(propbuf, proplen, "%a %b %e %k:%M:%S %Y",
- &t) == 0)
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- }
- zcp_check(zhp, prop, val, NULL);
- break;
-
- default:
- switch (zfs_prop_get_type(prop)) {
- case PROP_TYPE_NUMBER:
- if (get_numeric_property(zhp, prop, src,
- &source, &val) != 0) {
- return (-1);
- }
-
- if (literal) {
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)val);
- } else {
- zfs_nicenum(val, propbuf, proplen);
- }
- zcp_check(zhp, prop, val, NULL);
- break;
-
- case PROP_TYPE_STRING:
- str = getprop_string(zhp, prop, &source);
- if (str == NULL)
- return (-1);
-
- (void) strlcpy(propbuf, str, proplen);
- zcp_check(zhp, prop, 0, str);
- break;
-
- case PROP_TYPE_INDEX:
- if (get_numeric_property(zhp, prop, src,
- &source, &val) != 0)
- return (-1);
- if (zfs_prop_index_to_string(prop, val, &strval) != 0)
- return (-1);
-
- (void) strlcpy(propbuf, strval, proplen);
- zcp_check(zhp, prop, 0, strval);
- break;
-
- default:
- abort();
- }
- }
-
- get_source(zhp, src, source, statbuf, statlen);
-
- return (0);
-}
-
-/*
- * Utility function to get the given numeric property. Does no validation that
- * the given property is the appropriate type; should only be used with
- * hard-coded property types.
- */
-uint64_t
-zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
-{
- const char *source;
- uint64_t val = 0;
-
- (void) get_numeric_property(zhp, prop, NULL, &source, &val);
-
- return (val);
-}
-
-static int
-zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
-{
- char buf[64];
-
- (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
- return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
-}
-
-/*
- * Similar to zfs_prop_get(), but returns the value as an integer.
- */
-int
-zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
- zprop_source_t *src, char *statbuf, size_t statlen)
-{
- const char *source;
-
- /*
- * Check to see if this property applies to our object
- */
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) {
- return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
- dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
- zfs_prop_to_name(prop)));
- }
-
- if (src)
- *src = ZPROP_SRC_NONE;
-
- if (get_numeric_property(zhp, prop, src, &source, value) != 0)
- return (-1);
-
- get_source(zhp, src, source, statbuf, statlen);
-
- return (0);
-}
-
-#ifdef HAVE_IDMAP
-static int
-idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
- char **domainp, idmap_rid_t *ridp)
-{
- idmap_get_handle_t *get_hdl = NULL;
- idmap_stat status;
- int err = EINVAL;
-
- if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
- goto out;
-
- if (isuser) {
- err = idmap_get_sidbyuid(get_hdl, id,
- IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
- } else {
- err = idmap_get_sidbygid(get_hdl, id,
- IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
- }
- if (err == IDMAP_SUCCESS &&
- idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
- status == IDMAP_SUCCESS)
- err = 0;
- else
- err = EINVAL;
-out:
- if (get_hdl)
- idmap_get_destroy(get_hdl);
- return (err);
-}
-#endif /* HAVE_IDMAP */
-
-/*
- * convert the propname into parameters needed by kernel
- * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
- * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
- * Eg: groupquota@staff -> ZFS_PROP_GROUPQUOTA, "", 1234
- * Eg: groupused@staff -> ZFS_PROP_GROUPUSED, "", 1234
- * Eg: projectquota@123 -> ZFS_PROP_PROJECTQUOTA, "", 123
- * Eg: projectused@789 -> ZFS_PROP_PROJECTUSED, "", 789
- */
-static int
-userquota_propname_decode(const char *propname, boolean_t zoned,
- zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
-{
- zfs_userquota_prop_t type;
- char *cp;
- boolean_t isuser;
- boolean_t isgroup;
- boolean_t isproject;
- struct passwd *pw;
- struct group *gr;
-
- domain[0] = '\0';
-
- /* Figure out the property type ({user|group|project}{quota|space}) */
- for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
- if (strncmp(propname, zfs_userquota_prop_prefixes[type],
- strlen(zfs_userquota_prop_prefixes[type])) == 0)
- break;
- }
- if (type == ZFS_NUM_USERQUOTA_PROPS)
- return (EINVAL);
- *typep = type;
-
- isuser = (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_USERUSED ||
- type == ZFS_PROP_USEROBJQUOTA ||
- type == ZFS_PROP_USEROBJUSED);
- isgroup = (type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_GROUPUSED ||
- type == ZFS_PROP_GROUPOBJQUOTA ||
- type == ZFS_PROP_GROUPOBJUSED);
- isproject = (type == ZFS_PROP_PROJECTQUOTA ||
- type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTOBJQUOTA ||
- type == ZFS_PROP_PROJECTOBJUSED);
-
- cp = strchr(propname, '@') + 1;
-
- if (isuser &&
- getpwnam_r(cp, &gpwd, rpbuf, sizeof (rpbuf), &pw) == 0 &&
- pw != NULL) {
- if (zoned && getzoneid() == GLOBAL_ZONEID)
- return (ENOENT);
- *ridp = pw->pw_uid;
- } else if (isgroup &&
- getgrnam_r(cp, &ggrp, rpbuf, sizeof (rpbuf), &gr) == 0 &&
- gr != NULL) {
- if (zoned && getzoneid() == GLOBAL_ZONEID)
- return (ENOENT);
- *ridp = gr->gr_gid;
- } else if (!isproject && strchr(cp, '@')) {
-#ifdef HAVE_IDMAP
- /*
- * It's a SID name (eg "user@domain") that needs to be
- * turned into S-1-domainID-RID.
- */
- directory_error_t e;
- char *numericsid = NULL;
- char *end;
-
- if (zoned && getzoneid() == GLOBAL_ZONEID)
- return (ENOENT);
- if (isuser) {
- e = directory_sid_from_user_name(NULL,
- cp, &numericsid);
- } else {
- e = directory_sid_from_group_name(NULL,
- cp, &numericsid);
- }
- if (e != NULL) {
- directory_error_free(e);
- return (ENOENT);
- }
- if (numericsid == NULL)
- return (ENOENT);
- cp = numericsid;
- (void) strlcpy(domain, cp, domainlen);
- cp = strrchr(domain, '-');
- *cp = '\0';
- cp++;
-
- errno = 0;
- *ridp = strtoull(cp, &end, 10);
- free(numericsid);
-
- if (errno != 0 || *end != '\0')
- return (EINVAL);
-#else
- (void) domainlen;
- return (ENOSYS);
-#endif /* HAVE_IDMAP */
- } else {
- /* It's a user/group/project ID (eg "12345"). */
- uid_t id;
- char *end;
- id = strtoul(cp, &end, 10);
- if (*end != '\0')
- return (EINVAL);
- if (id > MAXUID && !isproject) {
-#ifdef HAVE_IDMAP
- /* It's an ephemeral ID. */
- idmap_rid_t rid;
- char *mapdomain;
-
- if (idmap_id_to_numeric_domain_rid(id, isuser,
- &mapdomain, &rid) != 0)
- return (ENOENT);
- (void) strlcpy(domain, mapdomain, domainlen);
- *ridp = rid;
-#else
- return (ENOSYS);
-#endif /* HAVE_IDMAP */
- } else {
- *ridp = id;
- }
- }
-
- return (0);
-}
-
-static int
-zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
- uint64_t *propvalue, zfs_userquota_prop_t *typep)
-{
- int err;
- zfs_cmd_t zc = {"\0"};
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- err = userquota_propname_decode(propname,
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
- typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
- zc.zc_objset_type = *typep;
- if (err)
- return (err);
-
- err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_USERSPACE_ONE, &zc);
- if (err)
- return (err);
-
- *propvalue = zc.zc_cookie;
- return (0);
-}
-
-int
-zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
- uint64_t *propvalue)
-{
- zfs_userquota_prop_t type;
-
- return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
- &type));
-}
-
-int
-zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
- char *propbuf, int proplen, boolean_t literal)
-{
- int err;
- uint64_t propvalue;
- zfs_userquota_prop_t type;
-
- err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
- &type);
-
- if (err)
- return (err);
-
- if (literal) {
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)propvalue);
- } else if (propvalue == 0 &&
- (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
- type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA ||
- type == ZFS_PROP_PROJECTQUOTA ||
- type == ZFS_PROP_PROJECTOBJQUOTA)) {
- (void) strlcpy(propbuf, "none", proplen);
- } else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
- type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED ||
- type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTQUOTA) {
- zfs_nicebytes(propvalue, propbuf, proplen);
- } else {
- zfs_nicenum(propvalue, propbuf, proplen);
- }
- return (0);
-}
-
-/*
- * propname must start with "written@" or "written#".
- */
-int
-zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
- uint64_t *propvalue)
-{
- int err;
- zfs_cmd_t zc = {"\0"};
- const char *snapname;
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- assert(zfs_prop_written(propname));
- snapname = propname + strlen("written@");
- if (strchr(snapname, '@') != NULL || strchr(snapname, '#') != NULL) {
- /* full snapshot or bookmark name specified */
- (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
- } else {
- /* snapname is the short name, append it to zhp's fsname */
- char *cp;
-
- (void) strlcpy(zc.zc_value, zhp->zfs_name,
- sizeof (zc.zc_value));
- cp = strchr(zc.zc_value, '@');
- if (cp != NULL)
- *cp = '\0';
- (void) strlcat(zc.zc_value, snapname - 1, sizeof (zc.zc_value));
- }
-
- err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SPACE_WRITTEN, &zc);
- if (err)
- return (err);
-
- *propvalue = zc.zc_cookie;
- return (0);
-}
-
-int
-zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
- char *propbuf, int proplen, boolean_t literal)
-{
- int err;
- uint64_t propvalue;
-
- err = zfs_prop_get_written_int(zhp, propname, &propvalue);
-
- if (err)
- return (err);
-
- if (literal) {
- (void) snprintf(propbuf, proplen, "%llu",
- (u_longlong_t)propvalue);
- } else {
- zfs_nicebytes(propvalue, propbuf, proplen);
- }
-
- return (0);
-}
-
-/*
- * Returns the name of the given zfs handle.
- */
-const char *
-zfs_get_name(const zfs_handle_t *zhp)
-{
- return (zhp->zfs_name);
-}
-
-/*
- * Returns the name of the parent pool for the given zfs handle.
- */
-const char *
-zfs_get_pool_name(const zfs_handle_t *zhp)
-{
- return (zhp->zpool_hdl->zpool_name);
-}
-
-/*
- * Returns the type of the given zfs handle.
- */
-zfs_type_t
-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?
- *
- * Needs to handle these cases:
- * Dataset 1 "a/foo" "a/foo" "a/foo" "a/foo"
- * Dataset 2 "a/fo" "a/foobar" "a/bar/baz" "a/foo/bar"
- * Descendant? No. No. No. Yes.
- */
-static boolean_t
-is_descendant(const char *ds1, const char *ds2)
-{
- size_t d1len = strlen(ds1);
-
- /* ds2 can't be a descendant if it's smaller */
- if (strlen(ds2) < d1len)
- return (B_FALSE);
-
- /* otherwise, compare strings and verify that there's a '/' char */
- return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
-}
-
-/*
- * Given a complete name, return just the portion that refers to the parent.
- * Will return -1 if there is no parent (path is just the name of the
- * pool).
- */
-static int
-parent_name(const char *path, char *buf, size_t buflen)
-{
- char *slashp;
-
- (void) strlcpy(buf, path, buflen);
-
- if ((slashp = strrchr(buf, '/')) == NULL)
- return (-1);
- *slashp = '\0';
-
- return (0);
-}
-
-int
-zfs_parent_name(zfs_handle_t *zhp, char *buf, size_t buflen)
-{
- return (parent_name(zfs_get_name(zhp), buf, buflen));
-}
-
-/*
- * If accept_ancestor is false, then check to make sure that the given path has
- * a parent, and that it exists. If accept_ancestor is true, then find the
- * closest existing ancestor for the given path. In prefixlen return the
- * length of already existing prefix of the given path. We also fetch the
- * 'zoned' property, which is used to validate property settings when creating
- * new datasets.
- */
-static int
-check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
- boolean_t accept_ancestor, int *prefixlen)
-{
- zfs_cmd_t zc = {"\0"};
- char parent[ZFS_MAX_DATASET_NAME_LEN];
- char *slash;
- zfs_handle_t *zhp;
- char errbuf[ERRBUFLEN];
- uint64_t is_zoned;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
-
- /* get parent, and check to see if this is just a pool */
- if (parent_name(path, parent, sizeof (parent)) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "missing dataset name"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
-
- /* check to see if the pool exists */
- if ((slash = strchr(parent, '/')) == NULL)
- slash = parent + strlen(parent);
- (void) strlcpy(zc.zc_name, parent,
- MIN(sizeof (zc.zc_name), slash - parent + 1));
- if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
- errno == ENOENT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "no such pool '%s'"), zc.zc_name);
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
- }
-
- /* check to see if the parent dataset exists */
- while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
- if (errno == ENOENT && accept_ancestor) {
- /*
- * Go deeper to find an ancestor, give up on top level.
- */
- if (parent_name(parent, parent, sizeof (parent)) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "no such pool '%s'"), zc.zc_name);
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
- }
- } else if (errno == ENOENT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "parent does not exist"));
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
- } else
- return (zfs_standard_error(hdl, errno, errbuf));
- }
-
- is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
- if (zoned != NULL)
- *zoned = is_zoned;
-
- /* we are in a non-global zone, but parent is in the global zone */
- if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
- (void) zfs_standard_error(hdl, EPERM, errbuf);
- zfs_close(zhp);
- return (-1);
- }
-
- /* make sure parent is a filesystem */
- if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "parent is not a filesystem"));
- (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
- zfs_close(zhp);
- return (-1);
- }
-
- zfs_close(zhp);
- if (prefixlen != NULL)
- *prefixlen = strlen(parent);
- return (0);
-}
-
-/*
- * Finds whether the dataset of the given type(s) exists.
- */
-boolean_t
-zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
-{
- zfs_handle_t *zhp;
-
- if (!zfs_validate_name(hdl, path, types, B_FALSE))
- return (B_FALSE);
-
- /*
- * Try to get stats for the dataset, which will tell us if it exists.
- */
- if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
- int ds_type = zhp->zfs_type;
-
- zfs_close(zhp);
- if (types & ds_type)
- return (B_TRUE);
- }
- return (B_FALSE);
-}
-
-/*
- * Given a path to 'target', create all the ancestors between
- * the prefixlen portion of the path, and the target itself.
- * Fail if the initial prefixlen-ancestor does not already exist.
- */
-int
-create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
-{
- zfs_handle_t *h;
- char *cp;
- const char *opname;
-
- /* make sure prefix exists */
- cp = target + prefixlen;
- if (*cp != '/') {
- assert(strchr(cp, '/') == NULL);
- h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
- } else {
- *cp = '\0';
- h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
- *cp = '/';
- }
- if (h == NULL)
- return (-1);
- zfs_close(h);
-
- /*
- * Attempt to create, mount, and share any ancestor filesystems,
- * up to the prefixlen-long one.
- */
- for (cp = target + prefixlen + 1;
- (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) {
-
- *cp = '\0';
-
- h = make_dataset_handle(hdl, target);
- if (h) {
- /* it already exists, nothing to do here */
- zfs_close(h);
- continue;
- }
-
- if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
- NULL) != 0) {
- opname = dgettext(TEXT_DOMAIN, "create");
- goto ancestorerr;
- }
-
- h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
- if (h == NULL) {
- opname = dgettext(TEXT_DOMAIN, "open");
- goto ancestorerr;
- }
-
- if (zfs_mount(h, NULL, 0) != 0) {
- opname = dgettext(TEXT_DOMAIN, "mount");
- goto ancestorerr;
- }
-
- if (zfs_share(h, NULL) != 0) {
- opname = dgettext(TEXT_DOMAIN, "share");
- goto ancestorerr;
- }
-
- zfs_close(h);
- }
- zfs_commit_shares(NULL);
-
- return (0);
-
-ancestorerr:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "failed to %s ancestor '%s'"), opname, target);
- return (-1);
-}
-
-/*
- * Creates non-existing ancestors of the given path.
- */
-int
-zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
-{
- int prefix;
- char *path_copy;
- char errbuf[ERRBUFLEN];
- int rc = 0;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create '%s'"), path);
-
- /*
- * Check that we are not passing the nesting limit
- * before we start creating any ancestors.
- */
- if (dataset_nestcheck(path) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "maximum name nesting depth exceeded"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
-
- if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
- return (-1);
-
- if ((path_copy = strdup(path)) != NULL) {
- rc = create_parents(hdl, path_copy, prefix);
- free(path_copy);
- }
- if (path_copy == NULL || rc != 0)
- return (-1);
-
- return (0);
-}
-
-/*
- * Create a new filesystem or volume.
- */
-int
-zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
- nvlist_t *props)
-{
- int ret;
- uint64_t size = 0;
- uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
- uint64_t zoned;
- enum lzc_dataset_type ost;
- zpool_handle_t *zpool_handle;
- uint8_t *wkeydata = NULL;
- uint_t wkeylen = 0;
- char errbuf[ERRBUFLEN];
- char parent[ZFS_MAX_DATASET_NAME_LEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create '%s'"), path);
-
- /* validate the path, taking care to note the extended error message */
- if (!zfs_validate_name(hdl, path, type, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- if (dataset_nestcheck(path) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "maximum name nesting depth exceeded"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
-
- /* validate parents exist */
- if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
- return (-1);
-
- /*
- * The failure modes when creating a dataset of a different type over
- * one that already exists is a little strange. In particular, if you
- * try to create a dataset on top of an existing dataset, the ioctl()
- * will return ENOENT, not EEXIST. To prevent this from happening, we
- * first try to see if the dataset exists.
- */
- if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset already exists"));
- return (zfs_error(hdl, EZFS_EXISTS, errbuf));
- }
-
- if (type == ZFS_TYPE_VOLUME)
- ost = LZC_DATSET_TYPE_ZVOL;
- else
- ost = LZC_DATSET_TYPE_ZFS;
-
- /* open zpool handle for prop validation */
- char pool_path[ZFS_MAX_DATASET_NAME_LEN];
- (void) strlcpy(pool_path, path, sizeof (pool_path));
-
- /* truncate pool_path at first slash */
- char *p = strchr(pool_path, '/');
- if (p != NULL)
- *p = '\0';
-
- if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL)
- return (-1);
-
- if (props && (props = zfs_valid_proplist(hdl, type, props,
- zoned, NULL, zpool_handle, B_TRUE, errbuf)) == 0) {
- zpool_close(zpool_handle);
- return (-1);
- }
- zpool_close(zpool_handle);
-
- if (type == ZFS_TYPE_VOLUME) {
- /*
- * If we are creating a volume, the size and block size must
- * satisfy a few restraints. First, the blocksize must be a
- * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the
- * volsize must be a multiple of the block size, and cannot be
- * zero.
- */
- if (props == NULL || nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
- nvlist_free(props);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "missing volume size"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
-
- if ((ret = nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
- &blocksize)) != 0) {
- if (ret == ENOENT) {
- blocksize = zfs_prop_default_numeric(
- ZFS_PROP_VOLBLOCKSIZE);
- } else {
- nvlist_free(props);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "missing volume block size"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
- }
-
- if (size == 0) {
- nvlist_free(props);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "volume size cannot be zero"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
-
- if (size % blocksize != 0) {
- nvlist_free(props);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "volume size must be a multiple of volume block "
- "size"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
- }
-
- (void) parent_name(path, parent, sizeof (parent));
- if (zfs_crypto_create(hdl, parent, props, NULL, B_TRUE,
- &wkeydata, &wkeylen) != 0) {
- nvlist_free(props);
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
- }
-
- /* create the dataset */
- ret = lzc_create(path, ost, props, wkeydata, wkeylen);
- nvlist_free(props);
- if (wkeydata != NULL)
- free(wkeydata);
-
- /* check for failure */
- if (ret != 0) {
- switch (errno) {
- case ENOENT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "no such parent '%s'"), parent);
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
-
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded to set this "
- "property or value"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
-
- case EACCES:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encryption root's key is not loaded "
- "or provided"));
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
-
- case ERANGE:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property value(s) specified"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
-#ifdef _ILP32
- case EOVERFLOW:
- /*
- * This platform can't address a volume this big.
- */
- if (type == ZFS_TYPE_VOLUME)
- return (zfs_error(hdl, EZFS_VOLTOOBIG,
- errbuf));
- zfs_fallthrough;
-#endif
- default:
- return (zfs_standard_error(hdl, errno, errbuf));
- }
- }
-
- return (0);
-}
-
-/*
- * Destroys the given dataset. The caller must make sure that the filesystem
- * isn't mounted, and that there are no active dependents. If the file system
- * does not exist this function does nothing.
- */
-int
-zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
-{
- int error;
-
- if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT && defer)
- return (EINVAL);
-
- if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
- nvlist_t *nv = fnvlist_alloc();
- fnvlist_add_boolean(nv, zhp->zfs_name);
- error = lzc_destroy_bookmarks(nv, NULL);
- fnvlist_free(nv);
- if (error != 0) {
- return (zfs_standard_error_fmt(zhp->zfs_hdl, error,
- dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
- zhp->zfs_name));
- }
- return (0);
- }
-
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- nvlist_t *nv = fnvlist_alloc();
- fnvlist_add_boolean(nv, zhp->zfs_name);
- error = lzc_destroy_snaps(nv, defer, NULL);
- fnvlist_free(nv);
- } else {
- error = lzc_destroy(zhp->zfs_name);
- }
-
- if (error != 0 && error != ENOENT) {
- return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
- zhp->zfs_name));
- }
-
- remove_mountpoint(zhp);
-
- return (0);
-}
-
-struct destroydata {
- nvlist_t *nvl;
- const char *snapname;
-};
-
-static int
-zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
-{
- struct destroydata *dd = arg;
- char name[ZFS_MAX_DATASET_NAME_LEN];
- int rv = 0;
-
- if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
- dd->snapname) >= sizeof (name))
- return (EINVAL);
-
- if (lzc_exists(name))
- fnvlist_add_boolean(dd->nvl, name);
-
- rv = zfs_iter_filesystems_v2(zhp, 0, zfs_check_snap_cb, dd);
- zfs_close(zhp);
- return (rv);
-}
-
-/*
- * Destroys all snapshots with the given name in zhp & descendants.
- */
-int
-zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
-{
- int ret;
- struct destroydata dd = { 0 };
-
- dd.snapname = snapname;
- dd.nvl = fnvlist_alloc();
- (void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
-
- if (nvlist_empty(dd.nvl)) {
- ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
- dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
- zhp->zfs_name, snapname);
- } else {
- ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
- }
- fnvlist_free(dd.nvl);
- return (ret);
-}
-
-/*
- * Destroys all the snapshots named in the nvlist.
- */
-int
-zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
-{
- nvlist_t *errlist = NULL;
- nvpair_t *pair;
-
- int ret = zfs_destroy_snaps_nvl_os(hdl, snaps);
- if (ret != 0)
- return (ret);
-
- ret = lzc_destroy_snaps(snaps, defer, &errlist);
-
- if (ret == 0) {
- nvlist_free(errlist);
- return (0);
- }
-
- if (nvlist_empty(errlist)) {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
-
- ret = zfs_standard_error(hdl, ret, errbuf);
- }
- for (pair = nvlist_next_nvpair(errlist, NULL);
- pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
- nvpair_name(pair));
-
- switch (fnvpair_value_int32(pair)) {
- case EEXIST:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "snapshot is cloned"));
- ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
- break;
- case EBUSY: {
- nvlist_t *existing_holds;
- int err = lzc_get_holds(nvpair_name(pair),
- &existing_holds);
-
- /* check the presence of holders */
- if (err == 0 && !nvlist_empty(existing_holds)) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "it's being held. "
- "Run 'zfs holds -r %s' to see holders."),
- nvpair_name(pair));
- ret = zfs_error(hdl, EBUSY, errbuf);
- } else {
- ret = zfs_standard_error(hdl, errno, errbuf);
- }
-
- if (err == 0)
- nvlist_free(existing_holds);
- break;
- }
- default:
- ret = zfs_standard_error(hdl, errno, errbuf);
- break;
- }
- }
-
- nvlist_free(errlist);
- return (ret);
-}
-
-/*
- * Clones the given dataset. The target must be of the same type as the source.
- */
-int
-zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
-{
- char parent[ZFS_MAX_DATASET_NAME_LEN];
- int ret;
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- uint64_t zoned;
-
- assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create '%s'"), target);
-
- /* validate the target/clone name */
- if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- /* validate parents exist */
- if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
- return (-1);
-
- (void) parent_name(target, parent, sizeof (parent));
-
- /* do the clone */
-
- if (props) {
- zfs_type_t type = ZFS_TYPE_FILESYSTEM;
-
- if (ZFS_IS_VOLUME(zhp))
- type = ZFS_TYPE_VOLUME;
- if ((props = zfs_valid_proplist(hdl, type, props, zoned,
- zhp, zhp->zpool_hdl, B_TRUE, errbuf)) == NULL)
- return (-1);
- if (zfs_fix_auto_resv(zhp, props) == -1) {
- nvlist_free(props);
- return (-1);
- }
- }
-
- if (zfs_crypto_clone_check(hdl, zhp, parent, props) != 0) {
- nvlist_free(props);
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
- }
-
- ret = lzc_clone(target, zhp->zfs_name, props);
- nvlist_free(props);
-
- if (ret != 0) {
- switch (errno) {
-
- case ENOENT:
- /*
- * The parent doesn't exist. We should have caught this
- * above, but there may a race condition that has since
- * destroyed the parent.
- *
- * At this point, we don't know whether it's the source
- * that doesn't exist anymore, or whether the target
- * dataset doesn't exist.
- */
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "no such parent '%s'"), parent);
- return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
-
- case EXDEV:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "source and target pools differ"));
- return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
- errbuf));
-
- default:
- return (zfs_standard_error(zhp->zfs_hdl, errno,
- errbuf));
- }
- }
-
- return (ret);
-}
-
-/*
- * Promotes the given clone fs to be the clone parent.
- */
-int
-zfs_promote(zfs_handle_t *zhp)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char snapname[ZFS_MAX_DATASET_NAME_LEN];
- int ret;
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot promote '%s'"), zhp->zfs_name);
-
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots can not be promoted"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- }
-
- if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not a cloned filesystem"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- }
-
- if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
-
- if (ret != 0) {
- switch (ret) {
- case EACCES:
- /*
- * Promoting encrypted dataset outside its
- * encryption root.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot promote dataset outside its "
- "encryption root"));
- return (zfs_error(hdl, EZFS_EXISTS, errbuf));
-
- case EEXIST:
- /* There is a conflicting snapshot name. */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "conflicting snapshot '%s' from parent '%s'"),
- snapname, zhp->zfs_dmustats.dds_origin);
- return (zfs_error(hdl, EZFS_EXISTS, errbuf));
-
- default:
- return (zfs_standard_error(hdl, ret, errbuf));
- }
- }
- return (ret);
-}
-
-typedef struct snapdata {
- nvlist_t *sd_nvl;
- const char *sd_snapname;
-} snapdata_t;
-
-static int
-zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
-{
- snapdata_t *sd = arg;
- char name[ZFS_MAX_DATASET_NAME_LEN];
- int rv = 0;
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
- if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
- sd->sd_snapname) >= sizeof (name))
- return (EINVAL);
-
- fnvlist_add_boolean(sd->sd_nvl, name);
-
- rv = zfs_iter_filesystems_v2(zhp, 0, zfs_snapshot_cb, sd);
- }
- zfs_close(zhp);
-
- return (rv);
-}
-
-/*
- * Creates snapshots. The keys in the snaps nvlist are the snapshots to be
- * created.
- */
-int
-zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
-{
- int ret;
- char errbuf[ERRBUFLEN];
- nvpair_t *elem;
- nvlist_t *errors;
- zpool_handle_t *zpool_hdl;
- char pool[ZFS_MAX_DATASET_NAME_LEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create snapshots "));
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
- const char *snapname = nvpair_name(elem);
-
- /* validate the target name */
- if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
- B_TRUE)) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot create snapshot '%s'"), snapname);
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
- }
-
- /*
- * get pool handle for prop validation. assumes all snaps are in the
- * same pool, as does lzc_snapshot (below).
- */
- elem = nvlist_next_nvpair(snaps, NULL);
- if (elem == NULL)
- return (-1);
- (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
- pool[strcspn(pool, "/@")] = '\0';
- zpool_hdl = zpool_open(hdl, pool);
- if (zpool_hdl == NULL)
- return (-1);
-
- if (props != NULL &&
- (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
- props, B_FALSE, NULL, zpool_hdl, B_FALSE, errbuf)) == NULL) {
- zpool_close(zpool_hdl);
- return (-1);
- }
- zpool_close(zpool_hdl);
-
- ret = lzc_snapshot(snaps, props, &errors);
-
- if (ret != 0) {
- boolean_t printed = B_FALSE;
- for (elem = nvlist_next_nvpair(errors, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(errors, elem)) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot create snapshot '%s'"), nvpair_name(elem));
- (void) zfs_standard_error(hdl,
- fnvpair_value_int32(elem), errbuf);
- printed = B_TRUE;
- }
- if (!printed) {
- switch (ret) {
- case EXDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "multiple snapshots of same "
- "fs not allowed"));
- (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
-
- break;
- default:
- (void) zfs_standard_error(hdl, ret, errbuf);
- }
- }
- }
-
- nvlist_free(props);
- nvlist_free(errors);
- return (ret);
-}
-
-int
-zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
- nvlist_t *props)
-{
- int ret;
- snapdata_t sd = { 0 };
- char fsname[ZFS_MAX_DATASET_NAME_LEN];
- char *cp;
- zfs_handle_t *zhp;
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot snapshot %s"), path);
-
- if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- (void) strlcpy(fsname, path, sizeof (fsname));
- cp = strchr(fsname, '@');
- *cp = '\0';
- sd.sd_snapname = cp + 1;
-
- if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
- ZFS_TYPE_VOLUME)) == NULL) {
- return (-1);
- }
-
- sd.sd_nvl = fnvlist_alloc();
- if (recursive) {
- (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
- } else {
- fnvlist_add_boolean(sd.sd_nvl, path);
- }
-
- ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
- fnvlist_free(sd.sd_nvl);
- zfs_close(zhp);
- return (ret);
-}
-
-/*
- * Destroy any more recent snapshots. We invoke this callback on any dependents
- * of the snapshot first. If the 'cb_dependent' member is non-zero, then this
- * is a dependent and we should just destroy it without checking the transaction
- * group.
- */
-typedef struct rollback_data {
- const char *cb_target; /* the snapshot */
- uint64_t cb_create; /* creation time reference */
- boolean_t cb_error;
- boolean_t cb_force;
-} rollback_data_t;
-
-static int
-rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
-{
- rollback_data_t *cbp = data;
- prop_changelist_t *clp;
-
- /* We must destroy this clone; first unmount it */
- clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
- cbp->cb_force ? MS_FORCE: 0);
- if (clp == NULL || changelist_prefix(clp) != 0) {
- cbp->cb_error = B_TRUE;
- zfs_close(zhp);
- return (0);
- }
- if (zfs_destroy(zhp, B_FALSE) != 0)
- cbp->cb_error = B_TRUE;
- else
- changelist_remove(clp, zhp->zfs_name);
- (void) changelist_postfix(clp);
- changelist_free(clp);
-
- zfs_close(zhp);
- return (0);
-}
-
-static int
-rollback_destroy(zfs_handle_t *zhp, void *data)
-{
- rollback_data_t *cbp = data;
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
- cbp->cb_error |= zfs_iter_dependents_v2(zhp, 0, B_FALSE,
- rollback_destroy_dependent, cbp);
-
- cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
- }
-
- zfs_close(zhp);
- return (0);
-}
-
-/*
- * Given a dataset, rollback to a specific snapshot, discarding any
- * data changes since then and making it the active dataset.
- *
- * Any snapshots and bookmarks more recent than the target are
- * destroyed, along with their dependents (i.e. clones).
- */
-int
-zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
-{
- rollback_data_t cb = { 0 };
- int err;
- boolean_t restore_resv = 0;
- uint64_t old_volsize = 0, new_volsize;
- zfs_prop_t resv_prop = { 0 };
- uint64_t min_txg = 0;
-
- assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
- zhp->zfs_type == ZFS_TYPE_VOLUME);
-
- /*
- * Destroy all recent snapshots and their dependents.
- */
- cb.cb_force = force;
- cb.cb_target = snap->zfs_name;
- cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
-
- if (cb.cb_create > 0)
- min_txg = cb.cb_create;
-
- (void) zfs_iter_snapshots_v2(zhp, 0, rollback_destroy, &cb,
- min_txg, 0);
-
- (void) zfs_iter_bookmarks_v2(zhp, 0, rollback_destroy, &cb);
-
- if (cb.cb_error)
- return (-1);
-
- /*
- * Now that we have verified that the snapshot is the latest,
- * rollback to the given snapshot.
- */
-
- if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
- if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
- return (-1);
- old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
- restore_resv =
- (old_volsize == zfs_prop_get_int(zhp, resv_prop));
- }
-
- /*
- * Pass both the filesystem and the wanted snapshot names,
- * we would get an error back if the snapshot is destroyed or
- * a new snapshot is created before this request is processed.
- */
- err = lzc_rollback_to(zhp->zfs_name, snap->zfs_name);
- if (err != 0) {
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
- zhp->zfs_name);
- switch (err) {
- case EEXIST:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "there is a snapshot or bookmark more recent "
- "than '%s'"), snap->zfs_name);
- (void) zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf);
- break;
- case ESRCH:
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "'%s' is not found among snapshots of '%s'"),
- snap->zfs_name, zhp->zfs_name);
- (void) zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf);
- break;
- case EINVAL:
- (void) zfs_error(zhp->zfs_hdl, EZFS_BADTYPE, errbuf);
- break;
- default:
- (void) zfs_standard_error(zhp->zfs_hdl, err, errbuf);
- }
- return (err);
- }
-
- /*
- * For volumes, if the pre-rollback volsize matched the pre-
- * rollback reservation and the volsize has changed then set
- * the reservation property to the post-rollback volsize.
- * Make a new handle since the rollback closed the dataset.
- */
- if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
- (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
- if (restore_resv) {
- new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
- if (old_volsize != new_volsize)
- err = zfs_prop_set_int(zhp, resv_prop,
- new_volsize);
- }
- zfs_close(zhp);
- }
- return (err);
-}
-
-/*
- * Renames the given dataset.
- */
-int
-zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
-{
- int ret = 0;
- zfs_cmd_t zc = {"\0"};
- char *delim;
- prop_changelist_t *cl = NULL;
- char parent[ZFS_MAX_DATASET_NAME_LEN];
- char property[ZFS_MAXPROPLEN];
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char errbuf[ERRBUFLEN];
-
- /* if we have the same exact name, just return success */
- if (strcmp(zhp->zfs_name, target) == 0)
- return (0);
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot rename to '%s'"), target);
-
- /* make sure source name is valid */
- if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- /*
- * Make sure the target name is valid
- */
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- if ((strchr(target, '@') == NULL) ||
- *target == '@') {
- /*
- * Snapshot target name is abbreviated,
- * reconstruct full dataset name
- */
- (void) strlcpy(parent, zhp->zfs_name,
- sizeof (parent));
- delim = strchr(parent, '@');
- if (strchr(target, '@') == NULL)
- *(++delim) = '\0';
- else
- *delim = '\0';
- (void) strlcat(parent, target, sizeof (parent));
- target = parent;
- } else {
- /*
- * Make sure we're renaming within the same dataset.
- */
- delim = strchr(target, '@');
- if (strncmp(zhp->zfs_name, target, delim - target)
- != 0 || zhp->zfs_name[delim - target] != '@') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots must be part of same "
- "dataset"));
- return (zfs_error(hdl, EZFS_CROSSTARGET,
- errbuf));
- }
- }
-
- if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- } else {
- if (flags.recursive) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "recursive rename must be a snapshot"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- }
-
- if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- /* validate parents */
- if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
- return (-1);
-
- /* make sure we're in the same pool */
- verify((delim = strchr(target, '/')) != NULL);
- if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
- zhp->zfs_name[delim - target] != '/') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "datasets must be within same pool"));
- return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
- }
-
- /* new name cannot be a child of the current dataset name */
- if (is_descendant(zhp->zfs_name, target)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "New dataset name cannot be a descendant of "
- "current dataset name"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
- }
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
-
- if (getzoneid() == GLOBAL_ZONEID &&
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset is used in a non-global zone"));
- return (zfs_error(hdl, EZFS_ZONED, errbuf));
- }
-
- /*
- * Avoid unmounting file systems with mountpoint property set to
- * 'legacy' or 'none' even if -u option is not given.
- */
- if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
- !flags.recursive && !flags.nounmount &&
- zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
- sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
- (strcmp(property, "legacy") == 0 ||
- strcmp(property, "none") == 0)) {
- flags.nounmount = B_TRUE;
- }
- if (flags.recursive) {
- char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
- delim = strchr(parentname, '@');
- *delim = '\0';
- zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname,
- ZFS_TYPE_DATASET);
- free(parentname);
- if (zhrp == NULL) {
- ret = -1;
- goto error;
- }
- zfs_close(zhrp);
- } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
- if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
- flags.nounmount ? CL_GATHER_DONT_UNMOUNT :
- CL_GATHER_ITER_MOUNTED,
- flags.forceunmount ? MS_FORCE : 0)) == NULL)
- return (-1);
-
- if (changelist_haszonedchild(cl)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "child dataset with inherited mountpoint is used "
- "in a non-global zone"));
- (void) zfs_error(hdl, EZFS_ZONED, errbuf);
- ret = -1;
- goto error;
- }
-
- if ((ret = changelist_prefix(cl)) != 0)
- goto error;
- }
-
- if (ZFS_IS_VOLUME(zhp))
- zc.zc_objset_type = DMU_OST_ZVOL;
- else
- zc.zc_objset_type = DMU_OST_ZFS;
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
-
- zc.zc_cookie = !!flags.recursive;
- zc.zc_cookie |= (!!flags.nounmount) << 1;
-
- if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
- /*
- * if it was recursive, the one that actually failed will
- * be in zc.zc_name
- */
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot rename '%s'"), zc.zc_name);
-
- if (flags.recursive && errno == EEXIST) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "a child dataset already has a snapshot "
- "with the new name"));
- (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
- } else if (errno == EACCES) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot move encrypted child outside of "
- "its encryption root"));
- (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
- } else {
- (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
- }
-
- /*
- * On failure, we still want to remount any filesystems that
- * were previously mounted, so we don't alter the system state.
- */
- if (cl != NULL)
- (void) changelist_postfix(cl);
- } else {
- if (cl != NULL) {
- changelist_rename(cl, zfs_get_name(zhp), target);
- ret = changelist_postfix(cl);
- }
- (void) strlcpy(zhp->zfs_name, target, sizeof (zhp->zfs_name));
- }
-
-error:
- if (cl != NULL) {
- changelist_free(cl);
- }
- return (ret);
-}
-
-nvlist_t *
-zfs_get_all_props(zfs_handle_t *zhp)
-{
- return (zhp->zfs_props);
-}
-
-nvlist_t *
-zfs_get_recvd_props(zfs_handle_t *zhp)
-{
- if (zhp->zfs_recvd_props == NULL)
- if (get_recvd_props_ioctl(zhp) != 0)
- return (NULL);
- return (zhp->zfs_recvd_props);
-}
-
-nvlist_t *
-zfs_get_user_props(zfs_handle_t *zhp)
-{
- return (zhp->zfs_user_props);
-}
-
-/*
- * This function is used by 'zfs list' to determine the exact set of columns to
- * display, and their maximum widths. This does two main things:
- *
- * - If this is a list of all properties, then expand the list to include
- * all native properties, and set a flag so that for each dataset we look
- * for new unique user properties and add them to the list.
- *
- * - For non fixed-width properties, keep track of the maximum width seen
- * so that we can size the column appropriately. If the user has
- * requested received property values, we also need to compute the width
- * of the RECEIVED column.
- */
-int
-zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
- boolean_t literal)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- zprop_list_t *entry;
- zprop_list_t **last, **start;
- nvlist_t *userprops, *propval;
- nvpair_t *elem;
- const char *strval;
- char buf[ZFS_MAXPROPLEN];
-
- if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
- return (-1);
-
- userprops = zfs_get_user_props(zhp);
-
- entry = *plp;
- if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
- /*
- * Go through and add any user properties as necessary. We
- * start by incrementing our list pointer to the first
- * non-native property.
- */
- start = plp;
- while (*start != NULL) {
- if ((*start)->pl_prop == ZPROP_USERPROP)
- break;
- start = &(*start)->pl_next;
- }
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
- /*
- * See if we've already found this property in our list.
- */
- for (last = start; *last != NULL;
- last = &(*last)->pl_next) {
- if (strcmp((*last)->pl_user_prop,
- nvpair_name(elem)) == 0)
- break;
- }
-
- if (*last == NULL) {
- entry = zfs_alloc(hdl, sizeof (zprop_list_t));
- entry->pl_user_prop =
- zfs_strdup(hdl, nvpair_name(elem));
- entry->pl_prop = ZPROP_USERPROP;
- entry->pl_width = strlen(nvpair_name(elem));
- entry->pl_all = B_TRUE;
- *last = entry;
- }
- }
- }
-
- /*
- * Now go through and check the width of any non-fixed columns
- */
- for (entry = *plp; entry != NULL; entry = entry->pl_next) {
- if (entry->pl_fixed && !literal)
- continue;
-
- if (entry->pl_prop != ZPROP_USERPROP) {
- if (zfs_prop_get(zhp, entry->pl_prop,
- buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
- if (strlen(buf) > entry->pl_width)
- entry->pl_width = strlen(buf);
- }
- if (received && zfs_prop_get_recvd(zhp,
- zfs_prop_to_name(entry->pl_prop),
- buf, sizeof (buf), literal) == 0)
- if (strlen(buf) > entry->pl_recvd_width)
- entry->pl_recvd_width = strlen(buf);
- } else {
- if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
- &propval) == 0) {
- strval = fnvlist_lookup_string(propval,
- ZPROP_VALUE);
- if (strlen(strval) > entry->pl_width)
- entry->pl_width = strlen(strval);
- }
- if (received && zfs_prop_get_recvd(zhp,
- entry->pl_user_prop,
- buf, sizeof (buf), literal) == 0)
- if (strlen(buf) > entry->pl_recvd_width)
- entry->pl_recvd_width = strlen(buf);
- }
- }
-
- return (0);
-}
-
-void
-zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
-{
- nvpair_t *curr;
- nvpair_t *next;
-
- /*
- * Keep a reference to the props-table against which we prune the
- * properties.
- */
- zhp->zfs_props_table = props;
-
- curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
-
- while (curr) {
- zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
- next = nvlist_next_nvpair(zhp->zfs_props, curr);
-
- /*
- * User properties will result in ZPROP_USERPROP (an alias
- * for ZPROP_INVAL), and since we
- * only know how to prune standard ZFS properties, we always
- * leave these in the list. This can also happen if we
- * encounter an unknown DSL property (when running older
- * software, for example).
- */
- if (zfs_prop != ZPROP_USERPROP && props[zfs_prop] == B_FALSE)
- (void) nvlist_remove(zhp->zfs_props,
- nvpair_name(curr), nvpair_type(curr));
- curr = next;
- }
-}
-
-static int
-zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
- zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
-{
- zfs_cmd_t zc = {"\0"};
- nvlist_t *nvlist = NULL;
- int error;
-
- (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
- zc.zc_cookie = (uint64_t)cmd;
-
- if (cmd == ZFS_SMB_ACL_RENAME) {
- if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
- (void) no_memory(hdl);
- return (0);
- }
- }
-
- switch (cmd) {
- case ZFS_SMB_ACL_ADD:
- case ZFS_SMB_ACL_REMOVE:
- (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
- break;
- case ZFS_SMB_ACL_RENAME:
- if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
- resource1) != 0) {
- (void) no_memory(hdl);
- return (-1);
- }
- if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
- resource2) != 0) {
- (void) no_memory(hdl);
- return (-1);
- }
- zcmd_write_src_nvlist(hdl, &zc, nvlist);
- break;
- case ZFS_SMB_ACL_PURGE:
- break;
- default:
- return (-1);
- }
- error = lzc_ioctl_fd(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
- nvlist_free(nvlist);
- return (error);
-}
-
-int
-zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
- char *path, char *resource)
-{
- return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
- resource, NULL));
-}
-
-int
-zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
- char *path, char *resource)
-{
- return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
- resource, NULL));
-}
-
-int
-zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
-{
- return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
- NULL, NULL));
-}
-
-int
-zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
- char *oldname, char *newname)
-{
- return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
- oldname, newname));
-}
-
-int
-zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
- zfs_userspace_cb_t func, void *arg)
-{
- zfs_cmd_t zc = {"\0"};
- zfs_useracct_t buf[100];
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- int ret;
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- zc.zc_objset_type = type;
- zc.zc_nvlist_dst = (uintptr_t)buf;
-
- for (;;) {
- zfs_useracct_t *zua = buf;
-
- zc.zc_nvlist_dst_size = sizeof (buf);
- if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
- if ((errno == ENOTSUP &&
- (type == ZFS_PROP_USEROBJUSED ||
- type == ZFS_PROP_GROUPOBJUSED ||
- type == ZFS_PROP_USEROBJQUOTA ||
- type == ZFS_PROP_GROUPOBJQUOTA ||
- type == ZFS_PROP_PROJECTOBJUSED ||
- type == ZFS_PROP_PROJECTOBJQUOTA ||
- type == ZFS_PROP_PROJECTUSED ||
- type == ZFS_PROP_PROJECTQUOTA)))
- break;
-
- return (zfs_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN,
- "cannot get used/quota for %s"), zc.zc_name));
- }
- if (zc.zc_nvlist_dst_size == 0)
- break;
-
- while (zc.zc_nvlist_dst_size > 0) {
- if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
- zua->zu_space, zc.zc_guid)) != 0)
- return (ret);
- zua++;
- zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
- }
- }
-
- return (0);
-}
-
-struct holdarg {
- nvlist_t *nvl;
- const char *snapname;
- const char *tag;
- boolean_t recursive;
- int error;
-};
-
-static int
-zfs_hold_one(zfs_handle_t *zhp, void *arg)
-{
- struct holdarg *ha = arg;
- char name[ZFS_MAX_DATASET_NAME_LEN];
- int rv = 0;
-
- if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
- ha->snapname) >= sizeof (name))
- return (EINVAL);
-
- if (lzc_exists(name))
- fnvlist_add_string(ha->nvl, name, ha->tag);
-
- if (ha->recursive)
- rv = zfs_iter_filesystems_v2(zhp, 0, zfs_hold_one, ha);
- zfs_close(zhp);
- return (rv);
-}
-
-int
-zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
- boolean_t recursive, int cleanup_fd)
-{
- int ret;
- struct holdarg ha;
-
- ha.nvl = fnvlist_alloc();
- ha.snapname = snapname;
- ha.tag = tag;
- ha.recursive = recursive;
- (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
-
- if (nvlist_empty(ha.nvl)) {
- char errbuf[ERRBUFLEN];
-
- fnvlist_free(ha.nvl);
- ret = ENOENT;
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot hold snapshot '%s@%s'"),
- zhp->zfs_name, snapname);
- (void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
- return (ret);
- }
-
- ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
- fnvlist_free(ha.nvl);
-
- return (ret);
-}
-
-int
-zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
-{
- int ret;
- nvlist_t *errors;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char errbuf[ERRBUFLEN];
- nvpair_t *elem;
-
- errors = NULL;
- ret = lzc_hold(holds, cleanup_fd, &errors);
-
- if (ret == 0) {
- /* There may be errors even in the success case. */
- fnvlist_free(errors);
- return (0);
- }
-
- if (nvlist_empty(errors)) {
- /* no hold-specific errors */
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot hold"));
- switch (ret) {
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- case EINVAL:
- (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- default:
- (void) zfs_standard_error(hdl, ret, errbuf);
- }
- }
-
- for (elem = nvlist_next_nvpair(errors, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(errors, elem)) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot hold snapshot '%s'"), nvpair_name(elem));
- switch (fnvpair_value_int32(elem)) {
- case E2BIG:
- /*
- * Temporary tags wind up having the ds object id
- * prepended. So even if we passed the length check
- * above, it's still possible for the tag to wind
- * up being slightly too long.
- */
- (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
- break;
- case EINVAL:
- (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- case EEXIST:
- (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
- break;
- default:
- (void) zfs_standard_error(hdl,
- fnvpair_value_int32(elem), errbuf);
- }
- }
-
- fnvlist_free(errors);
- return (ret);
-}
-
-static int
-zfs_release_one(zfs_handle_t *zhp, void *arg)
-{
- struct holdarg *ha = arg;
- char name[ZFS_MAX_DATASET_NAME_LEN];
- int rv = 0;
- nvlist_t *existing_holds;
-
- if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
- ha->snapname) >= sizeof (name)) {
- ha->error = EINVAL;
- rv = EINVAL;
- }
-
- if (lzc_get_holds(name, &existing_holds) != 0) {
- ha->error = ENOENT;
- } else if (!nvlist_exists(existing_holds, ha->tag)) {
- ha->error = ESRCH;
- } else {
- nvlist_t *torelease = fnvlist_alloc();
- fnvlist_add_boolean(torelease, ha->tag);
- fnvlist_add_nvlist(ha->nvl, name, torelease);
- fnvlist_free(torelease);
- }
-
- if (ha->recursive)
- rv = zfs_iter_filesystems_v2(zhp, 0, zfs_release_one, ha);
- zfs_close(zhp);
- return (rv);
-}
-
-int
-zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
- boolean_t recursive)
-{
- int ret;
- struct holdarg ha;
- nvlist_t *errors = NULL;
- nvpair_t *elem;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char errbuf[ERRBUFLEN];
-
- ha.nvl = fnvlist_alloc();
- ha.snapname = snapname;
- ha.tag = tag;
- ha.recursive = recursive;
- ha.error = 0;
- (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
-
- if (nvlist_empty(ha.nvl)) {
- fnvlist_free(ha.nvl);
- ret = ha.error;
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot release hold from snapshot '%s@%s'"),
- zhp->zfs_name, snapname);
- if (ret == ESRCH) {
- (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
- } else {
- (void) zfs_standard_error(hdl, ret, errbuf);
- }
- return (ret);
- }
-
- ret = lzc_release(ha.nvl, &errors);
- fnvlist_free(ha.nvl);
-
- if (ret == 0) {
- /* There may be errors even in the success case. */
- fnvlist_free(errors);
- return (0);
- }
-
- if (nvlist_empty(errors)) {
- /* no hold-specific errors */
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot release"));
- switch (errno) {
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- default:
- (void) zfs_standard_error(hdl, errno, errbuf);
- }
- }
-
- for (elem = nvlist_next_nvpair(errors, NULL);
- elem != NULL;
- elem = nvlist_next_nvpair(errors, elem)) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot release hold from snapshot '%s'"),
- nvpair_name(elem));
- switch (fnvpair_value_int32(elem)) {
- case ESRCH:
- (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
- break;
- case EINVAL:
- (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- default:
- (void) zfs_standard_error(hdl,
- fnvpair_value_int32(elem), errbuf);
- }
- }
-
- fnvlist_free(errors);
- return (ret);
-}
-
-int
-zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- int nvsz = 2048;
- void *nvbuf;
- int err = 0;
- char errbuf[ERRBUFLEN];
-
- assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
- zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
-
-tryagain:
-
- nvbuf = malloc(nvsz);
- if (nvbuf == NULL) {
- err = (zfs_error(hdl, EZFS_NOMEM, zfs_strerror(errno)));
- goto out;
- }
-
- zc.zc_nvlist_dst_size = nvsz;
- zc.zc_nvlist_dst = (uintptr_t)nvbuf;
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- if (zfs_ioctl(hdl, ZFS_IOC_GET_FSACL, &zc) != 0) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
- zc.zc_name);
- switch (errno) {
- case ENOMEM:
- free(nvbuf);
- nvsz = zc.zc_nvlist_dst_size;
- goto tryagain;
-
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- case EINVAL:
- err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- case ENOENT:
- err = zfs_error(hdl, EZFS_NOENT, errbuf);
- break;
- default:
- err = zfs_standard_error(hdl, errno, errbuf);
- break;
- }
- } else {
- /* success */
- int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
- if (rc) {
- err = zfs_standard_error_fmt(hdl, rc, dgettext(
- TEXT_DOMAIN, "cannot get permissions on '%s'"),
- zc.zc_name);
- }
- }
-
- free(nvbuf);
-out:
- return (err);
-}
-
-int
-zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char *nvbuf;
- char errbuf[ERRBUFLEN];
- size_t nvsz;
- int err;
-
- assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
- zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
-
- err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
- assert(err == 0);
-
- nvbuf = malloc(nvsz);
-
- err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
- assert(err == 0);
-
- zc.zc_nvlist_src_size = nvsz;
- zc.zc_nvlist_src = (uintptr_t)nvbuf;
- zc.zc_perm_action = un;
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
-
- if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
- zc.zc_name);
- switch (errno) {
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- case EINVAL:
- err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- case ENOENT:
- err = zfs_error(hdl, EZFS_NOENT, errbuf);
- break;
- default:
- err = zfs_standard_error(hdl, errno, errbuf);
- break;
- }
- }
-
- free(nvbuf);
-
- return (err);
-}
-
-int
-zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
-{
- int err;
- char errbuf[ERRBUFLEN];
-
- err = lzc_get_holds(zhp->zfs_name, nvl);
-
- if (err != 0) {
- libzfs_handle_t *hdl = zhp->zfs_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
- zhp->zfs_name);
- switch (err) {
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded"));
- err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- case EINVAL:
- err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
- break;
- case ENOENT:
- err = zfs_error(hdl, EZFS_NOENT, errbuf);
- break;
- default:
- err = zfs_standard_error(hdl, errno, errbuf);
- break;
- }
- }
-
- return (err);
-}
-
-/*
- * The theory of raidz space accounting
- *
- * The "referenced" property of RAIDZ vdevs is scaled such that a 128KB block
- * will "reference" 128KB, even though it allocates more than that, to store the
- * parity information (and perhaps skip sectors). This concept of the
- * "referenced" (and other DMU space accounting) being lower than the allocated
- * space by a constant factor is called "raidz deflation."
- *
- * As mentioned above, the constant factor for raidz deflation assumes a 128KB
- * block size. However, zvols typically have a much smaller block size (default
- * 8KB). These smaller blocks may require proportionally much more parity
- * information (and perhaps skip sectors). In this case, the change to the
- * "referenced" property may be much more than the logical block size.
- *
- * Suppose a raidz vdev has 5 disks with ashift=12. A 128k block may be written
- * as follows.
- *
- * +-------+-------+-------+-------+-------+
- * | disk1 | disk2 | disk3 | disk4 | disk5 |
- * +-------+-------+-------+-------+-------+
- * | P0 | D0 | D8 | D16 | D24 |
- * | P1 | D1 | D9 | D17 | D25 |
- * | P2 | D2 | D10 | D18 | D26 |
- * | P3 | D3 | D11 | D19 | D27 |
- * | P4 | D4 | D12 | D20 | D28 |
- * | P5 | D5 | D13 | D21 | D29 |
- * | P6 | D6 | D14 | D22 | D30 |
- * | P7 | D7 | D15 | D23 | D31 |
- * +-------+-------+-------+-------+-------+
- *
- * Above, notice that 160k was allocated: 8 x 4k parity sectors + 32 x 4k data
- * sectors. The dataset's referenced will increase by 128k and the pool's
- * allocated and free properties will be adjusted by 160k.
- *
- * A 4k block written to the same raidz vdev will require two 4k sectors. The
- * blank cells represent unallocated space.
- *
- * +-------+-------+-------+-------+-------+
- * | disk1 | disk2 | disk3 | disk4 | disk5 |
- * +-------+-------+-------+-------+-------+
- * | P0 | D0 | | | |
- * +-------+-------+-------+-------+-------+
- *
- * Above, notice that the 4k block required one sector for parity and another
- * for data. vdev_raidz_psize_to_asize() will return 8k and as such the pool's
- * allocated and free properties will be adjusted by 8k. The dataset will not
- * be charged 8k. Rather, it will be charged a value that is scaled according
- * to the overhead of the 128k block on the same vdev. This 8k allocation will
- * be charged 8k * 128k / 160k. 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is
- * as calculated in the 128k block example above.
- *
- * Every raidz allocation is sized to be a multiple of nparity+1 sectors. That
- * is, every raidz1 allocation will be a multiple of 2 sectors, raidz2
- * allocations are a multiple of 3 sectors, and raidz3 allocations are a
- * multiple of of 4 sectors. When a block does not fill the required number of
- * sectors, skip blocks (sectors) are used.
- *
- * An 8k block being written to a raidz vdev may be written as follows:
- *
- * +-------+-------+-------+-------+-------+
- * | disk1 | disk2 | disk3 | disk4 | disk5 |
- * +-------+-------+-------+-------+-------+
- * | P0 | D0 | D1 | S0 | |
- * +-------+-------+-------+-------+-------+
- *
- * In order to maintain the nparity+1 allocation size, a skip block (S0) was
- * added. For this 8k block, the pool's allocated and free properties are
- * adjusted by 16k and the dataset's referenced is increased by 16k * 128k /
- * 160k. Again, 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as calculated in
- * the 128k block example above.
- *
- * 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:
- *
- * +-------+-------+-------+-------+-------+
- * | disk1 | disk2 | disk3 | disk4 | disk5 |
- * +-------+-------+-------+-------+-------+
- * | P0 | D0 | D1 | S0 | S1 |
- * +-------+-------+-------+-------+-------+
- *
- * Compression may lead to a variety of block sizes being written for the same
- * volume or file. There is no clear way to reserve just the amount of space
- * that will be required, so the worst case (no compression) is assumed.
- * Note that metadata blocks will typically be compressed, so the reservation
- * size returned by zvol_volsize_to_reservation() will generally be slightly
- * larger than the maximum that the volume can reference.
- */
-
-/*
- * Derived from function of same name in module/zfs/vdev_raidz.c. Returns the
- * amount of space (in bytes) that will be allocated for the specified block
- * size. Note that the "referenced" space accounted will be less than this, but
- * not necessarily equal to "blksize", due to RAIDZ deflation.
- */
-static uint64_t
-vdev_raidz_psize_to_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
- uint64_t blksize)
-{
- uint64_t asize, ndata;
-
- ASSERT3U(ndisks, >, nparity);
- ndata = ndisks - nparity;
- asize = ((blksize - 1) >> ashift) + 1;
- asize += nparity * ((asize + ndata - 1) / ndata);
- asize = roundup(asize, nparity + 1) << ashift;
-
- return (asize);
-}
-
-/*
- * Derived from function of same name in module/zfs/vdev_draid.c. Returns the
- * amount of space (in bytes) that will be allocated for the specified block
- * size.
- */
-static uint64_t
-vdev_draid_psize_to_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
- uint64_t blksize)
-{
- ASSERT3U(ndisks, >, nparity);
- uint64_t ndata = ndisks - nparity;
- uint64_t rows = ((blksize - 1) / (ndata << ashift)) + 1;
- uint64_t asize = (rows * ndisks) << ashift;
-
- return (asize);
-}
-
-/*
- * Determine how much space will be allocated if it lands on the most space-
- * inefficient top-level vdev. Returns the size in bytes required to store one
- * copy of the volume data. See theory comment above.
- */
-static uint64_t
-volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
-{
- nvlist_t *config, *tree, **vdevs;
- uint_t nvdevs;
- uint64_t ret = 0;
-
- config = zpool_get_config(zhp, NULL);
- if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree) != 0 ||
- nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN,
- &vdevs, &nvdevs) != 0) {
- return (nblocks * blksize);
- }
-
- for (int v = 0; v < nvdevs; v++) {
- const char *type;
- uint64_t nparity, ashift, asize, tsize;
- uint64_t volsize;
-
- if (nvlist_lookup_string(vdevs[v], ZPOOL_CONFIG_TYPE,
- &type) != 0)
- continue;
-
- if (strcmp(type, VDEV_TYPE_RAIDZ) != 0 &&
- strcmp(type, VDEV_TYPE_DRAID) != 0)
- continue;
-
- if (nvlist_lookup_uint64(vdevs[v],
- ZPOOL_CONFIG_NPARITY, &nparity) != 0)
- continue;
-
- if (nvlist_lookup_uint64(vdevs[v],
- ZPOOL_CONFIG_ASHIFT, &ashift) != 0)
- continue;
-
- if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
- nvlist_t **disks;
- uint_t ndisks;
-
- if (nvlist_lookup_nvlist_array(vdevs[v],
- ZPOOL_CONFIG_CHILDREN, &disks, &ndisks) != 0)
- continue;
-
- /* allocation size for the "typical" 128k block */
- tsize = vdev_raidz_psize_to_asize(ndisks, nparity,
- ashift, SPA_OLD_MAXBLOCKSIZE);
-
- /* allocation size for the blksize block */
- asize = vdev_raidz_psize_to_asize(ndisks, nparity,
- ashift, blksize);
- } else {
- uint64_t ndata;
-
- if (nvlist_lookup_uint64(vdevs[v],
- ZPOOL_CONFIG_DRAID_NDATA, &ndata) != 0)
- continue;
-
- /* allocation size for the "typical" 128k block */
- tsize = vdev_draid_psize_to_asize(ndata + nparity,
- nparity, ashift, SPA_OLD_MAXBLOCKSIZE);
-
- /* allocation size for the blksize block */
- asize = vdev_draid_psize_to_asize(ndata + nparity,
- nparity, ashift, blksize);
- }
-
- /*
- * Scale this size down as a ratio of 128k / tsize.
- * See theory statement above.
- *
- * Bitshift is to avoid the case of nblocks * asize < tsize
- * producing a size of 0.
- */
- volsize = (nblocks * asize) / (tsize >> SPA_MINBLOCKSHIFT);
- /*
- * If we would blow UINT64_MAX with this next multiplication,
- * don't.
- */
- if (volsize >
- (UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT)))
- volsize = UINT64_MAX;
- else
- volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
-
- if (volsize > ret) {
- ret = volsize;
- }
- }
-
- if (ret == 0) {
- ret = nblocks * blksize;
- }
-
- return (ret);
-}
-
-/*
- * Convert the zvol's volume size to an appropriate reservation. See theory
- * comment above.
- *
- * Note: If this routine is updated, it is necessary to update the ZFS test
- * suite's shell version in reservation.shlib.
- */
-uint64_t
-zvol_volsize_to_reservation(zpool_handle_t *zph, uint64_t volsize,
- nvlist_t *props)
-{
- uint64_t numdb;
- uint64_t nblocks, volblocksize;
- int ncopies;
- const char *strval;
-
- if (nvlist_lookup_string(props,
- zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
- ncopies = atoi(strval);
- else
- ncopies = 1;
- if (nvlist_lookup_uint64(props,
- zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
- &volblocksize) != 0)
- volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
-
- nblocks = volsize / volblocksize;
- /*
- * Metadata defaults to using 128k blocks, not volblocksize blocks. For
- * this reason, only the data blocks are scaled based on vdev config.
- */
- volsize = volsize_from_vdevs(zph, nblocks, volblocksize);
-
- /* start with metadnode L0-L6 */
- numdb = 7;
- /* calculate number of indirects */
- while (nblocks > 1) {
- nblocks += DNODES_PER_LEVEL - 1;
- nblocks /= DNODES_PER_LEVEL;
- numdb += nblocks;
- }
- numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
- volsize *= ncopies;
- /*
- * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
- * compressed, but in practice they compress down to about
- * 1100 bytes
- */
- numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
- volsize += numdb;
- return (volsize);
-}
-
-/*
- * Wait for the given activity and return the status of the wait (whether or not
- * any waiting was done) in the 'waited' parameter. Non-existent fses are
- * reported via the 'missing' parameter, rather than by printing an error
- * message. This is convenient when this function is called in a loop over a
- * long period of time (as it is, for example, by zfs's wait cmd). In that
- * scenario, a fs being exported or destroyed should be considered a normal
- * event, so we don't want to print an error when we find that the fs doesn't
- * exist.
- */
-int
-zfs_wait_status(zfs_handle_t *zhp, zfs_wait_activity_t activity,
- boolean_t *missing, boolean_t *waited)
-{
- int error = lzc_wait_fs(zhp->zfs_name, activity, waited);
- *missing = (error == ENOENT);
- if (*missing)
- return (0);
-
- if (error != 0) {
- (void) zfs_standard_error_fmt(zhp->zfs_hdl, error,
- dgettext(TEXT_DOMAIN, "error waiting in fs '%s'"),
- zhp->zfs_name);
- }
-
- return (error);
-}
diff --git a/lib/libzfs/libzfs_diff.c b/lib/libzfs/libzfs_diff.c
deleted file mode 100644
index 5f50bce531f7..000000000000
--- a/lib/libzfs/libzfs_diff.c
+++ /dev/null
@@ -1,830 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2015, 2018 by Delphix. All rights reserved.
- * Copyright 2016 Joyent, Inc.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- */
-
-/*
- * zfs diff support
- */
-#include <ctype.h>
-#include <errno.h>
-#include <libintl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <sys/zfs_ioctl.h>
-#include <libzfs.h>
-#include <libzutil.h>
-#include "libzfs_impl.h"
-
-#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
-#define ZDIFF_PREFIX "zfs-diff-%d"
-
-#define ZDIFF_ADDED '+'
-#define ZDIFF_MODIFIED "M"
-#define ZDIFF_REMOVED '-'
-#define ZDIFF_RENAMED "R"
-
-#define ZDIFF_ADDED_COLOR ANSI_GREEN
-#define ZDIFF_MODIFIED_COLOR ANSI_YELLOW
-#define ZDIFF_REMOVED_COLOR ANSI_RED
-#define ZDIFF_RENAMED_COLOR ANSI_BOLD_BLUE
-
-/*
- * Given a {dsname, object id}, get the object path
- */
-static int
-get_stats_for_obj(differ_info_t *di, const char *dsname, uint64_t obj,
- char *pn, int maxlen, zfs_stat_t *sb)
-{
- zfs_cmd_t zc = {"\0"};
- int error;
-
- (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
- zc.zc_obj = obj;
-
- errno = 0;
- error = zfs_ioctl(di->zhp->zfs_hdl, ZFS_IOC_OBJ_TO_STATS, &zc);
- di->zerr = errno;
-
- /* we can get stats even if we failed to get a path */
- (void) memcpy(sb, &zc.zc_stat, sizeof (zfs_stat_t));
- if (error == 0) {
- ASSERT0(di->zerr);
- (void) strlcpy(pn, zc.zc_value, maxlen);
- return (0);
- }
-
- if (di->zerr == ESTALE) {
- (void) snprintf(pn, maxlen, "(on_delete_queue)");
- return (0);
- } else if (di->zerr == EPERM) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "The sys_config privilege or diff delegated permission "
- "is needed\nto discover path names"));
- return (-1);
- } else if (di->zerr == EACCES) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Key must be loaded to discover path names"));
- return (-1);
- } else {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Unable to determine path or stats for "
- "object %lld in %s"), (longlong_t)obj, dsname);
- return (-1);
- }
-}
-
-/*
- * stream_bytes
- *
- * Prints a file name out a character at a time. If the character is
- * not in the range of what we consider "printable" ASCII, display it
- * as an escaped 4-digit octal value. ASCII values less than a space
- * are all control characters and we declare the upper end as the
- * DELete character. This also is the last 7-bit ASCII character.
- * We choose to treat all 8-bit ASCII as not printable for this
- * application.
- */
-static void
-stream_bytes(FILE *fp, const char *string)
-{
- char c;
-
- while ((c = *string++) != '\0') {
- if (c > ' ' && c != '\\' && c < '\177') {
- (void) fputc(c, fp);
- } else {
- (void) fprintf(fp, "\\%04hho", (uint8_t)c);
- }
- }
-}
-
-/*
- * Takes the type of change (like `print_file`), outputs the appropriate color
- */
-static const char *
-type_to_color(char type)
-{
- if (type == '+')
- return (ZDIFF_ADDED_COLOR);
- else if (type == '-')
- return (ZDIFF_REMOVED_COLOR);
- else if (type == 'M')
- return (ZDIFF_MODIFIED_COLOR);
- else if (type == 'R')
- return (ZDIFF_RENAMED_COLOR);
- else
- return (NULL);
-}
-
-
-static char
-get_what(mode_t what)
-{
- switch (what & S_IFMT) {
- case S_IFBLK:
- return ('B');
- case S_IFCHR:
- return ('C');
- case S_IFDIR:
- return ('/');
-#ifdef S_IFDOOR
- case S_IFDOOR:
- return ('>');
-#endif
- case S_IFIFO:
- return ('|');
- case S_IFLNK:
- return ('@');
-#ifdef S_IFPORT
- case S_IFPORT:
- return ('P');
-#endif
- case S_IFSOCK:
- return ('=');
- case S_IFREG:
- return ('F');
- default:
- return ('?');
- }
-}
-
-static void
-print_cmn(FILE *fp, differ_info_t *di, const char *file)
-{
- if (!di->no_mangle) {
- stream_bytes(fp, di->dsmnt);
- stream_bytes(fp, file);
- } else {
- (void) fputs(di->dsmnt, fp);
- (void) fputs(file, fp);
- }
-}
-
-static void
-print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
- zfs_stat_t *isb)
-{
- if (isatty(fileno(fp)))
- color_start(ZDIFF_RENAMED_COLOR);
- if (di->timestamped)
- (void) fprintf(fp, "%10lld.%09lld\t",
- (longlong_t)isb->zs_ctime[0],
- (longlong_t)isb->zs_ctime[1]);
- (void) fputs(ZDIFF_RENAMED "\t", fp);
- if (di->classify)
- (void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
- print_cmn(fp, di, old);
- (void) fputs(di->scripted ? "\t" : " -> ", fp);
- print_cmn(fp, di, new);
- (void) fputc('\n', fp);
-
- if (isatty(fileno(fp)))
- color_end();
-}
-
-static void
-print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
- zfs_stat_t *isb)
-{
- if (isatty(fileno(fp)))
- color_start(ZDIFF_MODIFIED_COLOR);
-
- if (di->timestamped)
- (void) fprintf(fp, "%10lld.%09lld\t",
- (longlong_t)isb->zs_ctime[0],
- (longlong_t)isb->zs_ctime[1]);
- (void) fputs(ZDIFF_MODIFIED "\t", fp);
- if (di->classify)
- (void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
- print_cmn(fp, di, file);
- (void) fprintf(fp, "\t(%+d)\n", delta);
- if (isatty(fileno(fp)))
- color_end();
-}
-
-static void
-print_file(FILE *fp, differ_info_t *di, char type, const char *file,
- zfs_stat_t *isb)
-{
- if (isatty(fileno(fp)))
- color_start(type_to_color(type));
-
- if (di->timestamped)
- (void) fprintf(fp, "%10lld.%09lld\t",
- (longlong_t)isb->zs_ctime[0],
- (longlong_t)isb->zs_ctime[1]);
- (void) fprintf(fp, "%c\t", type);
- if (di->classify)
- (void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
- print_cmn(fp, di, file);
- (void) fputc('\n', fp);
-
- if (isatty(fileno(fp)))
- color_end();
-}
-
-static int
-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;
-
- if (dobj == di->shares)
- return (0);
-
- /*
- * Check the from and to snapshots for info on the object. If
- * 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 != ENOTSUP && di->zerr != ENOENT) {
- zfs_error_aux(di->zhp->zfs_hdl, "%s", zfs_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 != ENOTSUP && di->zerr != ENOENT) {
- if (!already_logged) {
- zfs_error_aux(di->zhp->zfs_hdl,
- "%s", zfs_strerror(di->zerr));
- zfs_error(di->zhp->zfs_hdl, di->zerr, di->errbuf);
- }
- }
- /*
- * Unallocated object sharing the same meta dnode block
- */
- if (fobjerr && tobjerr) {
- di->zerr = 0;
- return (0);
- }
-
- di->zerr = 0; /* negate get_stats_for_obj() from side that failed */
- fmode = fsb.zs_mode & S_IFMT;
- tmode = tsb.zs_mode & S_IFMT;
- if (fmode == S_IFDIR || tmode == S_IFDIR || fsb.zs_links == 0 ||
- tsb.zs_links == 0)
- change = 0;
- else
- change = tsb.zs_links - fsb.zs_links;
-
- if (fobjerr) {
- if (change) {
- print_link_change(fp, di, change, tobjname, &tsb);
- return (0);
- }
- print_file(fp, di, ZDIFF_ADDED, tobjname, &tsb);
- return (0);
- } else if (tobjerr) {
- if (change) {
- print_link_change(fp, di, change, fobjname, &fsb);
- return (0);
- }
- print_file(fp, di, ZDIFF_REMOVED, fobjname, &fsb);
- return (0);
- }
-
- if (fmode != tmode && fsb.zs_gen == tsb.zs_gen)
- tsb.zs_gen++; /* Force a generational difference */
-
- /* Simple modification or no change */
- if (fsb.zs_gen == tsb.zs_gen) {
- /* No apparent changes. Could we assert !this? */
- if (fsb.zs_ctime[0] == tsb.zs_ctime[0] &&
- fsb.zs_ctime[1] == tsb.zs_ctime[1])
- return (0);
- if (change) {
- print_link_change(fp, di, change,
- change > 0 ? fobjname : tobjname, &tsb);
- } else if (strcmp(fobjname, tobjname) == 0) {
- print_file(fp, di, *ZDIFF_MODIFIED, fobjname, &tsb);
- } else {
- print_rename(fp, di, fobjname, tobjname, &tsb);
- }
- return (0);
- } else {
- /* file re-created or object re-used */
- print_file(fp, di, ZDIFF_REMOVED, fobjname, &fsb);
- print_file(fp, di, ZDIFF_ADDED, tobjname, &tsb);
- return (0);
- }
-}
-
-static int
-write_inuse_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
-{
- uint64_t o;
- int err;
-
- for (o = dr->ddr_first; o <= dr->ddr_last; o++) {
- if ((err = write_inuse_diffs_one(fp, di, o)) != 0)
- return (err);
- }
- return (0);
-}
-
-static int
-describe_free(FILE *fp, differ_info_t *di, uint64_t object, char *namebuf,
- int maxlen)
-{
- struct zfs_stat sb;
-
- (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 || di->zerr == ENOENT) {
- di->zerr = 0;
- return (0);
- }
-
- print_file(fp, di, ZDIFF_REMOVED, namebuf, &sb);
- return (0);
-}
-
-static int
-write_free_diffs(FILE *fp, differ_info_t *di, dmu_diff_record_t *dr)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *lhdl = di->zhp->zfs_hdl;
- char fobjname[MAXPATHLEN];
-
- (void) strlcpy(zc.zc_name, di->fromsnap, sizeof (zc.zc_name));
- zc.zc_obj = dr->ddr_first - 1;
-
- ASSERT0(di->zerr);
-
- while (zc.zc_obj < dr->ddr_last) {
- int err;
-
- err = zfs_ioctl(lhdl, ZFS_IOC_NEXT_OBJ, &zc);
- if (err == 0) {
- if (zc.zc_obj == di->shares) {
- zc.zc_obj++;
- continue;
- }
- if (zc.zc_obj > dr->ddr_last) {
- break;
- }
- (void) describe_free(fp, di, zc.zc_obj, fobjname,
- MAXPATHLEN);
- } else if (errno == ESRCH) {
- break;
- } else {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "next allocated object (> %lld) find failure"),
- (longlong_t)zc.zc_obj);
- di->zerr = errno;
- break;
- }
- }
- if (di->zerr)
- return (-1);
- return (0);
-}
-
-static void *
-differ(void *arg)
-{
- differ_info_t *di = arg;
- dmu_diff_record_t dr;
- FILE *ofp;
- int err = 0;
-
- if ((ofp = fdopen(di->outputfd, "w")) == NULL) {
- di->zerr = errno;
- strlcpy(di->errbuf, zfs_strerror(errno), sizeof (di->errbuf));
- (void) close(di->datafd);
- return ((void *)-1);
- }
-
- for (;;) {
- char *cp = (char *)&dr;
- int len = sizeof (dr);
- int rv;
-
- do {
- rv = read(di->datafd, cp, len);
- cp += rv;
- len -= rv;
- } while (len > 0 && rv > 0);
-
- if (rv < 0 || (rv == 0 && len != sizeof (dr))) {
- di->zerr = EPIPE;
- break;
- } else if (rv == 0) {
- /* end of file at a natural breaking point */
- break;
- }
-
- switch (dr.ddr_type) {
- case DDR_FREE:
- err = write_free_diffs(ofp, di, &dr);
- break;
- case DDR_INUSE:
- err = write_inuse_diffs(ofp, di, &dr);
- break;
- default:
- di->zerr = EPIPE;
- break;
- }
-
- if (err || di->zerr)
- break;
- }
-
- (void) fclose(ofp);
- (void) close(di->datafd);
- if (err)
- return ((void *)-1);
- if (di->zerr) {
- ASSERT(di->zerr == EPIPE);
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Internal error: bad data from diff IOCTL"));
- return ((void *)-1);
- }
- return ((void *)0);
-}
-
-static int
-make_temp_snapshot(differ_info_t *di)
-{
- libzfs_handle_t *hdl = di->zhp->zfs_hdl;
- zfs_cmd_t zc = {"\0"};
-
- (void) snprintf(zc.zc_value, sizeof (zc.zc_value),
- ZDIFF_PREFIX, getpid());
- (void) strlcpy(zc.zc_name, di->ds, sizeof (zc.zc_name));
- zc.zc_cleanup_fd = di->cleanupfd;
-
- if (zfs_ioctl(hdl, ZFS_IOC_TMP_SNAPSHOT, &zc) != 0) {
- int err = errno;
- if (err == EPERM) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN, "The diff delegated "
- "permission is needed in order\nto create a "
- "just-in-time snapshot for diffing\n"));
- return (zfs_error(hdl, EZFS_DIFF, di->errbuf));
- } else {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN, "Cannot create just-in-time "
- "snapshot of '%s'"), zc.zc_name);
- return (zfs_standard_error(hdl, err, di->errbuf));
- }
- }
-
- di->tmpsnap = zfs_strdup(hdl, zc.zc_value);
- di->tosnap = zfs_asprintf(hdl, "%s@%s", di->ds, di->tmpsnap);
- return (0);
-}
-
-static void
-teardown_differ_info(differ_info_t *di)
-{
- free(di->ds);
- free(di->dsmnt);
- free(di->fromsnap);
- free(di->frommnt);
- free(di->tosnap);
- free(di->tmpsnap);
- free(di->tomnt);
- (void) close(di->cleanupfd);
-}
-
-static int
-get_snapshot_names(differ_info_t *di, const char *fromsnap,
- const char *tosnap)
-{
- libzfs_handle_t *hdl = di->zhp->zfs_hdl;
- char *atptrf = NULL;
- char *atptrt = NULL;
- int fdslen, fsnlen;
- int tdslen, tsnlen;
-
- /*
- * Can accept
- * fdslen fsnlen tdslen tsnlen
- * dataset@snap1
- * 0. dataset@snap1 dataset@snap2 >0 >1 >0 >1
- * 1. dataset@snap1 @snap2 >0 >1 ==0 >1
- * 2. dataset@snap1 dataset >0 >1 >0 ==0
- * 3. @snap1 dataset@snap2 ==0 >1 >0 >1
- * 4. @snap1 dataset ==0 >1 >0 ==0
- */
- if (tosnap == NULL) {
- /* only a from snapshot given, must be valid */
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Badly formed snapshot name %s"), fromsnap);
-
- if (!zfs_validate_name(hdl, fromsnap, ZFS_TYPE_SNAPSHOT,
- B_FALSE)) {
- return (zfs_error(hdl, EZFS_INVALIDNAME,
- di->errbuf));
- }
-
- atptrf = strchr(fromsnap, '@');
- ASSERT(atptrf != NULL);
- fdslen = atptrf - fromsnap;
-
- di->fromsnap = zfs_strdup(hdl, fromsnap);
- di->ds = zfs_strdup(hdl, fromsnap);
- di->ds[fdslen] = '\0';
-
- /* the to snap will be a just-in-time snap of the head */
- return (make_temp_snapshot(di));
- }
-
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Unable to determine which snapshots to compare"));
-
- atptrf = strchr(fromsnap, '@');
- atptrt = strchr(tosnap, '@');
- fdslen = atptrf ? atptrf - fromsnap : strlen(fromsnap);
- tdslen = atptrt ? atptrt - tosnap : strlen(tosnap);
- fsnlen = strlen(fromsnap) - fdslen; /* includes @ sign */
- tsnlen = strlen(tosnap) - tdslen; /* includes @ sign */
-
- if (fsnlen <= 1 || tsnlen == 1 || (fdslen == 0 && tdslen == 0)) {
- return (zfs_error(hdl, EZFS_INVALIDNAME, di->errbuf));
- } else if ((fdslen > 0 && tdslen > 0) &&
- ((tdslen != fdslen || strncmp(fromsnap, tosnap, fdslen) != 0))) {
- /*
- * not the same dataset name, might be okay if
- * tosnap is a clone of a fromsnap descendant.
- */
- char origin[ZFS_MAX_DATASET_NAME_LEN];
- zprop_source_t src;
- zfs_handle_t *zhp;
-
- di->ds = zfs_alloc(di->zhp->zfs_hdl, tdslen + 1);
- (void) strlcpy(di->ds, tosnap, tdslen + 1);
-
- zhp = zfs_open(hdl, di->ds, ZFS_TYPE_FILESYSTEM);
- while (zhp != NULL) {
- if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin,
- sizeof (origin), &src, NULL, 0, B_FALSE) != 0) {
- (void) zfs_close(zhp);
- zhp = NULL;
- break;
- }
- if (strncmp(origin, fromsnap, fsnlen) == 0)
- break;
-
- (void) zfs_close(zhp);
- zhp = zfs_open(hdl, origin, ZFS_TYPE_FILESYSTEM);
- }
-
- if (zhp == NULL) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Not an earlier snapshot from the same fs"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, di->errbuf));
- } else {
- (void) zfs_close(zhp);
- }
-
- di->isclone = B_TRUE;
- di->fromsnap = zfs_strdup(hdl, fromsnap);
- if (tsnlen)
- di->tosnap = zfs_strdup(hdl, tosnap);
- else
- return (make_temp_snapshot(di));
- } else {
- int dslen = fdslen ? fdslen : tdslen;
-
- di->ds = zfs_alloc(hdl, dslen + 1);
- (void) strlcpy(di->ds, fdslen ? fromsnap : tosnap, dslen + 1);
-
- di->fromsnap = zfs_asprintf(hdl, "%s%s", di->ds, atptrf);
- if (tsnlen) {
- di->tosnap = zfs_asprintf(hdl, "%s%s", di->ds, atptrt);
- } else {
- return (make_temp_snapshot(di));
- }
- }
- return (0);
-}
-
-static int
-get_mountpoint(differ_info_t *di, char *dsnm, char **mntpt)
-{
- boolean_t mounted;
-
- mounted = is_mounted(di->zhp->zfs_hdl, dsnm, mntpt);
- if (mounted == B_FALSE) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN,
- "Cannot diff an unmounted snapshot"));
- return (zfs_error(di->zhp->zfs_hdl, EZFS_BADTYPE, di->errbuf));
- }
-
- /* Avoid a double slash at the beginning of root-mounted datasets */
- if (**mntpt == '/' && *(*mntpt + 1) == '\0')
- **mntpt = '\0';
- return (0);
-}
-
-static int
-get_mountpoints(differ_info_t *di)
-{
- char *strptr;
- char *frommntpt;
-
- /*
- * first get the mountpoint for the parent dataset
- */
- if (get_mountpoint(di, di->ds, &di->dsmnt) != 0)
- return (-1);
-
- strptr = strchr(di->tosnap, '@');
- ASSERT3P(strptr, !=, NULL);
- di->tomnt = zfs_asprintf(di->zhp->zfs_hdl, "%s%s%s", di->dsmnt,
- ZDIFF_SNAPDIR, ++strptr);
-
- strptr = strchr(di->fromsnap, '@');
- ASSERT3P(strptr, !=, NULL);
-
- frommntpt = di->dsmnt;
- if (di->isclone) {
- char *mntpt;
- int err;
-
- *strptr = '\0';
- err = get_mountpoint(di, di->fromsnap, &mntpt);
- *strptr = '@';
- if (err != 0)
- return (-1);
- frommntpt = mntpt;
- }
-
- di->frommnt = zfs_asprintf(di->zhp->zfs_hdl, "%s%s%s", frommntpt,
- ZDIFF_SNAPDIR, ++strptr);
-
- if (di->isclone)
- free(frommntpt);
-
- return (0);
-}
-
-static int
-setup_differ_info(zfs_handle_t *zhp, const char *fromsnap,
- const char *tosnap, differ_info_t *di)
-{
- di->zhp = zhp;
-
- di->cleanupfd = open(ZFS_DEV, O_RDWR | O_CLOEXEC);
- VERIFY(di->cleanupfd >= 0);
-
- if (get_snapshot_names(di, fromsnap, tosnap) != 0)
- return (-1);
-
- if (get_mountpoints(di) != 0)
- return (-1);
-
- if (find_shares_object(di) != 0)
- return (-1);
-
- return (0);
-}
-
-int
-zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap,
- const char *tosnap, int flags)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- differ_info_t di = { 0 };
- pthread_t tid;
- int pipefd[2];
- int iocerr;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "zfs diff failed"));
-
- if (setup_differ_info(zhp, fromsnap, tosnap, &di)) {
- teardown_differ_info(&di);
- return (-1);
- }
-
- if (pipe2(pipefd, O_CLOEXEC)) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno));
- teardown_differ_info(&di);
- return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED, errbuf));
- }
-
- di.scripted = (flags & ZFS_DIFF_PARSEABLE);
- di.classify = (flags & ZFS_DIFF_CLASSIFY);
- di.timestamped = (flags & ZFS_DIFF_TIMESTAMP);
- di.no_mangle = (flags & ZFS_DIFF_NO_MANGLE);
-
- di.outputfd = outfd;
- di.datafd = pipefd[0];
-
- if (pthread_create(&tid, NULL, differ, &di)) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno));
- (void) close(pipefd[0]);
- (void) close(pipefd[1]);
- teardown_differ_info(&di);
- return (zfs_error(zhp->zfs_hdl,
- EZFS_THREADCREATEFAILED, errbuf));
- }
-
- /* do the ioctl() */
- (void) strlcpy(zc.zc_value, di.fromsnap, strlen(di.fromsnap) + 1);
- (void) strlcpy(zc.zc_name, di.tosnap, strlen(di.tosnap) + 1);
- zc.zc_cookie = pipefd[1];
-
- iocerr = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DIFF, &zc);
- if (iocerr != 0) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Unable to obtain diffs"));
- if (errno == EPERM) {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "\n The sys_mount privilege or diff delegated "
- "permission is needed\n to execute the "
- "diff ioctl"));
- } else if (errno == EXDEV) {
- 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, "%s", zfs_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, "%s",
- zfs_strerror(di.zerr));
- return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf));
- } else {
- return (zfs_error(zhp->zfs_hdl, EZFS_DIFFDATA, errbuf));
- }
- }
-
- (void) close(pipefd[1]);
- (void) pthread_join(tid, NULL);
-
- if (di.zerr != 0) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(di.zerr));
- return (zfs_error(zhp->zfs_hdl, EZFS_DIFF, di.errbuf));
- }
- teardown_differ_info(&di);
- return (0);
-}
diff --git a/lib/libzfs/libzfs_impl.h b/lib/libzfs/libzfs_impl.h
deleted file mode 100644
index 9053740ec2f0..000000000000
--- a/lib/libzfs/libzfs_impl.h
+++ /dev/null
@@ -1,242 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
- * Copyright (c) 2018 Datto Inc.
- * Copyright 2020 Joyent, Inc.
- */
-
-#ifndef _LIBZFS_IMPL_H
-#define _LIBZFS_IMPL_H
-
-#include <sys/fs/zfs.h>
-#include <sys/nvpair.h>
-#include <sys/dmu.h>
-#include <sys/zfs_ioctl.h>
-#include <regex.h>
-
-#include <libuutil.h>
-#include <libzfs.h>
-#include <libshare.h>
-#include <libzfs_core.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ERRBUFLEN 1024
-
-struct libzfs_handle {
- int libzfs_error;
- int libzfs_fd;
- zpool_handle_t *libzfs_pool_handles;
- uu_avl_pool_t *libzfs_ns_avlpool;
- uu_avl_t *libzfs_ns_avl;
- uint64_t libzfs_ns_gen;
- int libzfs_desc_active;
- char libzfs_action[1024];
- char libzfs_desc[1024];
- int libzfs_printerr;
- boolean_t libzfs_mnttab_enable;
- /*
- * We need a lock to handle the case where parallel mount
- * threads are populating the mnttab cache simultaneously. The
- * lock only protects the integrity of the avl tree, and does
- * not protect the contents of the mnttab entries themselves.
- */
- pthread_mutex_t libzfs_mnttab_cache_lock;
- avl_tree_t libzfs_mnttab_cache;
- int libzfs_pool_iter;
- boolean_t libzfs_prop_debug;
- regex_t libzfs_urire;
- uint64_t libzfs_max_nvlist;
- void *libfetch;
- char *libfetch_load_error;
-};
-
-struct zfs_handle {
- libzfs_handle_t *zfs_hdl;
- zpool_handle_t *zpool_hdl;
- char zfs_name[ZFS_MAX_DATASET_NAME_LEN];
- zfs_type_t zfs_type; /* type including snapshot */
- zfs_type_t zfs_head_type; /* type excluding snapshot */
- dmu_objset_stats_t zfs_dmustats;
- nvlist_t *zfs_props;
- nvlist_t *zfs_user_props;
- nvlist_t *zfs_recvd_props;
- boolean_t zfs_mntcheck;
- char *zfs_mntopts;
- uint8_t *zfs_props_table;
-};
-
-/*
- * This is different from checking zfs_type, because it will also catch
- * snapshots of volumes.
- */
-#define ZFS_IS_VOLUME(zhp) ((zhp)->zfs_head_type == ZFS_TYPE_VOLUME)
-#define ZHP_MAX_PROPNAMES 4
-
-struct zpool_handle {
- libzfs_handle_t *zpool_hdl;
- zpool_handle_t *zpool_next;
- char zpool_name[ZFS_MAX_DATASET_NAME_LEN];
- int zpool_state;
- unsigned int zpool_n_propnames;
- const char *zpool_propnames[ZHP_MAX_PROPNAMES];
- size_t zpool_config_size;
- nvlist_t *zpool_config;
- nvlist_t *zpool_old_config;
- nvlist_t *zpool_props;
- diskaddr_t zpool_start_block;
-};
-
-typedef int (*zfs_uri_handler_fn_t)(struct libzfs_handle *, const char *,
- const char *, zfs_keyformat_t, boolean_t, uint8_t **, size_t *);
-
-typedef struct zfs_uri_handler {
- const char *zuh_scheme;
- zfs_uri_handler_fn_t zuh_handler;
-} zfs_uri_handler_t;
-
-#define CONFIG_BUF_MINSIZE 262144
-
-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 *);
-
-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)));
-
-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 *);
-
-extern int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
- nvlist_t *, const char **, uint64_t *, const char *);
-extern int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
- zfs_type_t type);
-
-/*
- * Use this changelist_gather() flag to force attempting mounts
- * on each change node regardless of whether or not it is currently
- * mounted.
- */
-#define CL_GATHER_MOUNT_ALWAYS 1
-/*
- * changelist_gather() flag to force it to iterate on mounted datasets only
- */
-#define CL_GATHER_ITER_MOUNTED 2
-/*
- * Use this changelist_gather() flag to prevent unmounting of file systems.
- */
-#define CL_GATHER_DONT_UNMOUNT 4
-
-typedef struct prop_changelist prop_changelist_t;
-
-extern void zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
-extern void zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
-extern void zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
-extern void 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 *);
-
-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 *, const enum sa_protocol *);
-extern int changelist_haszonedchild(prop_changelist_t *);
-
-extern void remove_mountpoint(zfs_handle_t *);
-extern int create_parents(libzfs_handle_t *, char *, int);
-
-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);
-
-extern int zpool_open_silent(libzfs_handle_t *, const char *,
- zpool_handle_t **);
-
-extern boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
-
-extern int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
- boolean_t modifying);
-
-extern void namespace_clear(libzfs_handle_t *);
-
-typedef struct {
- zfs_prop_t p_prop;
- int p_share_err;
- int p_unshare_err;
-} proto_table_t;
-
-typedef struct differ_info {
- zfs_handle_t *zhp;
- char *fromsnap;
- char *frommnt;
- char *tosnap;
- char *tomnt;
- char *ds;
- char *dsmnt;
- char *tmpsnap;
- char errbuf[ERRBUFLEN];
- boolean_t isclone;
- boolean_t scripted;
- boolean_t classify;
- boolean_t timestamped;
- boolean_t no_mangle;
- uint64_t shares;
- int zerr;
- int cleanupfd;
- int outputfd;
- int datafd;
-} differ_info_t;
-
-extern int do_mount(zfs_handle_t *zhp, const char *mntpt, const char *opts,
- int flags);
-extern int do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags);
-extern int libzfs_load_module(void);
-extern int zpool_relabel_disk(libzfs_handle_t *hdl, const char *path,
- const char *msg);
-extern int find_shares_object(differ_info_t *di);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LIBZFS_IMPL_H */
diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c
deleted file mode 100644
index 7f276e9592c9..000000000000
--- a/lib/libzfs/libzfs_import.c
+++ /dev/null
@@ -1,438 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
- * Copyright 2015 RackTop Systems.
- * Copyright (c) 2016, Intel Corporation.
- */
-
-#include <errno.h>
-#include <libintl.h>
-#include <libgen.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/vdev_impl.h>
-#include <libzfs.h>
-#include "libzfs_impl.h"
-#include <libzutil.h>
-#include <sys/arc_impl.h>
-
-/*
- * Returns true if the named pool matches the given GUID.
- */
-static int
-pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
- boolean_t *isactive)
-{
- zpool_handle_t *zhp;
-
- if (zpool_open_silent(hdl, name, &zhp) != 0)
- return (-1);
-
- if (zhp == NULL) {
- *isactive = B_FALSE;
- return (0);
- }
-
- uint64_t theguid = fnvlist_lookup_uint64(zhp->zpool_config,
- ZPOOL_CONFIG_POOL_GUID);
-
- zpool_close(zhp);
-
- *isactive = (theguid == guid);
- return (0);
-}
-
-static nvlist_t *
-refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
-{
- nvlist_t *nvl;
- zfs_cmd_t zc = {"\0"};
- int err, dstbuf_size;
-
- zcmd_write_conf_nvlist(hdl, &zc, config);
-
- dstbuf_size = MAX(CONFIG_BUF_MINSIZE, zc.zc_nvlist_conf_size * 32);
-
- zcmd_alloc_dst_nvlist(hdl, &zc, dstbuf_size);
-
- while ((err = zfs_ioctl(hdl, ZFS_IOC_POOL_TRYIMPORT,
- &zc)) != 0 && errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
-
- if (err) {
- zcmd_free_nvlists(&zc);
- return (NULL);
- }
-
- if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
- zcmd_free_nvlists(&zc);
- return (NULL);
- }
-
- zcmd_free_nvlists(&zc);
- return (nvl);
-}
-
-static nvlist_t *
-refresh_config_libzfs(void *handle, nvlist_t *tryconfig)
-{
- return (refresh_config((libzfs_handle_t *)handle, tryconfig));
-}
-
-static int
-pool_active_libzfs(void *handle, const char *name, uint64_t guid,
- boolean_t *isactive)
-{
- return (pool_active((libzfs_handle_t *)handle, name, guid, isactive));
-}
-
-const pool_config_ops_t libzfs_config_ops = {
- .pco_refresh_config = refresh_config_libzfs,
- .pco_pool_active = pool_active_libzfs,
-};
-
-/*
- * Return the offset of the given label.
- */
-static uint64_t
-label_offset(uint64_t size, int l)
-{
- ASSERT0(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t));
- return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
- 0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
-}
-
-/*
- * Given a file descriptor, clear (zero) the label information. This function
- * is used in the appliance stack as part of the ZFS sysevent module and
- * to implement the "zpool labelclear" command.
- */
-int
-zpool_clear_label(int fd)
-{
- struct stat64 statbuf;
- int l;
- vdev_label_t *label;
- uint64_t size;
- boolean_t labels_cleared = B_FALSE, clear_l2arc_header = B_FALSE,
- header_cleared = B_FALSE;
-
- if (fstat64_blk(fd, &statbuf) == -1)
- return (0);
-
- size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
-
- if ((label = calloc(1, sizeof (vdev_label_t))) == NULL)
- return (-1);
-
- for (l = 0; l < VDEV_LABELS; l++) {
- uint64_t state, guid, l2cache;
- nvlist_t *config;
-
- if (pread64(fd, label, sizeof (vdev_label_t),
- label_offset(size, l)) != sizeof (vdev_label_t)) {
- continue;
- }
-
- if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
- sizeof (label->vl_vdev_phys.vp_nvlist), &config, 0) != 0) {
- continue;
- }
-
- /* Skip labels which do not have a valid guid. */
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
- &guid) != 0 || guid == 0) {
- nvlist_free(config);
- continue;
- }
-
- /* Skip labels which are not in a known valid state. */
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
- &state) != 0 || state > POOL_STATE_L2CACHE) {
- nvlist_free(config);
- continue;
- }
-
- /* If the device is a cache device clear the header. */
- if (!clear_l2arc_header) {
- if (nvlist_lookup_uint64(config,
- ZPOOL_CONFIG_POOL_STATE, &l2cache) == 0 &&
- l2cache == POOL_STATE_L2CACHE) {
- clear_l2arc_header = B_TRUE;
- }
- }
-
- nvlist_free(config);
-
- /*
- * A valid label was found, overwrite this label's nvlist
- * and uberblocks with zeros on disk. This is done to prevent
- * system utilities, like blkid, from incorrectly detecting a
- * partial label. The leading pad space is left untouched.
- */
- memset(label, 0, sizeof (vdev_label_t));
- size_t label_size = sizeof (vdev_label_t) - (2 * VDEV_PAD_SIZE);
-
- if (pwrite64(fd, label, label_size, label_offset(size, l) +
- (2 * VDEV_PAD_SIZE)) == label_size)
- labels_cleared = B_TRUE;
- }
-
- if (clear_l2arc_header) {
- _Static_assert(sizeof (*label) >= sizeof (l2arc_dev_hdr_phys_t),
- "label < l2arc_dev_hdr_phys_t");
- memset(label, 0, sizeof (l2arc_dev_hdr_phys_t));
- if (pwrite64(fd, label, sizeof (l2arc_dev_hdr_phys_t),
- VDEV_LABEL_START_SIZE) == sizeof (l2arc_dev_hdr_phys_t))
- header_cleared = B_TRUE;
- }
-
- free(label);
-
- if (!labels_cleared || (clear_l2arc_header && !header_cleared))
- return (-1);
-
- return (0);
-}
-
-static boolean_t
-find_guid(nvlist_t *nv, uint64_t guid)
-{
- nvlist_t **child;
- uint_t c, children;
-
- if (fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID) == guid)
- return (B_TRUE);
-
- if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
- &child, &children) == 0) {
- for (c = 0; c < children; c++)
- if (find_guid(child[c], guid))
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-typedef struct aux_cbdata {
- const char *cb_type;
- uint64_t cb_guid;
- zpool_handle_t *cb_zhp;
-} aux_cbdata_t;
-
-static int
-find_aux(zpool_handle_t *zhp, void *data)
-{
- aux_cbdata_t *cbp = data;
- nvlist_t **list;
- uint_t count;
-
- nvlist_t *nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE);
-
- if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
- &list, &count) == 0) {
- for (uint_t i = 0; i < count; i++) {
- uint64_t guid = fnvlist_lookup_uint64(list[i],
- ZPOOL_CONFIG_GUID);
- if (guid == cbp->cb_guid) {
- cbp->cb_zhp = zhp;
- return (1);
- }
- }
- }
-
- zpool_close(zhp);
- return (0);
-}
-
-/*
- * Determines if the pool is in use. If so, it returns true and the state of
- * the pool as well as the name of the pool. Name string is allocated and
- * must be freed by the caller.
- */
-int
-zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
- boolean_t *inuse)
-{
- nvlist_t *config;
- const char *name = NULL;
- boolean_t ret;
- uint64_t guid = 0, vdev_guid;
- zpool_handle_t *zhp;
- nvlist_t *pool_config;
- uint64_t stateval, isspare;
- aux_cbdata_t cb = { 0 };
- boolean_t isactive;
-
- *inuse = B_FALSE;
-
- if (zpool_read_label(fd, &config, NULL) != 0)
- return (-1);
-
- if (config == NULL)
- return (0);
-
- stateval = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE);
- vdev_guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID);
-
- if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
- name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
- guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID);
- }
-
- switch (stateval) {
- case POOL_STATE_EXPORTED:
- /*
- * A pool with an exported state may in fact be imported
- * read-only, so check the in-core state to see if it's
- * active and imported read-only. If it is, set
- * its state to active.
- */
- if (pool_active(hdl, name, guid, &isactive) == 0 && isactive &&
- (zhp = zpool_open_canfail(hdl, name)) != NULL) {
- if (zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL))
- stateval = POOL_STATE_ACTIVE;
-
- /*
- * All we needed the zpool handle for is the
- * readonly prop check.
- */
- zpool_close(zhp);
- }
-
- ret = B_TRUE;
- break;
-
- case POOL_STATE_ACTIVE:
- /*
- * For an active pool, we have to determine if it's really part
- * of a currently active pool (in which case the pool will exist
- * and the guid will be the same), or whether it's part of an
- * active pool that was disconnected without being explicitly
- * exported.
- */
- if (pool_active(hdl, name, guid, &isactive) != 0) {
- nvlist_free(config);
- return (-1);
- }
-
- if (isactive) {
- /*
- * Because the device may have been removed while
- * offlined, we only report it as active if the vdev is
- * still present in the config. Otherwise, pretend like
- * it's not in use.
- */
- if ((zhp = zpool_open_canfail(hdl, name)) != NULL &&
- (pool_config = zpool_get_config(zhp, NULL))
- != NULL) {
- nvlist_t *nvroot = fnvlist_lookup_nvlist(
- pool_config, ZPOOL_CONFIG_VDEV_TREE);
- ret = find_guid(nvroot, vdev_guid);
- } else {
- ret = B_FALSE;
- }
-
- /*
- * If this is an active spare within another pool, we
- * treat it like an unused hot spare. This allows the
- * user to create a pool with a hot spare that currently
- * in use within another pool. Since we return B_TRUE,
- * libdiskmgt will continue to prevent generic consumers
- * from using the device.
- */
- if (ret && nvlist_lookup_uint64(config,
- ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
- stateval = POOL_STATE_SPARE;
-
- if (zhp != NULL)
- zpool_close(zhp);
- } else {
- stateval = POOL_STATE_POTENTIALLY_ACTIVE;
- ret = B_TRUE;
- }
- break;
-
- case POOL_STATE_SPARE:
- /*
- * For a hot spare, it can be either definitively in use, or
- * potentially active. To determine if it's in use, we iterate
- * over all pools in the system and search for one with a spare
- * with a matching guid.
- *
- * Due to the shared nature of spares, we don't actually report
- * the potentially active case as in use. This means the user
- * can freely create pools on the hot spares of exported pools,
- * but to do otherwise makes the resulting code complicated, and
- * we end up having to deal with this case anyway.
- */
- cb.cb_zhp = NULL;
- cb.cb_guid = vdev_guid;
- cb.cb_type = ZPOOL_CONFIG_SPARES;
- if (zpool_iter(hdl, find_aux, &cb) == 1) {
- name = (char *)zpool_get_name(cb.cb_zhp);
- ret = B_TRUE;
- } else {
- ret = B_FALSE;
- }
- break;
-
- case POOL_STATE_L2CACHE:
-
- /*
- * Check if any pool is currently using this l2cache device.
- */
- cb.cb_zhp = NULL;
- cb.cb_guid = vdev_guid;
- cb.cb_type = ZPOOL_CONFIG_L2CACHE;
- if (zpool_iter(hdl, find_aux, &cb) == 1) {
- name = (char *)zpool_get_name(cb.cb_zhp);
- ret = B_TRUE;
- } else {
- ret = B_FALSE;
- }
- break;
-
- default:
- ret = B_FALSE;
- }
-
-
- if (ret) {
- *namestr = zfs_strdup(hdl, name);
- *state = (pool_state_t)stateval;
- }
-
- if (cb.cb_zhp)
- zpool_close(cb.cb_zhp);
-
- nvlist_free(config);
- *inuse = ret;
- return (0);
-}
diff --git a/lib/libzfs/libzfs_iter.c b/lib/libzfs/libzfs_iter.c
deleted file mode 100644
index 1844ce1624b3..000000000000
--- a/lib/libzfs/libzfs_iter.c
+++ /dev/null
@@ -1,655 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, 2019 by Delphix. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2019 Datto Inc.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stddef.h>
-#include <libintl.h>
-#include <libzfs.h>
-#include <libzutil.h>
-#include <sys/mntent.h>
-
-#include "libzfs_impl.h"
-
-static int
-zfs_iter_clones(zfs_handle_t *zhp, int flags __maybe_unused, zfs_iter_f func,
- void *data)
-{
- nvlist_t *nvl = zfs_get_clones_nvl(zhp);
- nvpair_t *pair;
-
- if (nvl == NULL)
- return (0);
-
- for (pair = nvlist_next_nvpair(nvl, NULL); pair != NULL;
- pair = nvlist_next_nvpair(nvl, pair)) {
- zfs_handle_t *clone = zfs_open(zhp->zfs_hdl, nvpair_name(pair),
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (clone != NULL) {
- int err = func(clone, data);
- if (err != 0)
- return (err);
- }
- }
- return (0);
-}
-
-static int
-zfs_do_list_ioctl(zfs_handle_t *zhp, int arg, zfs_cmd_t *zc)
-{
- int rc;
- uint64_t orig_cookie;
-
- orig_cookie = zc->zc_cookie;
-top:
- (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
- zc->zc_objset_stats.dds_creation_txg = 0;
- rc = zfs_ioctl(zhp->zfs_hdl, arg, zc);
-
- if (rc == -1) {
- switch (errno) {
- case ENOMEM:
- /* expand nvlist memory and try again */
- zcmd_expand_dst_nvlist(zhp->zfs_hdl, zc);
- zc->zc_cookie = orig_cookie;
- goto top;
- /*
- * An errno value of ESRCH indicates normal completion.
- * If ENOENT is returned, then the underlying dataset
- * has been removed since we obtained the handle.
- */
- case ESRCH:
- case ENOENT:
- rc = 1;
- break;
- default:
- rc = zfs_standard_error(zhp->zfs_hdl, errno,
- dgettext(TEXT_DOMAIN,
- "cannot iterate filesystems"));
- break;
- }
- }
- return (rc);
-}
-
-/*
- * Iterate over all child filesystems
- */
-int
-zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
-{
- return (zfs_iter_filesystems_v2(zhp, 0, func, data));
-}
-
-int
-zfs_iter_filesystems_v2(zfs_handle_t *zhp, int flags, zfs_iter_f func,
- void *data)
-{
- zfs_cmd_t zc = {"\0"};
- zfs_handle_t *nzhp;
- int ret;
-
- if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
- return (0);
-
- zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
-
- if ((flags & ZFS_ITER_SIMPLE) == ZFS_ITER_SIMPLE)
- zc.zc_simple = B_TRUE;
-
- while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT,
- &zc)) == 0) {
- if (zc.zc_simple)
- nzhp = make_dataset_simple_handle_zc(zhp, &zc);
- else
- nzhp = make_dataset_handle_zc(zhp->zfs_hdl, &zc);
- /*
- * Silently ignore errors, as the only plausible explanation is
- * that the pool has since been removed.
- */
- if (nzhp == NULL)
- continue;
-
- if ((ret = func(nzhp, data)) != 0) {
- zcmd_free_nvlists(&zc);
- return (ret);
- }
- }
- zcmd_free_nvlists(&zc);
- return ((ret < 0) ? ret : 0);
-}
-
-/*
- * Iterate over all snapshots
- */
-int
-zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
- void *data, uint64_t min_txg, uint64_t max_txg)
-{
- return (zfs_iter_snapshots_v2(zhp, simple ? ZFS_ITER_SIMPLE : 0, func,
- data, min_txg, max_txg));
-}
-
-int
-zfs_iter_snapshots_v2(zfs_handle_t *zhp, int flags, zfs_iter_f func,
- void *data, uint64_t min_txg, uint64_t max_txg)
-{
- zfs_cmd_t zc = {"\0"};
- zfs_handle_t *nzhp;
- int ret;
- nvlist_t *range_nvl = NULL;
-
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT ||
- zhp->zfs_type == ZFS_TYPE_BOOKMARK)
- return (0);
-
- zc.zc_simple = (flags & ZFS_ITER_SIMPLE) != 0;
-
- zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
-
- if (min_txg != 0) {
- range_nvl = fnvlist_alloc();
- fnvlist_add_uint64(range_nvl, SNAP_ITER_MIN_TXG, min_txg);
- }
- if (max_txg != 0) {
- if (range_nvl == NULL)
- range_nvl = fnvlist_alloc();
- fnvlist_add_uint64(range_nvl, SNAP_ITER_MAX_TXG, max_txg);
- }
-
- if (range_nvl != NULL)
- zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, range_nvl);
-
- while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
- &zc)) == 0) {
-
- if (zc.zc_simple)
- nzhp = make_dataset_simple_handle_zc(zhp, &zc);
- else
- nzhp = make_dataset_handle_zc(zhp->zfs_hdl, &zc);
- if (nzhp == NULL)
- continue;
-
- if ((ret = func(nzhp, data)) != 0) {
- zcmd_free_nvlists(&zc);
- fnvlist_free(range_nvl);
- return (ret);
- }
- }
- zcmd_free_nvlists(&zc);
- fnvlist_free(range_nvl);
- return ((ret < 0) ? ret : 0);
-}
-
-/*
- * Iterate over all bookmarks
- */
-int
-zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
-{
- return (zfs_iter_bookmarks_v2(zhp, 0, func, data));
-}
-
-int
-zfs_iter_bookmarks_v2(zfs_handle_t *zhp, int flags __maybe_unused,
- zfs_iter_f func, void *data)
-{
- zfs_handle_t *nzhp;
- nvlist_t *props = NULL;
- nvlist_t *bmarks = NULL;
- int err;
- nvpair_t *pair;
-
- if ((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK)) != 0)
- return (0);
-
- /* Setup the requested properties nvlist. */
- props = fnvlist_alloc();
- for (zfs_prop_t p = 0; p < ZFS_NUM_PROPS; p++) {
- if (zfs_prop_valid_for_type(p, ZFS_TYPE_BOOKMARK, B_FALSE)) {
- fnvlist_add_boolean(props, zfs_prop_to_name(p));
- }
- }
- fnvlist_add_boolean(props, "redact_complete");
-
- if ((err = lzc_get_bookmarks(zhp->zfs_name, props, &bmarks)) != 0)
- goto out;
-
- for (pair = nvlist_next_nvpair(bmarks, NULL);
- pair != NULL; pair = nvlist_next_nvpair(bmarks, pair)) {
- char name[ZFS_MAX_DATASET_NAME_LEN];
- const char *bmark_name;
- nvlist_t *bmark_props;
-
- bmark_name = nvpair_name(pair);
- bmark_props = fnvpair_value_nvlist(pair);
-
- if (snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
- bmark_name) >= sizeof (name)) {
- err = EINVAL;
- goto out;
- }
-
- nzhp = make_bookmark_handle(zhp, name, bmark_props);
- if (nzhp == NULL)
- continue;
-
- if ((err = func(nzhp, data)) != 0)
- goto out;
- }
-
-out:
- fnvlist_free(props);
- fnvlist_free(bmarks);
-
- return (err);
-}
-
-/*
- * Routines for dealing with the sorted snapshot functionality
- */
-typedef struct zfs_node {
- zfs_handle_t *zn_handle;
- avl_node_t zn_avlnode;
-} zfs_node_t;
-
-static int
-zfs_sort_snaps(zfs_handle_t *zhp, void *data)
-{
- avl_tree_t *avl = data;
- zfs_node_t *node;
- zfs_node_t search;
-
- search.zn_handle = zhp;
- node = avl_find(avl, &search, NULL);
- if (node) {
- /*
- * If this snapshot was renamed while we were creating the
- * AVL tree, it's possible that we already inserted it under
- * its old name. Remove the old handle before adding the new
- * one.
- */
- zfs_close(node->zn_handle);
- avl_remove(avl, node);
- free(node);
- }
-
- node = zfs_alloc(zhp->zfs_hdl, sizeof (zfs_node_t));
- node->zn_handle = zhp;
- avl_add(avl, node);
-
- return (0);
-}
-
-static int
-zfs_snapshot_compare(const void *larg, const void *rarg)
-{
- zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
- zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
- uint64_t lcreate, rcreate;
-
- /*
- * Sort them according to creation time. We use the hidden
- * CREATETXG property to get an absolute ordering of snapshots.
- */
- lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
- rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
-
- return (TREE_CMP(lcreate, rcreate));
-}
-
-int
-zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback,
- void *data, uint64_t min_txg, uint64_t max_txg)
-{
- return (zfs_iter_snapshots_sorted_v2(zhp, 0, callback, data,
- min_txg, max_txg));
-}
-
-int
-zfs_iter_snapshots_sorted_v2(zfs_handle_t *zhp, int flags, zfs_iter_f callback,
- void *data, uint64_t min_txg, uint64_t max_txg)
-{
- int ret = 0;
- zfs_node_t *node;
- avl_tree_t avl;
- void *cookie = NULL;
-
- avl_create(&avl, zfs_snapshot_compare,
- sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
-
- ret = zfs_iter_snapshots_v2(zhp, flags, zfs_sort_snaps, &avl, min_txg,
- max_txg);
-
- for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
- ret |= callback(node->zn_handle, data);
-
- while ((node = avl_destroy_nodes(&avl, &cookie)) != NULL)
- free(node);
-
- avl_destroy(&avl);
-
- return (ret);
-}
-
-typedef struct {
- char *ssa_first;
- char *ssa_last;
- boolean_t ssa_seenfirst;
- boolean_t ssa_seenlast;
- zfs_iter_f ssa_func;
- void *ssa_arg;
-} snapspec_arg_t;
-
-static int
-snapspec_cb(zfs_handle_t *zhp, void *arg)
-{
- snapspec_arg_t *ssa = arg;
- const char *shortsnapname;
- int err = 0;
-
- if (ssa->ssa_seenlast)
- return (0);
-
- shortsnapname = strchr(zfs_get_name(zhp), '@') + 1;
- if (!ssa->ssa_seenfirst && strcmp(shortsnapname, ssa->ssa_first) == 0)
- ssa->ssa_seenfirst = B_TRUE;
- if (strcmp(shortsnapname, ssa->ssa_last) == 0)
- ssa->ssa_seenlast = B_TRUE;
-
- if (ssa->ssa_seenfirst) {
- err = ssa->ssa_func(zhp, ssa->ssa_arg);
- } else {
- zfs_close(zhp);
- }
-
- return (err);
-}
-
-/*
- * spec is a string like "A,B%C,D"
- *
- * <snaps>, where <snaps> can be:
- * <snap> (single snapshot)
- * <snap>%<snap> (range of snapshots, inclusive)
- * %<snap> (range of snapshots, starting with earliest)
- * <snap>% (range of snapshots, ending with last)
- * % (all snapshots)
- * <snaps>[,...] (comma separated list of the above)
- *
- * If a snapshot can not be opened, continue trying to open the others, but
- * return ENOENT at the end.
- */
-int
-zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
- zfs_iter_f func, void *arg)
-{
- return (zfs_iter_snapspec_v2(fs_zhp, 0, spec_orig, func, arg));
-}
-
-int
-zfs_iter_snapspec_v2(zfs_handle_t *fs_zhp, int flags, const char *spec_orig,
- zfs_iter_f func, void *arg)
-{
- char *buf, *comma_separated, *cp;
- int err = 0;
- int ret = 0;
-
- buf = zfs_strdup(fs_zhp->zfs_hdl, spec_orig);
- cp = buf;
-
- while ((comma_separated = strsep(&cp, ",")) != NULL) {
- char *pct = strchr(comma_separated, '%');
- if (pct != NULL) {
- snapspec_arg_t ssa = { 0 };
- ssa.ssa_func = func;
- ssa.ssa_arg = arg;
-
- if (pct == comma_separated)
- ssa.ssa_seenfirst = B_TRUE;
- else
- ssa.ssa_first = comma_separated;
- *pct = '\0';
- ssa.ssa_last = pct + 1;
-
- /*
- * If there is a lastname specified, make sure it
- * exists.
- */
- if (ssa.ssa_last[0] != '\0') {
- char snapname[ZFS_MAX_DATASET_NAME_LEN];
- (void) snprintf(snapname, sizeof (snapname),
- "%s@%s", zfs_get_name(fs_zhp),
- ssa.ssa_last);
- if (!zfs_dataset_exists(fs_zhp->zfs_hdl,
- snapname, ZFS_TYPE_SNAPSHOT)) {
- ret = ENOENT;
- continue;
- }
- }
-
- err = zfs_iter_snapshots_sorted_v2(fs_zhp, flags,
- snapspec_cb, &ssa, 0, 0);
- if (ret == 0)
- ret = err;
- if (ret == 0 && (!ssa.ssa_seenfirst ||
- (ssa.ssa_last[0] != '\0' && !ssa.ssa_seenlast))) {
- ret = ENOENT;
- }
- } else {
- char snapname[ZFS_MAX_DATASET_NAME_LEN];
- zfs_handle_t *snap_zhp;
- (void) snprintf(snapname, sizeof (snapname), "%s@%s",
- zfs_get_name(fs_zhp), comma_separated);
- snap_zhp = make_dataset_handle(fs_zhp->zfs_hdl,
- snapname);
- if (snap_zhp == NULL) {
- ret = ENOENT;
- continue;
- }
- err = func(snap_zhp, arg);
- if (ret == 0)
- ret = err;
- }
- }
-
- free(buf);
- return (ret);
-}
-
-/*
- * Iterate over all children, snapshots and filesystems
- * Process snapshots before filesystems because they are nearer the input
- * handle: this is extremely important when used with zfs_iter_f functions
- * looking for data, following the logic that we would like to find it as soon
- * and as close as possible.
- */
-int
-zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
-{
- return (zfs_iter_children_v2(zhp, 0, func, data));
-}
-
-int
-zfs_iter_children_v2(zfs_handle_t *zhp, int flags, zfs_iter_f func, void *data)
-{
- int ret;
-
- if ((ret = zfs_iter_snapshots_v2(zhp, flags, func, data, 0, 0)) != 0)
- return (ret);
-
- return (zfs_iter_filesystems_v2(zhp, flags, func, data));
-}
-
-
-typedef struct iter_stack_frame {
- struct iter_stack_frame *next;
- zfs_handle_t *zhp;
-} iter_stack_frame_t;
-
-typedef struct iter_dependents_arg {
- boolean_t first;
- int flags;
- boolean_t allowrecursion;
- iter_stack_frame_t *stack;
- zfs_iter_f func;
- void *data;
-} iter_dependents_arg_t;
-
-static int
-iter_dependents_cb(zfs_handle_t *zhp, void *arg)
-{
- iter_dependents_arg_t *ida = arg;
- int err = 0;
- boolean_t first = ida->first;
- ida->first = B_FALSE;
-
- if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
- err = zfs_iter_clones(zhp, ida->flags, iter_dependents_cb, ida);
- } else if (zhp->zfs_type != ZFS_TYPE_BOOKMARK) {
- iter_stack_frame_t isf;
- iter_stack_frame_t *f;
-
- /*
- * check if there is a cycle by seeing if this fs is already
- * on the stack.
- */
- for (f = ida->stack; f != NULL; f = f->next) {
- if (f->zhp->zfs_dmustats.dds_guid ==
- zhp->zfs_dmustats.dds_guid) {
- if (ida->allowrecursion) {
- zfs_close(zhp);
- return (0);
- } else {
- zfs_error_aux(zhp->zfs_hdl,
- dgettext(TEXT_DOMAIN,
- "recursive dependency at '%s'"),
- zfs_get_name(zhp));
- err = zfs_error(zhp->zfs_hdl,
- EZFS_RECURSIVE,
- dgettext(TEXT_DOMAIN,
- "cannot determine dependent "
- "datasets"));
- zfs_close(zhp);
- return (err);
- }
- }
- }
-
- isf.zhp = zhp;
- isf.next = ida->stack;
- ida->stack = &isf;
- err = zfs_iter_filesystems_v2(zhp, ida->flags,
- iter_dependents_cb, ida);
- if (err == 0)
- err = zfs_iter_snapshots_sorted_v2(zhp, ida->flags,
- iter_dependents_cb, ida, 0, 0);
- ida->stack = isf.next;
- }
-
- if (!first && err == 0)
- err = ida->func(zhp, ida->data);
- else
- zfs_close(zhp);
-
- return (err);
-}
-
-int
-zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
- zfs_iter_f func, void *data)
-{
- return (zfs_iter_dependents_v2(zhp, 0, allowrecursion, func, data));
-}
-
-int
-zfs_iter_dependents_v2(zfs_handle_t *zhp, int flags, boolean_t allowrecursion,
- zfs_iter_f func, void *data)
-{
- iter_dependents_arg_t ida;
- ida.flags = flags;
- ida.allowrecursion = allowrecursion;
- ida.stack = NULL;
- ida.func = func;
- ida.data = data;
- ida.first = B_TRUE;
- return (iter_dependents_cb(zfs_handle_dup(zhp), &ida));
-}
-
-/*
- * Iterate over mounted children of the specified dataset
- */
-int
-zfs_iter_mounted(zfs_handle_t *zhp, zfs_iter_f func, void *data)
-{
- char mnt_prop[ZFS_MAXPROPLEN];
- struct mnttab entry;
- zfs_handle_t *mtab_zhp;
- size_t namelen = strlen(zhp->zfs_name);
- FILE *mnttab;
- int err = 0;
-
- if ((mnttab = fopen(MNTTAB, "re")) == NULL)
- return (ENOENT);
-
- while (err == 0 && getmntent(mnttab, &entry) == 0) {
- /* Ignore non-ZFS entries */
- if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
- continue;
-
- /* Ignore datasets not within the provided dataset */
- if (strncmp(entry.mnt_special, zhp->zfs_name, namelen) != 0 ||
- entry.mnt_special[namelen] != '/')
- continue;
-
- /* Skip snapshot of any child dataset */
- if (strchr(entry.mnt_special, '@') != NULL)
- continue;
-
- if ((mtab_zhp = zfs_open(zhp->zfs_hdl, entry.mnt_special,
- ZFS_TYPE_FILESYSTEM)) == NULL)
- continue;
-
- /* Ignore legacy mounts as they are user managed */
- verify(zfs_prop_get(mtab_zhp, ZFS_PROP_MOUNTPOINT, mnt_prop,
- sizeof (mnt_prop), NULL, NULL, 0, B_FALSE) == 0);
- if (strcmp(mnt_prop, "legacy") == 0) {
- zfs_close(mtab_zhp);
- continue;
- }
-
- err = func(mtab_zhp, data);
- }
-
- fclose(mnttab);
-
- return (err);
-}
diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c
deleted file mode 100644
index 5c9e2199eed4..000000000000
--- a/lib/libzfs/libzfs_mount.c
+++ /dev/null
@@ -1,1468 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2022 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright 2017 RackTop Systems.
- * Copyright (c) 2018 Datto Inc.
- * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
- */
-
-/*
- * Routines to manage ZFS mounts. We separate all the nasty routines that have
- * to deal with the OS. The following functions are the main entry points --
- * they are used by mount and unmount and when changing a filesystem's
- * mountpoint.
- *
- * zfs_is_mounted()
- * zfs_mount()
- * zfs_mount_at()
- * zfs_unmount()
- * zfs_unmountall()
- *
- * This file also contains the functions used to manage sharing filesystems:
- *
- * zfs_is_shared()
- * zfs_share()
- * zfs_unshare()
- * zfs_unshareall()
- * zfs_commit_shares()
- *
- * The following functions are available for pool consumers, and will
- * mount/unmount and share/unshare all datasets within pool:
- *
- * zpool_enable_datasets()
- * zpool_disable_datasets()
- */
-
-#include <dirent.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <zone.h>
-#include <sys/mntent.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/vfs.h>
-#include <sys/dsl_crypt.h>
-
-#include <libzfs.h>
-#include <libzutil.h>
-
-#include "libzfs_impl.h"
-#include <thread_pool.h>
-
-#include <libshare.h>
-#include <sys/systeminfo.h>
-#define MAXISALEN 257 /* based on sysinfo(2) man page */
-
-static void zfs_mount_task(void *);
-
-static const proto_table_t proto_table[SA_PROTOCOL_COUNT] = {
- [SA_PROTOCOL_NFS] =
- {ZFS_PROP_SHARENFS, EZFS_SHARENFSFAILED, EZFS_UNSHARENFSFAILED},
- [SA_PROTOCOL_SMB] =
- {ZFS_PROP_SHARESMB, EZFS_SHARESMBFAILED, EZFS_UNSHARESMBFAILED},
-};
-
-static const enum sa_protocol share_all_proto[SA_PROTOCOL_COUNT + 1] = {
- SA_PROTOCOL_NFS,
- SA_PROTOCOL_SMB,
- SA_NO_PROTOCOL
-};
-
-
-
-static boolean_t
-dir_is_empty_stat(const char *dirname)
-{
- struct stat st;
-
- /*
- * We only want to return false if the given path is a non empty
- * directory, all other errors are handled elsewhere.
- */
- if (stat(dirname, &st) < 0 || !S_ISDIR(st.st_mode)) {
- return (B_TRUE);
- }
-
- /*
- * An empty directory will still have two entries in it, one
- * entry for each of "." and "..".
- */
- if (st.st_size > 2) {
- return (B_FALSE);
- }
-
- return (B_TRUE);
-}
-
-static boolean_t
-dir_is_empty_readdir(const char *dirname)
-{
- DIR *dirp;
- struct dirent64 *dp;
- int dirfd;
-
- if ((dirfd = openat(AT_FDCWD, dirname,
- O_RDONLY | O_NDELAY | O_LARGEFILE | O_CLOEXEC, 0)) < 0) {
- return (B_TRUE);
- }
-
- if ((dirp = fdopendir(dirfd)) == NULL) {
- (void) close(dirfd);
- return (B_TRUE);
- }
-
- while ((dp = readdir64(dirp)) != NULL) {
-
- if (strcmp(dp->d_name, ".") == 0 ||
- strcmp(dp->d_name, "..") == 0)
- continue;
-
- (void) closedir(dirp);
- return (B_FALSE);
- }
-
- (void) closedir(dirp);
- return (B_TRUE);
-}
-
-/*
- * Returns true if the specified directory is empty. If we can't open the
- * directory at all, return true so that the mount can fail with a more
- * informative error message.
- */
-static boolean_t
-dir_is_empty(const char *dirname)
-{
- struct statfs64 st;
-
- /*
- * If the statvfs call fails or the filesystem is not a ZFS
- * filesystem, fall back to the slow path which uses readdir.
- */
- if ((statfs64(dirname, &st) != 0) ||
- (st.f_type != ZFS_SUPER_MAGIC)) {
- return (dir_is_empty_readdir(dirname));
- }
-
- /*
- * At this point, we know the provided path is on a ZFS
- * filesystem, so we can use stat instead of readdir to
- * determine if the directory is empty or not. We try to avoid
- * using readdir because that requires opening "dirname"; this
- * open file descriptor can potentially end up in a child
- * process if there's a concurrent fork, thus preventing the
- * zfs_mount() from otherwise succeeding (the open file
- * descriptor inherited by the child process will cause the
- * parent's mount to fail with EBUSY). The performance
- * implications of replacing the open, read, and close with a
- * single stat is nice; but is not the main motivation for the
- * added complexity.
- */
- return (dir_is_empty_stat(dirname));
-}
-
-/*
- * Checks to see if the mount is active. If the filesystem is mounted, we fill
- * in 'where' with the current mountpoint, and return 1. Otherwise, we return
- * 0.
- */
-boolean_t
-is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
-{
- struct mnttab entry;
-
- if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
- return (B_FALSE);
-
- if (where != NULL)
- *where = zfs_strdup(zfs_hdl, entry.mnt_mountp);
-
- return (B_TRUE);
-}
-
-boolean_t
-zfs_is_mounted(zfs_handle_t *zhp, char **where)
-{
- return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where));
-}
-
-/*
- * Checks any higher order concerns about whether the given dataset is
- * mountable, false otherwise. zfs_is_mountable_internal specifically assumes
- * that the caller has verified the sanity of mounting the dataset at
- * its mountpoint to the extent the caller wants.
- */
-static boolean_t
-zfs_is_mountable_internal(zfs_handle_t *zhp)
-{
- if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
- getzoneid() == GLOBAL_ZONEID)
- return (B_FALSE);
-
- return (B_TRUE);
-}
-
-/*
- * Returns true if the given dataset is mountable, false otherwise. Returns the
- * mountpoint in 'buf'.
- */
-static boolean_t
-zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
- zprop_source_t *source, int flags)
-{
- char sourceloc[MAXNAMELEN];
- zprop_source_t sourcetype;
-
- if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
- B_FALSE))
- return (B_FALSE);
-
- verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
- &sourcetype, sourceloc, sizeof (sourceloc), B_FALSE) == 0);
-
- if (strcmp(buf, ZFS_MOUNTPOINT_NONE) == 0 ||
- strcmp(buf, ZFS_MOUNTPOINT_LEGACY) == 0)
- return (B_FALSE);
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
- return (B_FALSE);
-
- if (!zfs_is_mountable_internal(zhp))
- return (B_FALSE);
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_REDACTED) && !(flags & MS_FORCE))
- return (B_FALSE);
-
- if (source)
- *source = sourcetype;
-
- return (B_TRUE);
-}
-
-/*
- * The filesystem is mounted by invoking the system mount utility rather
- * than by the system call mount(2). This ensures that the /etc/mtab
- * file is correctly locked for the update. Performing our own locking
- * and /etc/mtab update requires making an unsafe assumption about how
- * the mount utility performs its locking. Unfortunately, this also means
- * in the case of a mount failure we do not have the exact errno. We must
- * make due with return value from the mount process.
- *
- * In the long term a shared library called libmount is under development
- * which provides a common API to address the locking and errno issues.
- * Once the standard mount utility has been updated to use this library
- * we can add an autoconf check to conditionally use it.
- *
- * http://www.kernel.org/pub/linux/utils/util-linux/libmount-docs/index.html
- */
-
-static int
-zfs_add_option(zfs_handle_t *zhp, char *options, int len,
- zfs_prop_t prop, const char *on, const char *off)
-{
- const char *source;
- uint64_t value;
-
- /* Skip adding duplicate default options */
- if ((strstr(options, on) != NULL) || (strstr(options, off) != NULL))
- return (0);
-
- /*
- * zfs_prop_get_int() is not used to ensure our mount options
- * are not influenced by the current /proc/self/mounts contents.
- */
- value = getprop_uint64(zhp, prop, &source);
-
- (void) strlcat(options, ",", len);
- (void) strlcat(options, value ? on : off, len);
-
- return (0);
-}
-
-static int
-zfs_add_options(zfs_handle_t *zhp, char *options, int len)
-{
- int error = 0;
-
- error = zfs_add_option(zhp, options, len,
- ZFS_PROP_ATIME, MNTOPT_ATIME, MNTOPT_NOATIME);
- /*
- * don't add relatime/strictatime when atime=off, otherwise strictatime
- * will force atime=on
- */
- if (strstr(options, MNTOPT_NOATIME) == NULL) {
- error = zfs_add_option(zhp, options, len,
- ZFS_PROP_RELATIME, MNTOPT_RELATIME, MNTOPT_STRICTATIME);
- }
- error = error ? error : zfs_add_option(zhp, options, len,
- ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES);
- error = error ? error : zfs_add_option(zhp, options, len,
- ZFS_PROP_EXEC, MNTOPT_EXEC, MNTOPT_NOEXEC);
- error = error ? error : zfs_add_option(zhp, options, len,
- ZFS_PROP_READONLY, MNTOPT_RO, MNTOPT_RW);
- error = error ? error : zfs_add_option(zhp, options, len,
- ZFS_PROP_SETUID, MNTOPT_SETUID, MNTOPT_NOSETUID);
- error = error ? error : zfs_add_option(zhp, options, len,
- ZFS_PROP_NBMAND, MNTOPT_NBMAND, MNTOPT_NONBMAND);
-
- return (error);
-}
-
-int
-zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
-{
- char mountpoint[ZFS_MAXPROPLEN];
-
- if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL,
- flags))
- return (0);
-
- return (zfs_mount_at(zhp, options, flags, mountpoint));
-}
-
-/*
- * Mount the given filesystem.
- */
-int
-zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags,
- const char *mountpoint)
-{
- 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;
-
- if (options == NULL) {
- (void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts));
- } else {
- (void) strlcpy(mntopts, options, sizeof (mntopts));
- }
-
- if (strstr(mntopts, MNTOPT_REMOUNT) != NULL)
- remount = 1;
-
- /* Potentially duplicates some checks if invoked by zfs_mount(). */
- if (!zfs_is_mountable_internal(zhp))
- return (0);
-
- /*
- * If the pool is imported read-only then all mounts must be read-only
- */
- if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
- (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts));
-
- /*
- * Append default mount options which apply to the mount point.
- * This is done because under Linux (unlike Solaris) multiple mount
- * points may reference a single super block. This means that just
- * given a super block there is no back reference to update the per
- * mount point options.
- */
- rc = zfs_add_options(zhp, mntopts, sizeof (mntopts));
- if (rc) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "default options unavailable"));
- return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
- dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
- mountpoint));
- }
-
- /*
- * If the filesystem is encrypted the key must be loaded in order to
- * mount. If the key isn't loaded, the MS_CRYPT flag decides whether
- * or not we attempt to load the keys. Note: we must call
- * zfs_refresh_properties() here since some callers of this function
- * (most notably zpool_enable_datasets()) may implicitly load our key
- * by loading the parent's key first.
- */
- if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
- zfs_refresh_properties(zhp);
- keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
-
- /*
- * If the key is unavailable and MS_CRYPT is set give the
- * user a chance to enter the key. Otherwise just fail
- * immediately.
- */
- if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
- if (flags & MS_CRYPT) {
- 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 {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encryption key not loaded"));
- return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
- dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
- mountpoint));
- }
- }
-
- }
-
- /*
- * Append zfsutil option so the mount helper allow the mount
- */
- strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts));
-
- /* Create the directory if it doesn't already exist */
- if (lstat(mountpoint, &buf) != 0) {
- if (mkdirp(mountpoint, 0755) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "failed to create mountpoint: %s"),
- zfs_strerror(errno));
- return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
- dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
- mountpoint));
- }
- }
-
- /*
- * Overlay mounts are enabled by default but may be disabled
- * via the 'overlay' property. The -O flag remains for compatibility.
- */
- if (!(flags & MS_OVERLAY)) {
- if (zfs_prop_get(zhp, ZFS_PROP_OVERLAY, overlay,
- sizeof (overlay), NULL, NULL, 0, B_FALSE) == 0) {
- if (strcmp(overlay, "on") == 0) {
- flags |= MS_OVERLAY;
- }
- }
- }
-
- /*
- * Determine if the mountpoint is empty. If so, refuse to perform the
- * mount. We don't perform this check if 'remount' is
- * specified or if overlay option (-O) is given
- */
- if ((flags & MS_OVERLAY) == 0 && !remount &&
- !dir_is_empty(mountpoint)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "directory is not empty"));
- return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
- dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
- }
-
- /* perform the mount */
- rc = do_mount(zhp, mountpoint, mntopts, flags);
- if (rc) {
- /*
- * Generic errors are nasty, but there are just way too many
- * from mount(), and they're well-understood. We pick a few
- * common ones to improve upon.
- */
- if (rc == EBUSY) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "mountpoint or dataset is busy"));
- } else if (rc == EPERM) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Insufficient privileges"));
- } else if (rc == ENOTSUP) {
- int spa_version;
-
- VERIFY0(zfs_spa_version(zhp, &spa_version));
- 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);
- } else {
- zfs_error_aux(hdl, "%s", zfs_strerror(rc));
- }
- return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
- dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
- zhp->zfs_name));
- }
-
- /* remove the mounted entry before re-adding on remount */
- if (remount)
- libzfs_mnttab_remove(hdl, zhp->zfs_name);
-
- /* add the mounted entry into our cache */
- libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts);
- return (0);
-}
-
-/*
- * Unmount a single filesystem.
- */
-static int
-unmount_one(zfs_handle_t *zhp, const char *mountpoint, int flags)
-{
- int error;
-
- error = do_unmount(zhp, mountpoint, flags);
- if (error != 0) {
- int libzfs_err;
-
- switch (error) {
- case EBUSY:
- libzfs_err = EZFS_BUSY;
- break;
- case EIO:
- libzfs_err = EZFS_IO;
- break;
- case ENOENT:
- libzfs_err = EZFS_NOENT;
- break;
- case ENOMEM:
- libzfs_err = EZFS_NOMEM;
- break;
- case EPERM:
- libzfs_err = EZFS_PERM;
- break;
- default:
- libzfs_err = EZFS_UMOUNTFAILED;
- }
- if (zhp) {
- return (zfs_error_fmt(zhp->zfs_hdl, libzfs_err,
- dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
- mountpoint));
- } else {
- return (-1);
- }
- }
-
- return (0);
-}
-
-/*
- * Unmount the given filesystem.
- */
-int
-zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- struct mnttab entry;
- char *mntpt = NULL;
- boolean_t encroot, unmounted = B_FALSE;
-
- /* check to see if we need to unmount the filesystem */
- if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
- libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
- /*
- * mountpoint may have come from a call to
- * getmnt/getmntany if it isn't NULL. If it is NULL,
- * we know it comes from libzfs_mnttab_find which can
- * then get freed later. We strdup it to play it safe.
- */
- if (mountpoint == NULL)
- mntpt = zfs_strdup(hdl, entry.mnt_mountp);
- else
- mntpt = zfs_strdup(hdl, mountpoint);
-
- /*
- * Unshare and unmount the filesystem
- */
- if (zfs_unshare(zhp, mntpt, share_all_proto) != 0) {
- free(mntpt);
- return (-1);
- }
- zfs_commit_shares(NULL);
-
- if (unmount_one(zhp, mntpt, flags) != 0) {
- free(mntpt);
- (void) zfs_share(zhp, NULL);
- zfs_commit_shares(NULL);
- return (-1);
- }
-
- libzfs_mnttab_remove(hdl, zhp->zfs_name);
- free(mntpt);
- unmounted = B_TRUE;
- }
-
- /*
- * If the MS_CRYPT flag is provided we must ensure we attempt to
- * unload the dataset's key regardless of whether we did any work
- * to unmount it. We only do this for encryption roots.
- */
- if ((flags & MS_CRYPT) != 0 &&
- zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
- zfs_refresh_properties(zhp);
-
- if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0 &&
- unmounted) {
- (void) zfs_mount(zhp, NULL, 0);
- return (-1);
- }
-
- if (encroot && zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
- ZFS_KEYSTATUS_AVAILABLE &&
- zfs_crypto_unload_key(zhp) != 0) {
- (void) zfs_mount(zhp, NULL, 0);
- return (-1);
- }
- }
-
- zpool_disable_volume_os(zhp->zfs_name);
-
- return (0);
-}
-
-/*
- * Unmount this filesystem and any children inheriting the mountpoint property.
- * To do this, just act like we're changing the mountpoint property, but don't
- * remount the filesystems afterwards.
- */
-int
-zfs_unmountall(zfs_handle_t *zhp, int flags)
-{
- prop_changelist_t *clp;
- int ret;
-
- clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
- CL_GATHER_ITER_MOUNTED, flags);
- if (clp == NULL)
- return (-1);
-
- ret = changelist_prefix(clp);
- changelist_free(clp);
-
- return (ret);
-}
-
-/*
- * Unshare a filesystem by mountpoint.
- */
-static int
-unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
- enum sa_protocol proto)
-{
- int err = sa_disable_share(mountpoint, proto);
- if (err != SA_OK)
- return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
- dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
- name, sa_errorstr(err)));
-
- return (0);
-}
-
-/*
- * Share the given filesystem according to the options in the specified
- * protocol specific properties (sharenfs, sharesmb). We rely
- * on "libshare" to do the dirty work for us.
- */
-int
-zfs_share(zfs_handle_t *zhp, const enum sa_protocol *proto)
-{
- char mountpoint[ZFS_MAXPROPLEN];
- char shareopts[ZFS_MAXPROPLEN];
- char sourcestr[ZFS_MAXPROPLEN];
- const enum sa_protocol *curr_proto;
- zprop_source_t sourcetype;
- int err = 0;
-
- if (proto == NULL)
- proto = share_all_proto;
-
- if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, 0))
- return (0);
-
- for (curr_proto = proto; *curr_proto != SA_NO_PROTOCOL; curr_proto++) {
- /*
- * Return success if there are no share options.
- */
- if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
- shareopts, sizeof (shareopts), &sourcetype, sourcestr,
- ZFS_MAXPROPLEN, B_FALSE) != 0 ||
- strcmp(shareopts, "off") == 0)
- continue;
-
- /*
- * If the 'zoned' property is set, then zfs_is_mountable()
- * will have already bailed out if we are in the global zone.
- * But local zones cannot be NFS servers, so we ignore it for
- * local zones as well.
- */
- if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
- continue;
-
- err = sa_enable_share(zfs_get_name(zhp), mountpoint, shareopts,
- *curr_proto);
- if (err != SA_OK) {
- return (zfs_error_fmt(zhp->zfs_hdl,
- proto_table[*curr_proto].p_share_err,
- dgettext(TEXT_DOMAIN, "cannot share '%s: %s'"),
- zfs_get_name(zhp), sa_errorstr(err)));
- }
-
- }
- return (0);
-}
-
-/*
- * Check to see if the filesystem is currently shared.
- */
-boolean_t
-zfs_is_shared(zfs_handle_t *zhp, char **where,
- const enum sa_protocol *proto)
-{
- char *mountpoint;
- if (proto == NULL)
- proto = share_all_proto;
-
- if (ZFS_IS_VOLUME(zhp))
- return (B_FALSE);
-
- if (!zfs_is_mounted(zhp, &mountpoint))
- return (B_FALSE);
-
- for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
- if (sa_is_shared(mountpoint, *p)) {
- if (where != NULL)
- *where = mountpoint;
- else
- free(mountpoint);
- return (B_TRUE);
- }
-
- free(mountpoint);
- return (B_FALSE);
-}
-
-void
-zfs_commit_shares(const enum sa_protocol *proto)
-{
- if (proto == NULL)
- proto = share_all_proto;
-
- for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
- sa_commit_shares(*p);
-}
-
-void
-zfs_truncate_shares(const enum sa_protocol *proto)
-{
- if (proto == NULL)
- proto = share_all_proto;
-
- for (const enum sa_protocol *p = proto; *p != SA_NO_PROTOCOL; ++p)
- sa_truncate_shares(*p);
-}
-
-/*
- * Unshare the given filesystem.
- */
-int
-zfs_unshare(zfs_handle_t *zhp, const char *mountpoint,
- const enum sa_protocol *proto)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- struct mnttab entry;
-
- if (proto == NULL)
- proto = share_all_proto;
-
- if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
- libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
-
- /* check to see if need to unmount the filesystem */
- const char *mntpt = mountpoint ?: entry.mnt_mountp;
-
- for (const enum sa_protocol *curr_proto = proto;
- *curr_proto != SA_NO_PROTOCOL; curr_proto++)
- if (sa_is_shared(mntpt, *curr_proto) &&
- unshare_one(hdl, zhp->zfs_name,
- mntpt, *curr_proto) != 0)
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Same as zfs_unmountall(), but for NFS and SMB unshares.
- */
-int
-zfs_unshareall(zfs_handle_t *zhp, const enum sa_protocol *proto)
-{
- prop_changelist_t *clp;
- int ret;
-
- if (proto == NULL)
- proto = share_all_proto;
-
- clp = changelist_gather(zhp, ZFS_PROP_SHARENFS, 0, 0);
- if (clp == NULL)
- return (-1);
-
- ret = changelist_unshare(clp, proto);
- changelist_free(clp);
-
- return (ret);
-}
-
-/*
- * Remove the mountpoint associated with the current dataset, if necessary.
- * We only remove the underlying directory if:
- *
- * - The mountpoint is not 'none' or 'legacy'
- * - The mountpoint is non-empty
- * - The mountpoint is the default or inherited
- * - The 'zoned' property is set, or we're in a local zone
- *
- * Any other directories we leave alone.
- */
-void
-remove_mountpoint(zfs_handle_t *zhp)
-{
- char mountpoint[ZFS_MAXPROPLEN];
- zprop_source_t source;
-
- if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint),
- &source, 0))
- return;
-
- if (source == ZPROP_SRC_DEFAULT ||
- source == ZPROP_SRC_INHERITED) {
- /*
- * Try to remove the directory, silently ignoring any errors.
- * The filesystem may have since been removed or moved around,
- * and this error isn't really useful to the administrator in
- * any way.
- */
- (void) rmdir(mountpoint);
- }
-}
-
-/*
- * Add the given zfs handle to the cb_handles array, dynamically reallocating
- * the array if it is out of space.
- */
-void
-libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
-{
- if (cbp->cb_alloc == cbp->cb_used) {
- size_t newsz;
- zfs_handle_t **newhandles;
-
- newsz = cbp->cb_alloc != 0 ? cbp->cb_alloc * 2 : 64;
- newhandles = zfs_realloc(zhp->zfs_hdl,
- cbp->cb_handles, cbp->cb_alloc * sizeof (zfs_handle_t *),
- newsz * sizeof (zfs_handle_t *));
- cbp->cb_handles = newhandles;
- cbp->cb_alloc = newsz;
- }
- cbp->cb_handles[cbp->cb_used++] = zhp;
-}
-
-/*
- * Recursive helper function used during file system enumeration
- */
-static int
-zfs_iter_cb(zfs_handle_t *zhp, void *data)
-{
- get_all_cb_t *cbp = data;
-
- if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
- zfs_close(zhp);
- return (0);
- }
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_NOAUTO) {
- zfs_close(zhp);
- return (0);
- }
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
- ZFS_KEYSTATUS_UNAVAILABLE) {
- zfs_close(zhp);
- return (0);
- }
-
- /*
- * If this filesystem is inconsistent and has a receive resume
- * token, we can not mount it.
- */
- if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
- zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
- NULL, 0, NULL, NULL, 0, B_TRUE) == 0) {
- zfs_close(zhp);
- return (0);
- }
-
- libzfs_add_handle(cbp, zhp);
- if (zfs_iter_filesystems_v2(zhp, 0, zfs_iter_cb, cbp) != 0) {
- zfs_close(zhp);
- return (-1);
- }
- return (0);
-}
-
-/*
- * Sort comparator that compares two mountpoint paths. We sort these paths so
- * that subdirectories immediately follow their parents. This means that we
- * effectively treat the '/' character as the lowest value non-nul char.
- * Since filesystems from non-global zones can have the same mountpoint
- * as other filesystems, the comparator sorts global zone filesystems to
- * the top of the list. This means that the global zone will traverse the
- * filesystem list in the correct order and can stop when it sees the
- * first zoned filesystem. In a non-global zone, only the delegated
- * filesystems are seen.
- *
- * An example sorted list using this comparator would look like:
- *
- * /foo
- * /foo/bar
- * /foo/bar/baz
- * /foo/baz
- * /foo.bar
- * /foo (NGZ1)
- * /foo (NGZ2)
- *
- * The mounting code depends on this ordering to deterministically iterate
- * over filesystems in order to spawn parallel mount tasks.
- */
-static int
-mountpoint_cmp(const void *arga, const void *argb)
-{
- zfs_handle_t *const *zap = arga;
- zfs_handle_t *za = *zap;
- zfs_handle_t *const *zbp = argb;
- zfs_handle_t *zb = *zbp;
- char mounta[MAXPATHLEN];
- char mountb[MAXPATHLEN];
- const char *a = mounta;
- const char *b = mountb;
- boolean_t gota, gotb;
- uint64_t zoneda, zonedb;
-
- zoneda = zfs_prop_get_int(za, ZFS_PROP_ZONED);
- zonedb = zfs_prop_get_int(zb, ZFS_PROP_ZONED);
- if (zoneda && !zonedb)
- return (1);
- if (!zoneda && zonedb)
- return (-1);
-
- gota = (zfs_get_type(za) == ZFS_TYPE_FILESYSTEM);
- if (gota) {
- verify(zfs_prop_get(za, ZFS_PROP_MOUNTPOINT, mounta,
- sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
- }
- gotb = (zfs_get_type(zb) == ZFS_TYPE_FILESYSTEM);
- if (gotb) {
- verify(zfs_prop_get(zb, ZFS_PROP_MOUNTPOINT, mountb,
- sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
- }
-
- if (gota && gotb) {
- while (*a != '\0' && (*a == *b)) {
- a++;
- b++;
- }
- if (*a == *b)
- return (0);
- if (*a == '\0')
- return (-1);
- if (*b == '\0')
- return (1);
- if (*a == '/')
- return (-1);
- if (*b == '/')
- return (1);
- return (*a < *b ? -1 : *a > *b);
- }
-
- if (gota)
- return (-1);
- if (gotb)
- return (1);
-
- /*
- * If neither filesystem has a mountpoint, revert to sorting by
- * dataset name.
- */
- return (strcmp(zfs_get_name(za), zfs_get_name(zb)));
-}
-
-/*
- * Return true if path2 is a child of path1 or path2 equals path1 or
- * path1 is "/" (path2 is always a child of "/").
- */
-static boolean_t
-libzfs_path_contains(const char *path1, const char *path2)
-{
- return (strcmp(path1, path2) == 0 || strcmp(path1, "/") == 0 ||
- (strstr(path2, path1) == path2 && path2[strlen(path1)] == '/'));
-}
-
-/*
- * Given a mountpoint specified by idx in the handles array, find the first
- * non-descendent of that mountpoint and return its index. Descendant paths
- * start with the parent's path. This function relies on the ordering
- * enforced by mountpoint_cmp().
- */
-static int
-non_descendant_idx(zfs_handle_t **handles, size_t num_handles, int idx)
-{
- char parent[ZFS_MAXPROPLEN];
- char child[ZFS_MAXPROPLEN];
- int i;
-
- verify(zfs_prop_get(handles[idx], ZFS_PROP_MOUNTPOINT, parent,
- sizeof (parent), NULL, NULL, 0, B_FALSE) == 0);
-
- for (i = idx + 1; i < num_handles; i++) {
- verify(zfs_prop_get(handles[i], ZFS_PROP_MOUNTPOINT, child,
- sizeof (child), NULL, NULL, 0, B_FALSE) == 0);
- if (!libzfs_path_contains(parent, child))
- break;
- }
- return (i);
-}
-
-typedef struct mnt_param {
- libzfs_handle_t *mnt_hdl;
- tpool_t *mnt_tp;
- zfs_handle_t **mnt_zhps; /* filesystems to mount */
- size_t mnt_num_handles;
- int mnt_idx; /* Index of selected entry to mount */
- zfs_iter_f mnt_func;
- void *mnt_data;
-} mnt_param_t;
-
-/*
- * Allocate and populate the parameter struct for mount function, and
- * schedule mounting of the entry selected by idx.
- */
-static void
-zfs_dispatch_mount(libzfs_handle_t *hdl, zfs_handle_t **handles,
- size_t num_handles, int idx, zfs_iter_f func, void *data, tpool_t *tp)
-{
- mnt_param_t *mnt_param = zfs_alloc(hdl, sizeof (mnt_param_t));
-
- mnt_param->mnt_hdl = hdl;
- mnt_param->mnt_tp = tp;
- mnt_param->mnt_zhps = handles;
- mnt_param->mnt_num_handles = num_handles;
- mnt_param->mnt_idx = idx;
- mnt_param->mnt_func = func;
- mnt_param->mnt_data = data;
-
- if (tpool_dispatch(tp, zfs_mount_task, (void*)mnt_param)) {
- /* Could not dispatch to thread pool; execute directly */
- zfs_mount_task((void*)mnt_param);
- }
-}
-
-/*
- * This is the structure used to keep state of mounting or sharing operations
- * during a call to zpool_enable_datasets().
- */
-typedef struct mount_state {
- /*
- * ms_mntstatus is set to -1 if any mount fails. While multiple threads
- * could update this variable concurrently, no synchronization is
- * needed as it's only ever set to -1.
- */
- int ms_mntstatus;
- int ms_mntflags;
- const char *ms_mntopts;
-} mount_state_t;
-
-static int
-zfs_mount_one(zfs_handle_t *zhp, void *arg)
-{
- mount_state_t *ms = arg;
- int ret = 0;
-
- /*
- * don't attempt to mount encrypted datasets with
- * unloaded keys
- */
- if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) ==
- ZFS_KEYSTATUS_UNAVAILABLE)
- return (0);
-
- if (zfs_mount(zhp, ms->ms_mntopts, ms->ms_mntflags) != 0)
- ret = ms->ms_mntstatus = -1;
- return (ret);
-}
-
-static int
-zfs_share_one(zfs_handle_t *zhp, void *arg)
-{
- mount_state_t *ms = arg;
- int ret = 0;
-
- if (zfs_share(zhp, NULL) != 0)
- ret = ms->ms_mntstatus = -1;
- return (ret);
-}
-
-/*
- * Thread pool function to mount one file system. On completion, it finds and
- * schedules its children to be mounted. This depends on the sorting done in
- * zfs_foreach_mountpoint(). Note that the degenerate case (chain of entries
- * each descending from the previous) will have no parallelism since we always
- * have to wait for the parent to finish mounting before we can schedule
- * its children.
- */
-static void
-zfs_mount_task(void *arg)
-{
- mnt_param_t *mp = arg;
- int idx = mp->mnt_idx;
- zfs_handle_t **handles = mp->mnt_zhps;
- size_t num_handles = mp->mnt_num_handles;
- char mountpoint[ZFS_MAXPROPLEN];
-
- verify(zfs_prop_get(handles[idx], ZFS_PROP_MOUNTPOINT, mountpoint,
- sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
-
- if (mp->mnt_func(handles[idx], mp->mnt_data) != 0)
- goto out;
-
- /*
- * We dispatch tasks to mount filesystems with mountpoints underneath
- * this one. We do this by dispatching the next filesystem with a
- * descendant mountpoint of the one we just mounted, then skip all of
- * its descendants, dispatch the next descendant mountpoint, and so on.
- * The non_descendant_idx() function skips over filesystems that are
- * descendants of the filesystem we just dispatched.
- */
- for (int i = idx + 1; i < num_handles;
- i = non_descendant_idx(handles, num_handles, i)) {
- char child[ZFS_MAXPROPLEN];
- verify(zfs_prop_get(handles[i], ZFS_PROP_MOUNTPOINT,
- child, sizeof (child), NULL, NULL, 0, B_FALSE) == 0);
-
- if (!libzfs_path_contains(mountpoint, child))
- break; /* not a descendant, return */
- zfs_dispatch_mount(mp->mnt_hdl, handles, num_handles, i,
- mp->mnt_func, mp->mnt_data, mp->mnt_tp);
- }
-
-out:
- free(mp);
-}
-
-/*
- * Issue the func callback for each ZFS handle contained in the handles
- * array. This function is used to mount all datasets, and so this function
- * guarantees that filesystems for parent mountpoints are called before their
- * children. As such, before issuing any callbacks, we first sort the array
- * of handles by mountpoint.
- *
- * Callbacks are issued in one of two ways:
- *
- * 1. Sequentially: If the nthr argument is <= 1 or the ZFS_SERIAL_MOUNT
- * environment variable is set, then we issue callbacks sequentially.
- *
- * 2. In parallel: If the nthr argument is > 1 and the ZFS_SERIAL_MOUNT
- * environment variable is not set, then we use a tpool to dispatch threads
- * to mount filesystems in parallel. This function dispatches tasks to mount
- * the filesystems at the top-level mountpoints, and these tasks in turn
- * are responsible for recursively mounting filesystems in their children
- * mountpoints. The value of the nthr argument will be the number of worker
- * threads for the thread pool.
- */
-void
-zfs_foreach_mountpoint(libzfs_handle_t *hdl, zfs_handle_t **handles,
- size_t num_handles, zfs_iter_f func, void *data, uint_t nthr)
-{
- zoneid_t zoneid = getzoneid();
-
- /*
- * The ZFS_SERIAL_MOUNT environment variable is an undocumented
- * variable that can be used as a convenience to do a/b comparison
- * of serial vs. parallel mounting.
- */
- boolean_t serial_mount = nthr <= 1 ||
- (getenv("ZFS_SERIAL_MOUNT") != NULL);
-
- /*
- * Sort the datasets by mountpoint. See mountpoint_cmp for details
- * of how these are sorted.
- */
- qsort(handles, num_handles, sizeof (zfs_handle_t *), mountpoint_cmp);
-
- if (serial_mount) {
- for (int i = 0; i < num_handles; i++) {
- func(handles[i], data);
- }
- return;
- }
-
- /*
- * Issue the callback function for each dataset using a parallel
- * algorithm that uses a thread pool to manage threads.
- */
- tpool_t *tp = tpool_create(1, nthr, 0, NULL);
-
- /*
- * There may be multiple "top level" mountpoints outside of the pool's
- * root mountpoint, e.g.: /foo /bar. Dispatch a mount task for each of
- * these.
- */
- for (int i = 0; i < num_handles;
- i = non_descendant_idx(handles, num_handles, i)) {
- /*
- * Since the mountpoints have been sorted so that the zoned
- * filesystems are at the end, a zoned filesystem seen from
- * the global zone means that we're done.
- */
- if (zoneid == GLOBAL_ZONEID &&
- zfs_prop_get_int(handles[i], ZFS_PROP_ZONED))
- break;
- zfs_dispatch_mount(hdl, handles, num_handles, i, func, data,
- tp);
- }
-
- tpool_wait(tp); /* wait for all scheduled mounts to complete */
- tpool_destroy(tp);
-}
-
-/*
- * Mount and share all datasets within the given pool. This assumes that no
- * datasets within the pool are currently mounted. nthr will be number of
- * worker threads to use while mounting datasets.
- */
-int
-zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags,
- uint_t nthr)
-{
- get_all_cb_t cb = { 0 };
- mount_state_t ms = { 0 };
- zfs_handle_t *zfsp;
- int ret = 0;
-
- if ((zfsp = zfs_open(zhp->zpool_hdl, zhp->zpool_name,
- ZFS_TYPE_DATASET)) == NULL)
- goto out;
-
- /*
- * Gather all non-snapshot datasets within the pool. Start by adding
- * the root filesystem for this pool to the list, and then iterate
- * over all child filesystems.
- */
- libzfs_add_handle(&cb, zfsp);
- if (zfs_iter_filesystems_v2(zfsp, 0, zfs_iter_cb, &cb) != 0)
- goto out;
-
- /*
- * Mount all filesystems
- */
- ms.ms_mntopts = mntopts;
- ms.ms_mntflags = flags;
- zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
- zfs_mount_one, &ms, nthr);
- if (ms.ms_mntstatus != 0)
- ret = EZFS_MOUNTFAILED;
-
- /*
- * Share all filesystems that need to be shared. This needs to be
- * a separate pass because libshare is not mt-safe, and so we need
- * to share serially.
- */
- ms.ms_mntstatus = 0;
- zfs_foreach_mountpoint(zhp->zpool_hdl, cb.cb_handles, cb.cb_used,
- zfs_share_one, &ms, 1);
- if (ms.ms_mntstatus != 0)
- ret = EZFS_SHAREFAILED;
- else
- zfs_commit_shares(NULL);
-
-out:
- for (int i = 0; i < cb.cb_used; i++)
- zfs_close(cb.cb_handles[i]);
- free(cb.cb_handles);
-
- return (ret);
-}
-
-struct sets_s {
- char *mountpoint;
- zfs_handle_t *dataset;
-};
-
-static int
-mountpoint_compare(const void *a, const void *b)
-{
- const struct sets_s *mounta = (struct sets_s *)a;
- const struct sets_s *mountb = (struct sets_s *)b;
-
- return (strcmp(mountb->mountpoint, mounta->mountpoint));
-}
-
-/*
- * 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,
- * because this may be expensive (if not all of them are mounted), and can fail
- * arbitrarily (on I/O error, for example). Instead, we walk /proc/self/mounts
- * and gather all the filesystems that are currently mounted.
- */
-int
-zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
-{
- int used, alloc;
- FILE *mnttab;
- struct mnttab entry;
- size_t namelen;
- struct sets_s *sets = NULL;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- int i;
- int ret = -1;
- int flags = (force ? MS_FORCE : 0);
-
- namelen = strlen(zhp->zpool_name);
-
- if ((mnttab = fopen(MNTTAB, "re")) == NULL)
- return (ENOENT);
-
- used = alloc = 0;
- while (getmntent(mnttab, &entry) == 0) {
- /*
- * Ignore non-ZFS entries.
- */
- if (entry.mnt_fstype == NULL ||
- strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
- continue;
-
- /*
- * Ignore filesystems not within this pool.
- */
- if (entry.mnt_mountp == NULL ||
- strncmp(entry.mnt_special, zhp->zpool_name, namelen) != 0 ||
- (entry.mnt_special[namelen] != '/' &&
- entry.mnt_special[namelen] != '\0'))
- continue;
-
- /*
- * At this point we've found a filesystem within our pool. Add
- * it to our growing list.
- */
- if (used == alloc) {
- if (alloc == 0) {
- sets = zfs_alloc(hdl,
- 8 * sizeof (struct sets_s));
- alloc = 8;
- } else {
- sets = zfs_realloc(hdl, sets,
- alloc * sizeof (struct sets_s),
- alloc * 2 * sizeof (struct sets_s));
-
- alloc *= 2;
- }
- }
-
- sets[used].mountpoint = zfs_strdup(hdl, entry.mnt_mountp);
-
- /*
- * This is allowed to fail, in case there is some I/O error. It
- * is only used to determine if we need to remove the underlying
- * mountpoint, so failure is not fatal.
- */
- sets[used].dataset = make_dataset_handle(hdl,
- entry.mnt_special);
-
- used++;
- }
-
- /*
- * At this point, we have the entire list of filesystems, so sort it by
- * mountpoint.
- */
- if (used != 0)
- qsort(sets, used, sizeof (struct sets_s), mountpoint_compare);
-
- /*
- * Walk through and first unshare everything.
- */
- for (i = 0; i < used; i++) {
- for (enum sa_protocol p = 0; p < SA_PROTOCOL_COUNT; ++p) {
- if (sa_is_shared(sets[i].mountpoint, p) &&
- unshare_one(hdl, sets[i].mountpoint,
- sets[i].mountpoint, p) != 0)
- goto out;
- }
- }
- zfs_commit_shares(NULL);
-
- /*
- * Now unmount everything, removing the underlying directories as
- * appropriate.
- */
- for (i = 0; i < used; i++) {
- if (unmount_one(sets[i].dataset, sets[i].mountpoint,
- flags) != 0)
- goto out;
- }
-
- for (i = 0; i < used; i++) {
- if (sets[i].dataset)
- remove_mountpoint(sets[i].dataset);
- }
-
- zpool_disable_datasets_os(zhp, force);
-
- ret = 0;
-out:
- (void) fclose(mnttab);
- for (i = 0; i < used; i++) {
- if (sets[i].dataset)
- zfs_close(sets[i].dataset);
- free(sets[i].mountpoint);
- }
- free(sets);
-
- return (ret);
-}
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
deleted file mode 100644
index ce154ae1a4cd..000000000000
--- a/lib/libzfs/libzfs_pool.c
+++ /dev/null
@@ -1,5763 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2024 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright (c) 2018 Datto Inc.
- * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
- * Copyright (c) 2017, Intel Corporation.
- * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
- * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
- * Copyright (c) 2021, 2023, Klara Inc.
- * Copyright (c) 2025 Hewlett Packard Enterprise Development LP.
- */
-
-#include <errno.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <zone.h>
-#include <sys/stat.h>
-#include <sys/efi_partition.h>
-#include <sys/systeminfo.h>
-#include <sys/zfs_ioctl.h>
-#include <sys/zfs_sysfs.h>
-#include <sys/vdev_disk.h>
-#include <sys/types.h>
-#include <dlfcn.h>
-#include <libzutil.h>
-#include <fcntl.h>
-
-#include "zfs_namecheck.h"
-#include "zfs_prop.h"
-#include "libzfs_impl.h"
-#include "zfs_comutil.h"
-#include "zfeature_common.h"
-
-static boolean_t zpool_vdev_is_interior(const char *name);
-
-typedef struct prop_flags {
- unsigned int create:1; /* Validate property on creation */
- unsigned int import:1; /* Validate property on import */
- unsigned int vdevprop:1; /* Validate property as a VDEV property */
-} prop_flags_t;
-
-/*
- * ====================================================================
- * zpool property functions
- * ====================================================================
- */
-
-static int
-zpool_get_all_props(zpool_handle_t *zhp)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
-
- if (zhp->zpool_n_propnames > 0) {
- nvlist_t *innvl = fnvlist_alloc();
- fnvlist_add_string_array(innvl, ZPOOL_GET_PROPS_NAMES,
- zhp->zpool_propnames, zhp->zpool_n_propnames);
- zcmd_write_src_nvlist(hdl, &zc, innvl);
- fnvlist_free(innvl);
- }
-
- zcmd_alloc_dst_nvlist(hdl, &zc, 0);
-
- while (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
- if (errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
- else {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
- }
-
- if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
- zcmd_free_nvlists(&zc);
- return (-1);
- }
-
- zcmd_free_nvlists(&zc);
-
- return (0);
-}
-
-int
-zpool_props_refresh(zpool_handle_t *zhp)
-{
- nvlist_t *old_props;
-
- old_props = zhp->zpool_props;
-
- if (zpool_get_all_props(zhp) != 0)
- return (-1);
-
- nvlist_free(old_props);
- return (0);
-}
-
-static const char *
-zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
- zprop_source_t *src)
-{
- nvlist_t *nv, *nvl;
- const char *value;
- zprop_source_t source;
-
- nvl = zhp->zpool_props;
- if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
- source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- value = fnvlist_lookup_string(nv, ZPROP_VALUE);
- } else {
- source = ZPROP_SRC_DEFAULT;
- if ((value = zpool_prop_default_string(prop)) == NULL)
- value = "-";
- }
-
- if (src)
- *src = source;
-
- return (value);
-}
-
-uint64_t
-zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
-{
- nvlist_t *nv, *nvl;
- uint64_t value;
- zprop_source_t source;
-
- if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
- /*
- * zpool_get_all_props() has most likely failed because
- * the pool is faulted, but if all we need is the top level
- * vdev's guid then get it from the zhp config nvlist.
- */
- if ((prop == ZPOOL_PROP_GUID) &&
- (nvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
- (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
- == 0)) {
- return (value);
- }
- return (zpool_prop_default_numeric(prop));
- }
-
- nvl = zhp->zpool_props;
- if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
- source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- value = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
- } else {
- source = ZPROP_SRC_DEFAULT;
- value = zpool_prop_default_numeric(prop);
- }
-
- if (src)
- *src = source;
-
- return (value);
-}
-
-/*
- * Map VDEV STATE to printed strings.
- */
-const char *
-zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
-{
- switch (state) {
- case VDEV_STATE_CLOSED:
- case VDEV_STATE_OFFLINE:
- return (gettext("OFFLINE"));
- case VDEV_STATE_REMOVED:
- return (gettext("REMOVED"));
- case VDEV_STATE_CANT_OPEN:
- if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
- return (gettext("FAULTED"));
- else if (aux == VDEV_AUX_SPLIT_POOL)
- return (gettext("SPLIT"));
- else
- return (gettext("UNAVAIL"));
- case VDEV_STATE_FAULTED:
- return (gettext("FAULTED"));
- case VDEV_STATE_DEGRADED:
- return (gettext("DEGRADED"));
- case VDEV_STATE_HEALTHY:
- return (gettext("ONLINE"));
-
- default:
- break;
- }
-
- return (gettext("UNKNOWN"));
-}
-
-/*
- * Map POOL STATE to printed strings.
- */
-const char *
-zpool_pool_state_to_name(pool_state_t state)
-{
- switch (state) {
- default:
- break;
- case POOL_STATE_ACTIVE:
- return (gettext("ACTIVE"));
- case POOL_STATE_EXPORTED:
- return (gettext("EXPORTED"));
- case POOL_STATE_DESTROYED:
- return (gettext("DESTROYED"));
- case POOL_STATE_SPARE:
- return (gettext("SPARE"));
- case POOL_STATE_L2CACHE:
- return (gettext("L2CACHE"));
- case POOL_STATE_UNINITIALIZED:
- return (gettext("UNINITIALIZED"));
- case POOL_STATE_UNAVAIL:
- return (gettext("UNAVAIL"));
- case POOL_STATE_POTENTIALLY_ACTIVE:
- return (gettext("POTENTIALLY_ACTIVE"));
- }
-
- return (gettext("UNKNOWN"));
-}
-
-/*
- * Given a pool handle, return the pool health string ("ONLINE", "DEGRADED",
- * "SUSPENDED", etc).
- */
-const char *
-zpool_get_state_str(zpool_handle_t *zhp)
-{
- zpool_errata_t errata;
- zpool_status_t status;
- const char *str;
-
- status = zpool_get_status(zhp, NULL, &errata);
-
- if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
- str = gettext("FAULTED");
- } else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
- status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
- status == ZPOOL_STATUS_IO_FAILURE_MMP) {
- str = gettext("SUSPENDED");
- } else {
- nvlist_t *nvroot = fnvlist_lookup_nvlist(
- zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE);
- uint_t vsc;
- vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
- nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc);
- str = zpool_state_to_name(vs->vs_state, vs->vs_aux);
- }
- return (str);
-}
-
-/*
- * Get a zpool property value for 'prop' and return the value in
- * a pre-allocated buffer.
- */
-int
-zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
- size_t len, zprop_source_t *srctype, boolean_t literal)
-{
- uint64_t intval;
- const char *strval;
- zprop_source_t src = ZPROP_SRC_NONE;
-
- if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
- switch (prop) {
- case ZPOOL_PROP_NAME:
- (void) strlcpy(buf, zpool_get_name(zhp), len);
- break;
-
- case ZPOOL_PROP_HEALTH:
- (void) strlcpy(buf, zpool_get_state_str(zhp), len);
- break;
-
- case ZPOOL_PROP_GUID:
- intval = zpool_get_prop_int(zhp, prop, &src);
- (void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
- break;
-
- case ZPOOL_PROP_ALTROOT:
- case ZPOOL_PROP_CACHEFILE:
- case ZPOOL_PROP_COMMENT:
- case ZPOOL_PROP_COMPATIBILITY:
- if (zhp->zpool_props != NULL ||
- zpool_get_all_props(zhp) == 0) {
- (void) strlcpy(buf,
- zpool_get_prop_string(zhp, prop, &src),
- len);
- break;
- }
- zfs_fallthrough;
- default:
- (void) strlcpy(buf, "-", len);
- break;
- }
-
- if (srctype != NULL)
- *srctype = src;
- return (0);
- }
-
- /*
- * ZPOOL_PROP_DEDUPCACHED can be fetched by name only using
- * the ZPOOL_GET_PROPS_NAMES mechanism
- */
- if (prop == ZPOOL_PROP_DEDUPCACHED) {
- zpool_add_propname(zhp, ZPOOL_DEDUPCACHED_PROP_NAME);
- (void) zpool_props_refresh(zhp);
- }
-
- if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
- prop != ZPOOL_PROP_NAME)
- return (-1);
-
- switch (zpool_prop_get_type(prop)) {
- case PROP_TYPE_STRING:
- (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
- len);
- break;
-
- case PROP_TYPE_NUMBER:
- intval = zpool_get_prop_int(zhp, prop, &src);
-
- switch (prop) {
- case ZPOOL_PROP_DEDUP_TABLE_QUOTA:
- /*
- * If dedup quota is 0, we translate this into 'none'
- * (unless literal is set). And if it is UINT64_MAX
- * we translate that as 'automatic' (limit to size of
- * the dedicated dedup VDEV. Otherwise, fall throught
- * into the regular number formating.
- */
- if (intval == 0) {
- (void) strlcpy(buf, literal ? "0" : "none",
- len);
- break;
- } else if (intval == UINT64_MAX) {
- (void) strlcpy(buf, "auto", len);
- break;
- }
- zfs_fallthrough;
-
- case ZPOOL_PROP_SIZE:
- case ZPOOL_PROP_ALLOCATED:
- case ZPOOL_PROP_FREE:
- case ZPOOL_PROP_FREEING:
- case ZPOOL_PROP_LEAKED:
- case ZPOOL_PROP_ASHIFT:
- case ZPOOL_PROP_MAXBLOCKSIZE:
- case ZPOOL_PROP_MAXDNODESIZE:
- case ZPOOL_PROP_BCLONESAVED:
- case ZPOOL_PROP_BCLONEUSED:
- case ZPOOL_PROP_DEDUP_TABLE_SIZE:
- case ZPOOL_PROP_DEDUPCACHED:
- if (literal)
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- else
- (void) zfs_nicenum(intval, buf, len);
- break;
-
- case ZPOOL_PROP_EXPANDSZ:
- case ZPOOL_PROP_CHECKPOINT:
- if (intval == 0) {
- (void) strlcpy(buf, "-", len);
- } else if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) zfs_nicebytes(intval, buf, len);
- }
- break;
-
- case ZPOOL_PROP_CAPACITY:
- if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) snprintf(buf, len, "%llu%%",
- (u_longlong_t)intval);
- }
- break;
-
- case ZPOOL_PROP_FRAGMENTATION:
- if (intval == UINT64_MAX) {
- (void) strlcpy(buf, "-", len);
- } else if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) snprintf(buf, len, "%llu%%",
- (u_longlong_t)intval);
- }
- break;
-
- case ZPOOL_PROP_BCLONERATIO:
- case ZPOOL_PROP_DEDUPRATIO:
- if (literal)
- (void) snprintf(buf, len, "%llu.%02llu",
- (u_longlong_t)(intval / 100),
- (u_longlong_t)(intval % 100));
- else
- (void) snprintf(buf, len, "%llu.%02llux",
- (u_longlong_t)(intval / 100),
- (u_longlong_t)(intval % 100));
- break;
-
- case ZPOOL_PROP_HEALTH:
- (void) strlcpy(buf, zpool_get_state_str(zhp), len);
- break;
- case ZPOOL_PROP_VERSION:
- if (intval >= SPA_VERSION_FEATURES) {
- (void) snprintf(buf, len, "-");
- break;
- }
- zfs_fallthrough;
- default:
- (void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
- }
- break;
-
- case PROP_TYPE_INDEX:
- intval = zpool_get_prop_int(zhp, prop, &src);
- if (zpool_prop_index_to_string(prop, intval, &strval)
- != 0)
- return (-1);
- (void) strlcpy(buf, strval, len);
- break;
-
- default:
- abort();
- }
-
- if (srctype)
- *srctype = src;
-
- return (0);
-}
-
-/*
- * Get a zpool property value for 'propname' and return the value in
- * a pre-allocated buffer.
- */
-int
-zpool_get_userprop(zpool_handle_t *zhp, const char *propname, char *buf,
- size_t len, zprop_source_t *srctype)
-{
- nvlist_t *nv;
- uint64_t ival;
- const char *value;
- zprop_source_t source = ZPROP_SRC_LOCAL;
-
- if (zhp->zpool_props == NULL)
- zpool_get_all_props(zhp);
-
- if (nvlist_lookup_nvlist(zhp->zpool_props, propname, &nv) == 0) {
- if (nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0)
- source = ival;
- verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
- } else {
- source = ZPROP_SRC_DEFAULT;
- value = "-";
- }
-
- if (srctype)
- *srctype = source;
-
- (void) strlcpy(buf, value, len);
-
- return (0);
-}
-
-/*
- * Check if the bootfs name has the same pool name as it is set to.
- * Assuming bootfs is a valid dataset name.
- */
-static boolean_t
-bootfs_name_valid(const char *pool, const char *bootfs)
-{
- int len = strlen(pool);
- if (bootfs[0] == '\0')
- return (B_TRUE);
-
- if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
- return (B_FALSE);
-
- if (strncmp(pool, bootfs, len) == 0 &&
- (bootfs[len] == '/' || bootfs[len] == '\0'))
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-/*
- * Given an nvlist of zpool properties to be set, validate that they are
- * correct, and parse any numeric properties (index, boolean, etc) if they are
- * specified as strings.
- */
-static nvlist_t *
-zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
- nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
-{
- nvpair_t *elem;
- nvlist_t *retprops;
- zpool_prop_t prop;
- const char *strval;
- uint64_t intval;
- const char *check;
- struct stat64 statbuf;
- zpool_handle_t *zhp;
- char *parent, *slash;
- char report[1024];
-
- if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
- (void) no_memory(hdl);
- return (NULL);
- }
-
- elem = NULL;
- while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
- const char *propname = nvpair_name(elem);
-
- if (flags.vdevprop && zpool_prop_vdev(propname)) {
- vdev_prop_t vprop = vdev_name_to_prop(propname);
-
- if (vdev_prop_readonly(vprop)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
- "is readonly"), propname);
- (void) zfs_error(hdl, EZFS_PROPREADONLY,
- errbuf);
- goto error;
- }
-
- if (zprop_parse_value(hdl, elem, vprop, ZFS_TYPE_VDEV,
- retprops, &strval, &intval, errbuf) != 0)
- goto error;
-
- continue;
- } else if (flags.vdevprop && vdev_prop_user(propname)) {
- if (nvlist_add_nvpair(retprops, elem) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
- continue;
- } else if (flags.vdevprop) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property: '%s'"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- prop = zpool_name_to_prop(propname);
- if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) {
- int err;
- char *fname = strchr(propname, '@') + 1;
-
- err = zfeature_lookup_name(fname, NULL);
- if (err != 0) {
- ASSERT3U(err, ==, ENOENT);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "feature '%s' unsupported by kernel"),
- fname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (nvpair_type(elem) != DATA_TYPE_STRING) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a string"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- (void) nvpair_value_string(elem, &strval);
- if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0 &&
- strcmp(strval, ZFS_FEATURE_DISABLED) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' can only be set to "
- "'enabled' or 'disabled'"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (!flags.create &&
- strcmp(strval, ZFS_FEATURE_DISABLED) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' can only be set to "
- "'disabled' at creation time"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (nvlist_add_uint64(retprops, propname, 0) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
- continue;
- } else if (prop == ZPOOL_PROP_INVAL &&
- zfs_prop_user(propname)) {
- /*
- * This is a user property: make sure it's a
- * string, and that it's less than ZAP_MAXNAMELEN.
- */
- if (nvpair_type(elem) != DATA_TYPE_STRING) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a string"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property name '%s' is too long"),
- propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- (void) nvpair_value_string(elem, &strval);
-
- if (strlen(strval) >= ZFS_MAXPROPLEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property value '%s' is too long"),
- strval);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (nvlist_add_string(retprops, propname,
- strval) != 0) {
- (void) no_memory(hdl);
- goto error;
- }
-
- continue;
- }
-
- /*
- * Make sure this property is valid and applies to this type.
- */
- if (prop == ZPOOL_PROP_INVAL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property '%s'"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (zpool_prop_readonly(prop)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
- "is readonly"), propname);
- (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
- goto error;
- }
-
- if (!flags.create && zpool_prop_setonce(prop)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' can only be set at "
- "creation time"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
- &strval, &intval, errbuf) != 0)
- goto error;
-
- /*
- * Perform additional checking for specific properties.
- */
- switch (prop) {
- case ZPOOL_PROP_VERSION:
- if (intval < version ||
- !SPA_VERSION_IS_SUPPORTED(intval)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' number %llu is invalid."),
- propname, (unsigned long long)intval);
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- goto error;
- }
- break;
-
- case ZPOOL_PROP_ASHIFT:
- if (intval != 0 &&
- (intval < ASHIFT_MIN || intval > ASHIFT_MAX)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "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;
- }
- break;
-
- case ZPOOL_PROP_BOOTFS:
- if (flags.create || flags.import) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' cannot be set at creation "
- "or import time"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (version < SPA_VERSION_BOOTFS) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded to support "
- "'%s' property"), propname);
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- goto error;
- }
-
- /*
- * bootfs property value has to be a dataset name and
- * the dataset has to be in the same pool as it sets to.
- */
- if (!bootfs_name_valid(poolname, strval)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
- "is an invalid name"), strval);
- (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto error;
- }
-
- if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "could not open pool '%s'"), poolname);
- (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
- goto error;
- }
- zpool_close(zhp);
- break;
-
- case ZPOOL_PROP_ALTROOT:
- if (!flags.create && !flags.import) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' can only be set during pool "
- "creation or import"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- if (strval[0] != '/') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "bad alternate root '%s'"), strval);
- (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
- goto error;
- }
- break;
-
- case ZPOOL_PROP_CACHEFILE:
- if (strval[0] == '\0')
- break;
-
- if (strcmp(strval, "none") == 0)
- break;
-
- if (strval[0] != '/') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' must be empty, an "
- "absolute path, or 'none'"), propname);
- (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
- goto error;
- }
-
- parent = strdup(strval);
- if (parent == NULL) {
- (void) zfs_error(hdl, EZFS_NOMEM, errbuf);
- goto error;
- }
- slash = strrchr(parent, '/');
-
- if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
- strcmp(slash, "/..") == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is not a valid file"), parent);
- (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
- free(parent);
- goto error;
- }
-
- *slash = '\0';
-
- if (parent[0] != '\0' &&
- (stat64(parent, &statbuf) != 0 ||
- !S_ISDIR(statbuf.st_mode))) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is not a valid directory"),
- parent);
- (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
- free(parent);
- goto error;
- }
- free(parent);
-
- break;
-
- case ZPOOL_PROP_COMPATIBILITY:
- switch (zpool_load_compat(strval, NULL, report, 1024)) {
- case ZPOOL_COMPATIBILITY_OK:
- case ZPOOL_COMPATIBILITY_WARNTOKEN:
- break;
- case ZPOOL_COMPATIBILITY_BADFILE:
- case ZPOOL_COMPATIBILITY_BADTOKEN:
- case ZPOOL_COMPATIBILITY_NOFILES:
- zfs_error_aux(hdl, "%s", report);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
-
- case ZPOOL_PROP_COMMENT:
- for (check = strval; *check != '\0'; check++) {
- if (!isprint(*check)) {
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN,
- "comment may only have printable "
- "characters"));
- (void) zfs_error(hdl, EZFS_BADPROP,
- errbuf);
- goto error;
- }
- }
- if (strlen(strval) > ZPROP_MAX_COMMENT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "comment must not exceed %d characters"),
- ZPROP_MAX_COMMENT);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- case ZPOOL_PROP_READONLY:
- if (!flags.import) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' can only be set at "
- "import time"), propname);
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- case ZPOOL_PROP_MULTIHOST:
- if (get_system_hostid() == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "requires a non-zero system hostid"));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- break;
- case ZPOOL_PROP_DEDUPDITTO:
- printf("Note: property '%s' no longer has "
- "any effect\n", propname);
- break;
-
- default:
- break;
- }
- }
-
- return (retprops);
-error:
- nvlist_free(retprops);
- return (NULL);
-}
-
-/*
- * Set zpool property : propname=propval.
- */
-int
-zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
-{
- zfs_cmd_t zc = {"\0"};
- int ret;
- char errbuf[ERRBUFLEN];
- nvlist_t *nvl = NULL;
- nvlist_t *realprops;
- uint64_t version;
- prop_flags_t flags = { 0 };
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
- zhp->zpool_name);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
-
- if (nvlist_add_string(nvl, propname, propval) != 0) {
- nvlist_free(nvl);
- return (no_memory(zhp->zpool_hdl));
- }
-
- version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
- if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
- zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
- nvlist_free(nvl);
- return (-1);
- }
-
- nvlist_free(nvl);
- nvl = realprops;
-
- /*
- * Execute the corresponding ioctl() to set this property.
- */
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
-
- zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl);
-
- ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
-
- zcmd_free_nvlists(&zc);
- nvlist_free(nvl);
-
- if (ret)
- (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
- else
- (void) zpool_props_refresh(zhp);
-
- return (ret);
-}
-
-int
-zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
- zfs_type_t type, boolean_t literal)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- zprop_list_t *entry;
- char buf[ZFS_MAXPROPLEN];
- nvlist_t *features = NULL;
- nvpair_t *nvp;
- zprop_list_t **last;
- boolean_t firstexpand = (NULL == *plp);
- int i;
-
- if (zprop_expand_list(hdl, plp, type) != 0)
- return (-1);
-
- if (type == ZFS_TYPE_VDEV)
- return (0);
-
- last = plp;
- while (*last != NULL)
- last = &(*last)->pl_next;
-
- if ((*plp)->pl_all)
- features = zpool_get_features(zhp);
-
- if ((*plp)->pl_all && firstexpand) {
- /* Handle userprops in the all properties case */
- if (zhp->zpool_props == NULL && zpool_props_refresh(zhp))
- return (-1);
-
- nvp = NULL;
- while ((nvp = nvlist_next_nvpair(zhp->zpool_props, nvp)) !=
- NULL) {
- const char *propname = nvpair_name(nvp);
-
- if (!zfs_prop_user(propname))
- continue;
-
- entry = zfs_alloc(hdl, sizeof (zprop_list_t));
- entry->pl_prop = ZPROP_USERPROP;
- entry->pl_user_prop = zfs_strdup(hdl, propname);
- entry->pl_width = strlen(entry->pl_user_prop);
- entry->pl_all = B_TRUE;
-
- *last = entry;
- last = &entry->pl_next;
- }
-
- for (i = 0; i < SPA_FEATURES; i++) {
- entry = zfs_alloc(hdl, sizeof (zprop_list_t));
- entry->pl_prop = ZPROP_USERPROP;
- entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
- spa_feature_table[i].fi_uname);
- entry->pl_width = strlen(entry->pl_user_prop);
- entry->pl_all = B_TRUE;
-
- *last = entry;
- last = &entry->pl_next;
- }
- }
-
- /* add any unsupported features */
- for (nvp = nvlist_next_nvpair(features, NULL);
- nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
- char *propname;
- boolean_t found;
-
- if (zfeature_is_supported(nvpair_name(nvp)))
- continue;
-
- propname = zfs_asprintf(hdl, "unsupported@%s",
- nvpair_name(nvp));
-
- /*
- * Before adding the property to the list make sure that no
- * other pool already added the same property.
- */
- found = B_FALSE;
- entry = *plp;
- while (entry != NULL) {
- if (entry->pl_user_prop != NULL &&
- strcmp(propname, entry->pl_user_prop) == 0) {
- found = B_TRUE;
- break;
- }
- entry = entry->pl_next;
- }
- if (found) {
- free(propname);
- continue;
- }
-
- entry = zfs_alloc(hdl, sizeof (zprop_list_t));
- entry->pl_prop = ZPROP_USERPROP;
- entry->pl_user_prop = propname;
- entry->pl_width = strlen(entry->pl_user_prop);
- entry->pl_all = B_TRUE;
-
- *last = entry;
- last = &entry->pl_next;
- }
-
- for (entry = *plp; entry != NULL; entry = entry->pl_next) {
- if (entry->pl_fixed && !literal)
- continue;
-
- if (entry->pl_prop != ZPROP_USERPROP &&
- zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
- NULL, literal) == 0) {
- if (strlen(buf) > entry->pl_width)
- entry->pl_width = strlen(buf);
- } else if (entry->pl_prop == ZPROP_INVAL &&
- zfs_prop_user(entry->pl_user_prop) &&
- zpool_get_userprop(zhp, entry->pl_user_prop, buf,
- sizeof (buf), NULL) == 0) {
- if (strlen(buf) > entry->pl_width)
- entry->pl_width = strlen(buf);
- }
- }
-
- return (0);
-}
-
-int
-vdev_expand_proplist(zpool_handle_t *zhp, const char *vdevname,
- zprop_list_t **plp)
-{
- zprop_list_t *entry;
- char buf[ZFS_MAXPROPLEN];
- const char *strval = NULL;
- int err = 0;
- nvpair_t *elem = NULL;
- nvlist_t *vprops = NULL;
- nvlist_t *propval = NULL;
- const char *propname;
- vdev_prop_t prop;
- zprop_list_t **last;
-
- for (entry = *plp; entry != NULL; entry = entry->pl_next) {
- if (entry->pl_fixed)
- continue;
-
- if (zpool_get_vdev_prop(zhp, vdevname, entry->pl_prop,
- entry->pl_user_prop, buf, sizeof (buf), NULL,
- B_FALSE) == 0) {
- if (strlen(buf) > entry->pl_width)
- entry->pl_width = strlen(buf);
- }
- if (entry->pl_prop == VDEV_PROP_NAME &&
- strlen(vdevname) > entry->pl_width)
- entry->pl_width = strlen(vdevname);
- }
-
- /* Handle the all properties case */
- last = plp;
- if (*last != NULL && (*last)->pl_all == B_TRUE) {
- while (*last != NULL)
- last = &(*last)->pl_next;
-
- err = zpool_get_all_vdev_props(zhp, vdevname, &vprops);
- if (err != 0)
- return (err);
-
- while ((elem = nvlist_next_nvpair(vprops, elem)) != NULL) {
- propname = nvpair_name(elem);
-
- /* Skip properties that are not user defined */
- if ((prop = vdev_name_to_prop(propname)) !=
- VDEV_PROP_USERPROP)
- continue;
-
- if (nvpair_value_nvlist(elem, &propval) != 0)
- continue;
-
- strval = fnvlist_lookup_string(propval, ZPROP_VALUE);
-
- entry = zfs_alloc(zhp->zpool_hdl,
- sizeof (zprop_list_t));
- entry->pl_prop = prop;
- entry->pl_user_prop = zfs_strdup(zhp->zpool_hdl,
- propname);
- entry->pl_width = strlen(strval);
- entry->pl_all = B_TRUE;
- *last = entry;
- last = &entry->pl_next;
- }
- }
-
- return (0);
-}
-
-/*
- * Get the state for the given feature on the given ZFS pool.
- */
-int
-zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
- size_t len)
-{
- uint64_t refcount;
- boolean_t found = B_FALSE;
- nvlist_t *features = zpool_get_features(zhp);
- boolean_t supported;
- const char *feature = strchr(propname, '@') + 1;
-
- supported = zpool_prop_feature(propname);
- ASSERT(supported || zpool_prop_unsupported(propname));
-
- /*
- * Convert from feature name to feature guid. This conversion is
- * unnecessary for unsupported@... properties because they already
- * use guids.
- */
- if (supported) {
- int ret;
- spa_feature_t fid;
-
- ret = zfeature_lookup_name(feature, &fid);
- if (ret != 0) {
- (void) strlcpy(buf, "-", len);
- return (ENOTSUP);
- }
- feature = spa_feature_table[fid].fi_guid;
- }
-
- if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
- found = B_TRUE;
-
- if (supported) {
- if (!found) {
- (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
- } else {
- if (refcount == 0)
- (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
- else
- (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
- }
- } else {
- if (found) {
- if (refcount == 0) {
- (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
- } else {
- (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
- }
- } else {
- (void) strlcpy(buf, "-", len);
- return (ENOTSUP);
- }
- }
-
- return (0);
-}
-
-/*
- * Validate the given pool name, optionally putting an extended error message in
- * 'buf'.
- */
-boolean_t
-zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
-{
- namecheck_err_t why;
- char what;
- int ret;
-
- ret = pool_namecheck(pool, &why, &what);
-
- /*
- * The rules for reserved pool names were extended at a later point.
- * But we need to support users with existing pools that may now be
- * invalid. So we only check for this expanded set of names during a
- * create (or import), and only in userland.
- */
- if (ret == 0 && !isopen &&
- (strncmp(pool, "mirror", 6) == 0 ||
- strncmp(pool, "raidz", 5) == 0 ||
- strncmp(pool, "draid", 5) == 0 ||
- strncmp(pool, "spare", 5) == 0 ||
- strcmp(pool, "log") == 0)) {
- if (hdl != NULL)
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "name is reserved"));
- return (B_FALSE);
- }
-
-
- if (ret != 0) {
- if (hdl != NULL) {
- switch (why) {
- case NAME_ERR_TOOLONG:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "name is too long"));
- break;
-
- case NAME_ERR_INVALCHAR:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "invalid character "
- "'%c' in pool name"), what);
- break;
-
- case NAME_ERR_NOLETTER:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "name must begin with a letter"));
- break;
-
- case NAME_ERR_RESERVED:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "name is reserved"));
- break;
-
- case NAME_ERR_DISKLIKE:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool name is reserved"));
- break;
-
- case NAME_ERR_LEADING_SLASH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "leading slash in name"));
- break;
-
- case NAME_ERR_EMPTY_COMPONENT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "empty component in name"));
- break;
-
- case NAME_ERR_TRAILING_SLASH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "trailing slash in name"));
- break;
-
- case NAME_ERR_MULTIPLE_DELIMITERS:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "multiple '@' and/or '#' delimiters in "
- "name"));
- break;
-
- case NAME_ERR_NO_AT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "permission set is missing '@'"));
- break;
-
- default:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "(%d) not defined"), why);
- break;
- }
- }
- return (B_FALSE);
- }
-
- return (B_TRUE);
-}
-
-/*
- * Open a handle to the given pool, even if the pool is currently in the FAULTED
- * state.
- */
-zpool_handle_t *
-zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
-{
- zpool_handle_t *zhp;
- boolean_t missing;
-
- /*
- * Make sure the pool name is valid.
- */
- if (!zpool_name_valid(hdl, B_TRUE, pool)) {
- (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
- dgettext(TEXT_DOMAIN, "cannot open '%s'"),
- pool);
- return (NULL);
- }
-
- zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
-
- zhp->zpool_hdl = hdl;
- (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
-
- if (zpool_refresh_stats(zhp, &missing) != 0) {
- zpool_close(zhp);
- return (NULL);
- }
-
- if (missing) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
- (void) zfs_error_fmt(hdl, EZFS_NOENT,
- dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
- zpool_close(zhp);
- return (NULL);
- }
-
- return (zhp);
-}
-
-/*
- * Like the above, but silent on error. Used when iterating over pools (because
- * the configuration cache may be out of date).
- */
-int
-zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
-{
- zpool_handle_t *zhp;
- boolean_t missing;
-
- zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
-
- zhp->zpool_hdl = hdl;
- (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
-
- if (zpool_refresh_stats(zhp, &missing) != 0) {
- zpool_close(zhp);
- return (-1);
- }
-
- if (missing) {
- zpool_close(zhp);
- *ret = NULL;
- return (0);
- }
-
- *ret = zhp;
- return (0);
-}
-
-/*
- * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
- * state.
- */
-zpool_handle_t *
-zpool_open(libzfs_handle_t *hdl, const char *pool)
-{
- zpool_handle_t *zhp;
-
- if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
- return (NULL);
-
- if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
- (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
- dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
- zpool_close(zhp);
- return (NULL);
- }
-
- return (zhp);
-}
-
-/*
- * Close the handle. Simply frees the memory associated with the handle.
- */
-void
-zpool_close(zpool_handle_t *zhp)
-{
- nvlist_free(zhp->zpool_config);
- nvlist_free(zhp->zpool_old_config);
- nvlist_free(zhp->zpool_props);
- free(zhp);
-}
-
-/*
- * Return the name of the pool.
- */
-const char *
-zpool_get_name(zpool_handle_t *zhp)
-{
- return (zhp->zpool_name);
-}
-
-
-/*
- * Return the state of the pool (ACTIVE or UNAVAILABLE)
- */
-int
-zpool_get_state(zpool_handle_t *zhp)
-{
- return (zhp->zpool_state);
-}
-
-/*
- * Check if vdev list contains a dRAID vdev
- */
-static boolean_t
-zpool_has_draid_vdev(nvlist_t *nvroot)
-{
- nvlist_t **child;
- uint_t children;
-
- if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
- &child, &children) == 0) {
- for (uint_t c = 0; c < children; c++) {
- const char *type;
-
- if (nvlist_lookup_string(child[c],
- ZPOOL_CONFIG_TYPE, &type) == 0 &&
- strcmp(type, VDEV_TYPE_DRAID) == 0) {
- return (B_TRUE);
- }
- }
- }
- return (B_FALSE);
-}
-
-/*
- * Output a dRAID top-level vdev name in to the provided buffer.
- */
-static char *
-zpool_draid_name(char *name, int len, uint64_t data, uint64_t parity,
- uint64_t spares, uint64_t children)
-{
- snprintf(name, len, "%s%llu:%llud:%lluc:%llus",
- VDEV_TYPE_DRAID, (u_longlong_t)parity, (u_longlong_t)data,
- (u_longlong_t)children, (u_longlong_t)spares);
-
- return (name);
-}
-
-/*
- * Return B_TRUE if the provided name is a dRAID spare name.
- */
-boolean_t
-zpool_is_draid_spare(const char *name)
-{
- uint64_t spare_id, parity, vdev_id;
-
- if (sscanf(name, VDEV_TYPE_DRAID "%llu-%llu-%llu",
- (u_longlong_t *)&parity, (u_longlong_t *)&vdev_id,
- (u_longlong_t *)&spare_id) == 3) {
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-/*
- * Create the named pool, using the provided vdev list. It is assumed
- * that the consumer has already validated the contents of the nvlist, so we
- * don't have to worry about error semantics.
- */
-int
-zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
- nvlist_t *props, nvlist_t *fsprops)
-{
- zfs_cmd_t zc = {"\0"};
- nvlist_t *zc_fsprops = NULL;
- nvlist_t *zc_props = NULL;
- nvlist_t *hidden_args = NULL;
- uint8_t *wkeydata = NULL;
- uint_t wkeylen = 0;
- char errbuf[ERRBUFLEN];
- int ret = -1;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot create '%s'"), pool);
-
- if (!zpool_name_valid(hdl, B_FALSE, pool))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- zcmd_write_conf_nvlist(hdl, &zc, nvroot);
-
- if (props) {
- prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
-
- if ((zc_props = zpool_valid_proplist(hdl, pool, props,
- SPA_VERSION_1, flags, errbuf)) == NULL) {
- goto create_failed;
- }
- }
-
- if (fsprops) {
- uint64_t zoned;
- const char *zonestr;
-
- zoned = ((nvlist_lookup_string(fsprops,
- zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
- strcmp(zonestr, "on") == 0);
-
- if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
- fsprops, zoned, NULL, NULL, B_TRUE, errbuf)) == NULL) {
- goto create_failed;
- }
-
- if (!zc_props &&
- (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
- goto create_failed;
- }
- if (zfs_crypto_create(hdl, NULL, zc_fsprops, props, B_TRUE,
- &wkeydata, &wkeylen) != 0) {
- zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
- goto create_failed;
- }
- if (nvlist_add_nvlist(zc_props,
- ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
- goto create_failed;
- }
- if (wkeydata != NULL) {
- if (nvlist_alloc(&hidden_args, NV_UNIQUE_NAME, 0) != 0)
- goto create_failed;
-
- if (nvlist_add_uint8_array(hidden_args, "wkeydata",
- wkeydata, wkeylen) != 0)
- goto create_failed;
-
- if (nvlist_add_nvlist(zc_props, ZPOOL_HIDDEN_ARGS,
- hidden_args) != 0)
- goto create_failed;
- }
- }
-
- if (zc_props)
- zcmd_write_src_nvlist(hdl, &zc, zc_props);
-
- (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
-
- if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
-
- zcmd_free_nvlists(&zc);
- nvlist_free(zc_props);
- nvlist_free(zc_fsprops);
- nvlist_free(hidden_args);
- if (wkeydata != NULL)
- free(wkeydata);
-
- switch (errno) {
- case EBUSY:
- /*
- * This can happen if the user has specified the same
- * device multiple times. We can't reliably detect this
- * until we try to add it and see we already have a
- * label. This can also happen under if the device is
- * part of an active md or lvm device.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more vdevs refer to the same device, or "
- "one of\nthe devices is part of an active md or "
- "lvm device"));
- return (zfs_error(hdl, EZFS_BADDEV, errbuf));
-
- case ERANGE:
- /*
- * This happens if the record size is smaller or larger
- * than the allowed size range, or not a power of 2.
- *
- * NOTE: although zfs_valid_proplist is called earlier,
- * this case may have slipped through since the
- * pool does not exist yet and it is therefore
- * impossible to read properties e.g. max blocksize
- * from the pool.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "record size invalid"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
-
- case EOVERFLOW:
- /*
- * This occurs when one of the devices is below
- * SPA_MINDEVSIZE. Unfortunately, we can't detect which
- * device was the problem device since there's no
- * reliable way to determine device size from userland.
- */
- {
- char buf[64];
-
- zfs_nicebytes(SPA_MINDEVSIZE, buf,
- sizeof (buf));
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices is less than the "
- "minimum size (%s)"), buf);
- }
- return (zfs_error(hdl, EZFS_BADDEV, errbuf));
-
- case ENOSPC:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices is out of space"));
- return (zfs_error(hdl, EZFS_BADDEV, errbuf));
-
- case EINVAL:
- if (zpool_has_draid_vdev(nvroot) &&
- zfeature_lookup_name("draid", NULL) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dRAID vdevs are unsupported by the "
- "kernel"));
- return (zfs_error(hdl, EZFS_BADDEV, errbuf));
- } else {
- return (zpool_standard_error(hdl, errno,
- errbuf));
- }
-
- default:
- return (zpool_standard_error(hdl, errno, errbuf));
- }
- }
-
-create_failed:
- zcmd_free_nvlists(&zc);
- nvlist_free(zc_props);
- nvlist_free(zc_fsprops);
- nvlist_free(hidden_args);
- if (wkeydata != NULL)
- free(wkeydata);
- return (ret);
-}
-
-/*
- * Destroy the given pool. It is up to the caller to ensure that there are no
- * datasets left in the pool.
- */
-int
-zpool_destroy(zpool_handle_t *zhp, const char *log_str)
-{
- zfs_cmd_t zc = {"\0"};
- zfs_handle_t *zfp = NULL;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char errbuf[ERRBUFLEN];
-
- if (zhp->zpool_state == POOL_STATE_ACTIVE &&
- (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
- return (-1);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_history = (uint64_t)(uintptr_t)log_str;
-
- if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot destroy '%s'"), zhp->zpool_name);
-
- if (errno == EROFS) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices is read only"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- } else {
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
-
- if (zfp)
- zfs_close(zfp);
- return (-1);
- }
-
- if (zfp) {
- remove_mountpoint(zfp);
- zfs_close(zfp);
- }
-
- return (0);
-}
-
-/*
- * Create a checkpoint in the given pool.
- */
-int
-zpool_checkpoint(zpool_handle_t *zhp)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char errbuf[ERRBUFLEN];
- int error;
-
- error = lzc_pool_checkpoint(zhp->zpool_name);
- if (error != 0) {
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot checkpoint '%s'"), zhp->zpool_name);
- (void) zpool_standard_error(hdl, error, errbuf);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Discard the checkpoint from the given pool.
- */
-int
-zpool_discard_checkpoint(zpool_handle_t *zhp)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char errbuf[ERRBUFLEN];
- int error;
-
- error = lzc_pool_checkpoint_discard(zhp->zpool_name);
- if (error != 0) {
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot discard checkpoint in '%s'"), zhp->zpool_name);
- (void) zpool_standard_error(hdl, error, errbuf);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Load data type for the given pool.
- */
-int
-zpool_prefetch(zpool_handle_t *zhp, zpool_prefetch_type_t type)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char msg[1024];
- int error;
-
- error = lzc_pool_prefetch(zhp->zpool_name, type);
- if (error != 0) {
- (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
- "cannot prefetch %s in '%s'"),
- type == ZPOOL_PREFETCH_DDT ? "ddt" : "", zhp->zpool_name);
- (void) zpool_standard_error(hdl, error, msg);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Add the given vdevs to the pool. The caller must have already performed the
- * necessary verification to ensure that the vdev specification is well-formed.
- */
-int
-zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot, boolean_t check_ashift)
-{
- zfs_cmd_t zc = {"\0"};
- int ret;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char errbuf[ERRBUFLEN];
- nvlist_t **spares, **l2cache;
- uint_t nspares, nl2cache;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot add to '%s'"), zhp->zpool_name);
-
- if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
- SPA_VERSION_SPARES &&
- nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
- &spares, &nspares) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
- "upgraded to add hot spares"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
- }
-
- if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
- SPA_VERSION_L2CACHE &&
- nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
- &l2cache, &nl2cache) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
- "upgraded to add cache devices"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
- }
-
- zcmd_write_conf_nvlist(hdl, &zc, nvroot);
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_flags = check_ashift;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
- switch (errno) {
- case EBUSY:
- /*
- * This can happen if the user has specified the same
- * device multiple times. We can't reliably detect this
- * until we try to add it and see we already have a
- * label.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more vdevs refer to the same device"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case EINVAL:
-
- if (zpool_has_draid_vdev(nvroot) &&
- zfeature_lookup_name("draid", NULL) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dRAID vdevs are unsupported by the "
- "kernel"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid config; a pool with removing/"
- "removed vdevs does not support adding "
- "raidz or dRAID vdevs"));
- }
-
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case EOVERFLOW:
- /*
- * This occurs when one of the devices is below
- * SPA_MINDEVSIZE. Unfortunately, we can't detect which
- * device was the problem device since there's no
- * reliable way to determine device size from userland.
- */
- {
- char buf[64];
-
- zfs_nicebytes(SPA_MINDEVSIZE, buf,
- sizeof (buf));
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "device is less than the minimum "
- "size (%s)"), buf);
- }
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded to add these vdevs"));
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
-
- default:
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
-
- ret = -1;
- } else {
- ret = 0;
- }
-
- zcmd_free_nvlists(&zc);
-
- return (ret);
-}
-
-/*
- * Exports the pool from the system. The caller must ensure that there are no
- * mounted datasets in the pool.
- */
-static int
-zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
- const char *log_str)
-{
- zfs_cmd_t zc = {"\0"};
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_cookie = force;
- zc.zc_guid = hardforce;
- zc.zc_history = (uint64_t)(uintptr_t)log_str;
-
- if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
- switch (errno) {
- case EXDEV:
- zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
- "use '-f' to override the following errors:\n"
- "'%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_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,
- dgettext(TEXT_DOMAIN, "cannot export '%s'"),
- zhp->zpool_name));
- }
- }
-
- return (0);
-}
-
-int
-zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
-{
- return (zpool_export_common(zhp, force, B_FALSE, log_str));
-}
-
-int
-zpool_export_force(zpool_handle_t *zhp, const char *log_str)
-{
- return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
-}
-
-static void
-zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
- nvlist_t *config)
-{
- nvlist_t *nv = NULL;
- uint64_t rewindto;
- int64_t loss = -1;
- struct tm t;
- char timestr[128];
-
- if (!hdl->libzfs_printerr || config == NULL)
- return;
-
- if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
- nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
- return;
- }
-
- if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
- return;
- (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
-
- if (localtime_r((time_t *)&rewindto, &t) != NULL &&
- ctime_r((time_t *)&rewindto, timestr) != NULL) {
- timestr[24] = 0;
- if (dryrun) {
- (void) printf(dgettext(TEXT_DOMAIN,
- "Would be able to return %s "
- "to its state as of %s.\n"),
- name, timestr);
- } else {
- (void) printf(dgettext(TEXT_DOMAIN,
- "Pool %s returned to its state as of %s.\n"),
- name, timestr);
- }
- if (loss > 120) {
- (void) printf(dgettext(TEXT_DOMAIN,
- "%s approximately %lld "),
- dryrun ? "Would discard" : "Discarded",
- ((longlong_t)loss + 30) / 60);
- (void) printf(dgettext(TEXT_DOMAIN,
- "minutes of transactions.\n"));
- } else if (loss > 0) {
- (void) printf(dgettext(TEXT_DOMAIN,
- "%s approximately %lld "),
- dryrun ? "Would discard" : "Discarded",
- (longlong_t)loss);
- (void) printf(dgettext(TEXT_DOMAIN,
- "seconds of transactions.\n"));
- }
- }
-}
-
-void
-zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
- nvlist_t *config, char *buf, size_t size)
-{
- nvlist_t *nv = NULL;
- int64_t loss = -1;
- uint64_t edata = UINT64_MAX;
- uint64_t rewindto;
- struct tm t;
- char timestr[128], temp[1024];
-
- if (!hdl->libzfs_printerr)
- return;
-
- /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
- if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
- nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
- nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
- goto no_info;
-
- (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
- (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
- &edata);
-
- (void) snprintf(buf, size, dgettext(TEXT_DOMAIN,
- "Recovery is possible, but will result in some data loss.\n"));
-
- if (localtime_r((time_t *)&rewindto, &t) != NULL &&
- ctime_r((time_t *)&rewindto, timestr) != NULL) {
- timestr[24] = 0;
- (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
- "\tReturning the pool to its state as of %s\n"
- "\tshould correct the problem. "), timestr);
- (void) strlcat(buf, temp, size);
- } else {
- (void) strlcat(buf, dgettext(TEXT_DOMAIN,
- "\tReverting the pool to an earlier state "
- "should correct the problem.\n\t"), size);
- }
-
- if (loss > 120) {
- (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
- "Approximately %lld minutes of data\n"
- "\tmust be discarded, irreversibly. "),
- ((longlong_t)loss + 30) / 60);
- (void) strlcat(buf, temp, size);
- } else if (loss > 0) {
- (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
- "Approximately %lld seconds of data\n"
- "\tmust be discarded, irreversibly. "),
- (longlong_t)loss);
- (void) strlcat(buf, temp, size);
- }
- if (edata != 0 && edata != UINT64_MAX) {
- if (edata == 1) {
- (void) strlcat(buf, dgettext(TEXT_DOMAIN,
- "After rewind, at least\n"
- "\tone persistent user-data error will remain. "),
- size);
- } else {
- (void) strlcat(buf, dgettext(TEXT_DOMAIN,
- "After rewind, several\n"
- "\tpersistent user-data errors will remain. "),
- size);
- }
- }
- (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
- "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
- reason >= 0 ? "clear" : "import", name);
- (void) strlcat(buf, temp, size);
-
- (void) strlcat(buf, dgettext(TEXT_DOMAIN,
- "A scrub of the pool\n"
- "\tis strongly recommended after recovery.\n"), size);
- return;
-
-no_info:
- (void) strlcat(buf, dgettext(TEXT_DOMAIN,
- "Destroy and re-create the pool from\n\ta backup source.\n"), size);
-}
-
-/*
- * zpool_import() is a contracted interface. Should be kept the same
- * if possible.
- *
- * Applications should use zpool_import_props() to import a pool with
- * new properties value to be set.
- */
-int
-zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
- char *altroot)
-{
- nvlist_t *props = NULL;
- int ret;
-
- if (altroot != NULL) {
- if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
- return (zfs_error_fmt(hdl, EZFS_NOMEM,
- dgettext(TEXT_DOMAIN, "cannot import '%s'"),
- newname));
- }
-
- if (nvlist_add_string(props,
- zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
- nvlist_add_string(props,
- zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
- nvlist_free(props);
- return (zfs_error_fmt(hdl, EZFS_NOMEM,
- dgettext(TEXT_DOMAIN, "cannot import '%s'"),
- newname));
- }
- }
-
- ret = zpool_import_props(hdl, config, newname, props,
- ZFS_IMPORT_NORMAL);
- nvlist_free(props);
- return (ret);
-}
-
-static void
-print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
- int indent)
-{
- nvlist_t **child;
- uint_t c, children;
- char *vname;
- uint64_t is_log = 0;
-
- (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
- &is_log);
-
- if (name != NULL)
- (void) printf("\t%*s%s%s\n", indent, "", name,
- is_log ? " [log]" : "");
-
- if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
- &child, &children) != 0)
- return;
-
- for (c = 0; c < children; c++) {
- vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID);
- print_vdev_tree(hdl, vname, child[c], indent + 2);
- free(vname);
- }
-}
-
-void
-zpool_collect_unsup_feat(nvlist_t *config, char *buf, size_t size)
-{
- nvlist_t *nvinfo, *unsup_feat;
- char temp[512];
-
- nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
- unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT);
-
- for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL);
- nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
- const char *desc = fnvpair_value_string(nvp);
- if (strlen(desc) > 0) {
- (void) snprintf(temp, 512, "\t%s (%s)\n",
- nvpair_name(nvp), desc);
- (void) strlcat(buf, temp, size);
- } else {
- (void) snprintf(temp, 512, "\t%s\n", nvpair_name(nvp));
- (void) strlcat(buf, temp, size);
- }
- }
-}
-
-/*
- * Import the given pool using the known configuration and a list of
- * properties to be set. The configuration should have come from
- * zpool_find_import(). The 'newname' parameters control whether the pool
- * is imported with a different name.
- */
-int
-zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
- nvlist_t *props, int flags)
-{
- zfs_cmd_t zc = {"\0"};
- zpool_load_policy_t policy;
- nvlist_t *nv = NULL;
- nvlist_t *nvinfo = NULL;
- nvlist_t *missing = NULL;
- const char *thename;
- const char *origname;
- int ret;
- int error = 0;
- char buf[2048];
- char errbuf[ERRBUFLEN];
-
- origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot import pool '%s'"), origname);
-
- if (newname != NULL) {
- if (!zpool_name_valid(hdl, B_FALSE, newname))
- return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
- dgettext(TEXT_DOMAIN, "cannot import '%s'"),
- newname));
- thename = newname;
- } else {
- thename = origname;
- }
-
- if (props != NULL) {
- uint64_t version;
- prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
-
- version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
-
- if ((props = zpool_valid_proplist(hdl, origname,
- props, version, flags, errbuf)) == NULL)
- return (-1);
- zcmd_write_src_nvlist(hdl, &zc, props);
- nvlist_free(props);
- }
-
- (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
-
- zc.zc_guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID);
-
- zcmd_write_conf_nvlist(hdl, &zc, config);
- zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2);
-
- zc.zc_cookie = flags;
- while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
- errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
- if (ret != 0)
- error = errno;
-
- (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
-
- zcmd_free_nvlists(&zc);
-
- zpool_get_load_policy(config, &policy);
-
- if (error) {
- char desc[1024];
- char aux[256];
-
- /*
- * Dry-run failed, but we print out what success
- * looks like if we found a best txg
- */
- if (policy.zlp_rewind & ZPOOL_TRY_REWIND) {
- zpool_rewind_exclaim(hdl, newname ? origname : thename,
- B_TRUE, nv);
- nvlist_free(nv);
- return (-1);
- }
-
- if (newname == NULL)
- (void) snprintf(desc, sizeof (desc),
- dgettext(TEXT_DOMAIN, "cannot import '%s'"),
- thename);
- else
- (void) snprintf(desc, sizeof (desc),
- dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
- origname, thename);
-
- switch (error) {
- case ENOTSUP:
- if (nv != NULL && nvlist_lookup_nvlist(nv,
- ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
- nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
- (void) printf(dgettext(TEXT_DOMAIN, "This "
- "pool uses the following feature(s) not "
- "supported by this system:\n"));
- memset(buf, 0, 2048);
- zpool_collect_unsup_feat(nv, buf, 2048);
- (void) printf("%s", buf);
- if (nvlist_exists(nvinfo,
- ZPOOL_CONFIG_CAN_RDONLY)) {
- (void) printf(dgettext(TEXT_DOMAIN,
- "All unsupported features are only "
- "required for writing to the pool."
- "\nThe pool can be imported using "
- "'-o readonly=on'.\n"));
- }
- }
- /*
- * Unsupported version.
- */
- (void) zfs_error(hdl, EZFS_BADVERSION, desc);
- break;
-
- case EREMOTEIO:
- if (nv != NULL && nvlist_lookup_nvlist(nv,
- ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0) {
- const char *hostname = "<unknown>";
- uint64_t hostid = 0;
- mmp_state_t mmp_state;
-
- mmp_state = fnvlist_lookup_uint64(nvinfo,
- ZPOOL_CONFIG_MMP_STATE);
-
- if (nvlist_exists(nvinfo,
- ZPOOL_CONFIG_MMP_HOSTNAME))
- hostname = fnvlist_lookup_string(nvinfo,
- ZPOOL_CONFIG_MMP_HOSTNAME);
-
- if (nvlist_exists(nvinfo,
- ZPOOL_CONFIG_MMP_HOSTID))
- hostid = fnvlist_lookup_uint64(nvinfo,
- ZPOOL_CONFIG_MMP_HOSTID);
-
- if (mmp_state == MMP_STATE_ACTIVE) {
- (void) snprintf(aux, sizeof (aux),
- dgettext(TEXT_DOMAIN, "pool is imp"
- "orted on host '%s' (hostid=%lx).\n"
- "Export the pool on the other "
- "system, then run 'zpool import'."),
- hostname, (unsigned long) hostid);
- } else if (mmp_state == MMP_STATE_NO_HOSTID) {
- (void) snprintf(aux, sizeof (aux),
- dgettext(TEXT_DOMAIN, "pool has "
- "the multihost property on and "
- "the\nsystem's hostid is not set. "
- "Set a unique system hostid with "
- "the zgenhostid(8) command.\n"));
- }
-
- (void) zfs_error_aux(hdl, "%s", aux);
- }
- (void) zfs_error(hdl, EZFS_ACTIVE_POOL, desc);
- break;
-
- case EINVAL:
- (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
- break;
-
- case EROFS:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices is read only"));
- (void) zfs_error(hdl, EZFS_BADDEV, desc);
- break;
-
- case ENXIO:
- if (nv && nvlist_lookup_nvlist(nv,
- ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
- nvlist_lookup_nvlist(nvinfo,
- ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
- (void) printf(dgettext(TEXT_DOMAIN,
- "The devices below are missing or "
- "corrupted, use '-m' to import the pool "
- "anyway:\n"));
- print_vdev_tree(hdl, NULL, missing, 2);
- (void) printf("\n");
- }
- (void) zpool_standard_error(hdl, error, desc);
- break;
-
- case EEXIST:
- (void) zpool_standard_error(hdl, error, desc);
- break;
-
- case EBUSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices are already in use\n"));
- (void) zfs_error(hdl, EZFS_BADDEV, desc);
- break;
- case ENAMETOOLONG:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "new name of at least one dataset is longer than "
- "the maximum allowable length"));
- (void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
- break;
- default:
- (void) zpool_standard_error(hdl, error, desc);
- memset(buf, 0, 2048);
- zpool_explain_recover(hdl,
- newname ? origname : thename, -error, nv,
- buf, 2048);
- (void) printf("\t%s", buf);
- break;
- }
-
- nvlist_free(nv);
- ret = -1;
- } else {
- zpool_handle_t *zhp;
-
- /*
- * This should never fail, but play it safe anyway.
- */
- if (zpool_open_silent(hdl, thename, &zhp) != 0)
- ret = -1;
- else if (zhp != NULL)
- zpool_close(zhp);
- if (policy.zlp_rewind &
- (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
- zpool_rewind_exclaim(hdl, newname ? origname : thename,
- ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv);
- }
- nvlist_free(nv);
- }
-
- return (ret);
-}
-
-/*
- * Translate vdev names to guids. If a vdev_path is determined to be
- * unsuitable then a vd_errlist is allocated and the vdev path and errno
- * are added to it.
- */
-static int
-zpool_translate_vdev_guids(zpool_handle_t *zhp, nvlist_t *vds,
- nvlist_t *vdev_guids, nvlist_t *guids_to_paths, nvlist_t **vd_errlist)
-{
- nvlist_t *errlist = NULL;
- int error = 0;
-
- for (nvpair_t *elem = nvlist_next_nvpair(vds, NULL); elem != NULL;
- elem = nvlist_next_nvpair(vds, elem)) {
- boolean_t spare, cache;
-
- const char *vd_path = nvpair_name(elem);
- nvlist_t *tgt = zpool_find_vdev(zhp, vd_path, &spare, &cache,
- NULL);
-
- if ((tgt == NULL) || cache || spare) {
- if (errlist == NULL) {
- errlist = fnvlist_alloc();
- error = EINVAL;
- }
-
- uint64_t err = (tgt == NULL) ? EZFS_NODEVICE :
- (spare ? EZFS_ISSPARE : EZFS_ISL2CACHE);
- fnvlist_add_int64(errlist, vd_path, err);
- continue;
- }
-
- uint64_t guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
- fnvlist_add_uint64(vdev_guids, vd_path, guid);
-
- char msg[MAXNAMELEN];
- (void) snprintf(msg, sizeof (msg), "%llu", (u_longlong_t)guid);
- fnvlist_add_string(guids_to_paths, msg, vd_path);
- }
-
- if (error != 0) {
- verify(errlist != NULL);
- if (vd_errlist != NULL)
- *vd_errlist = errlist;
- else
- fnvlist_free(errlist);
- }
-
- return (error);
-}
-
-static int
-xlate_init_err(int err)
-{
- switch (err) {
- case ENODEV:
- return (EZFS_NODEVICE);
- case EINVAL:
- case EROFS:
- return (EZFS_BADDEV);
- case EBUSY:
- return (EZFS_INITIALIZING);
- case ESRCH:
- return (EZFS_NO_INITIALIZE);
- }
- return (err);
-}
-
-int
-zpool_initialize_one(zpool_handle_t *zhp, void *data)
-{
- int error;
- libzfs_handle_t *hdl = zpool_get_handle(zhp);
- const char *pool_name = zpool_get_name(zhp);
- if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
- return (-1);
- initialize_cbdata_t *cb = data;
- nvlist_t *vdevs = fnvlist_alloc();
-
- nvlist_t *config = zpool_get_config(zhp, NULL);
- nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_VDEV_TREE);
- zpool_collect_leaves(zhp, nvroot, vdevs);
- if (cb->wait)
- error = zpool_initialize_wait(zhp, cb->cmd_type, vdevs);
- else
- error = zpool_initialize(zhp, cb->cmd_type, vdevs);
- fnvlist_free(vdevs);
-
- return (error);
-}
-
-/*
- * Begin, suspend, cancel, or uninit (clear) the initialization (initializing
- * of all free blocks) for the given vdevs in the given pool.
- */
-static int
-zpool_initialize_impl(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
- nvlist_t *vds, boolean_t wait)
-{
- int err;
-
- nvlist_t *vdev_guids = fnvlist_alloc();
- nvlist_t *guids_to_paths = fnvlist_alloc();
- nvlist_t *vd_errlist = NULL;
- nvlist_t *errlist;
- nvpair_t *elem;
-
- err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
- guids_to_paths, &vd_errlist);
-
- if (err != 0) {
- verify(vd_errlist != NULL);
- goto list_errors;
- }
-
- err = lzc_initialize(zhp->zpool_name, cmd_type,
- vdev_guids, &errlist);
-
- if (err != 0) {
- if (errlist != NULL && nvlist_lookup_nvlist(errlist,
- ZPOOL_INITIALIZE_VDEVS, &vd_errlist) == 0) {
- goto list_errors;
- }
-
- if (err == EINVAL && cmd_type == POOL_INITIALIZE_UNINIT) {
- zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
- "uninitialize is not supported by kernel"));
- }
-
- (void) zpool_standard_error(zhp->zpool_hdl, err,
- dgettext(TEXT_DOMAIN, "operation failed"));
- goto out;
- }
-
- if (wait) {
- for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
- elem = nvlist_next_nvpair(vdev_guids, elem)) {
-
- uint64_t guid = fnvpair_value_uint64(elem);
-
- err = lzc_wait_tag(zhp->zpool_name,
- ZPOOL_WAIT_INITIALIZE, guid, NULL);
- if (err != 0) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl,
- err, dgettext(TEXT_DOMAIN, "error "
- "waiting for '%s' to initialize"),
- nvpair_name(elem));
-
- goto out;
- }
- }
- }
- goto out;
-
-list_errors:
- for (elem = nvlist_next_nvpair(vd_errlist, NULL); elem != NULL;
- elem = nvlist_next_nvpair(vd_errlist, elem)) {
- int64_t vd_error = xlate_init_err(fnvpair_value_int64(elem));
- const char *path;
-
- if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
- &path) != 0)
- path = nvpair_name(elem);
-
- (void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
- "cannot initialize '%s'", path);
- }
-
-out:
- fnvlist_free(vdev_guids);
- fnvlist_free(guids_to_paths);
-
- if (vd_errlist != NULL)
- fnvlist_free(vd_errlist);
-
- return (err == 0 ? 0 : -1);
-}
-
-int
-zpool_initialize(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
- nvlist_t *vds)
-{
- return (zpool_initialize_impl(zhp, cmd_type, vds, B_FALSE));
-}
-
-int
-zpool_initialize_wait(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
- nvlist_t *vds)
-{
- return (zpool_initialize_impl(zhp, cmd_type, vds, B_TRUE));
-}
-
-static int
-xlate_trim_err(int err)
-{
- switch (err) {
- case ENODEV:
- return (EZFS_NODEVICE);
- case EINVAL:
- case EROFS:
- return (EZFS_BADDEV);
- case EBUSY:
- return (EZFS_TRIMMING);
- case ESRCH:
- return (EZFS_NO_TRIM);
- case EOPNOTSUPP:
- return (EZFS_TRIM_NOTSUP);
- }
- return (err);
-}
-
-void
-zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- uint_t children = 0;
- nvlist_t **child;
- uint_t i;
-
- (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
- &child, &children);
-
- if (children == 0) {
- char *path = zpool_vdev_name(hdl, zhp, nvroot,
- VDEV_NAME_PATH);
-
- if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 &&
- strcmp(path, VDEV_TYPE_HOLE) != 0)
- fnvlist_add_boolean(res, path);
-
- free(path);
- return;
- }
-
- for (i = 0; i < children; i++) {
- zpool_collect_leaves(zhp, child[i], res);
- }
-}
-
-int
-zpool_trim_one(zpool_handle_t *zhp, void *data)
-{
- int error;
- libzfs_handle_t *hdl = zpool_get_handle(zhp);
- const char *pool_name = zpool_get_name(zhp);
- if (zpool_open_silent(hdl, pool_name, &zhp) != 0)
- return (-1);
-
- trim_cbdata_t *cb = data;
- nvlist_t *vdevs = fnvlist_alloc();
-
- /* no individual leaf vdevs specified, so add them all */
- nvlist_t *config = zpool_get_config(zhp, NULL);
- nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_VDEV_TREE);
-
- zpool_collect_leaves(zhp, nvroot, vdevs);
- error = zpool_trim(zhp, cb->cmd_type, vdevs, &cb->trim_flags);
- fnvlist_free(vdevs);
-
- return (error);
-}
-
-static int
-zpool_trim_wait(zpool_handle_t *zhp, nvlist_t *vdev_guids)
-{
- int err;
- nvpair_t *elem;
-
- for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
- elem = nvlist_next_nvpair(vdev_guids, elem)) {
-
- uint64_t guid = fnvpair_value_uint64(elem);
-
- err = lzc_wait_tag(zhp->zpool_name,
- ZPOOL_WAIT_TRIM, guid, NULL);
- if (err != 0) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl,
- err, dgettext(TEXT_DOMAIN, "error "
- "waiting to trim '%s'"), nvpair_name(elem));
-
- return (err);
- }
- }
- return (0);
-}
-
-/*
- * Check errlist and report any errors, omitting ones which should be
- * suppressed. Returns B_TRUE if any errors were reported.
- */
-static boolean_t
-check_trim_errs(zpool_handle_t *zhp, trimflags_t *trim_flags,
- nvlist_t *guids_to_paths, nvlist_t *vds, nvlist_t *errlist)
-{
- nvpair_t *elem;
- boolean_t reported_errs = B_FALSE;
- int num_vds = 0;
- int num_suppressed_errs = 0;
-
- for (elem = nvlist_next_nvpair(vds, NULL);
- elem != NULL; elem = nvlist_next_nvpair(vds, elem)) {
- num_vds++;
- }
-
- for (elem = nvlist_next_nvpair(errlist, NULL);
- elem != NULL; elem = nvlist_next_nvpair(errlist, elem)) {
- int64_t vd_error = xlate_trim_err(fnvpair_value_int64(elem));
- const char *path;
-
- /*
- * If only the pool was specified, and it was not a secure
- * trim then suppress warnings for individual vdevs which
- * do not support trimming.
- */
- if (vd_error == EZFS_TRIM_NOTSUP &&
- trim_flags->fullpool &&
- !trim_flags->secure) {
- num_suppressed_errs++;
- continue;
- }
-
- reported_errs = B_TRUE;
- if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
- &path) != 0)
- path = nvpair_name(elem);
-
- (void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
- "cannot trim '%s'", path);
- }
-
- if (num_suppressed_errs == num_vds) {
- (void) zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
- "no devices in pool support trim operations"));
- (void) (zfs_error(zhp->zpool_hdl, EZFS_TRIM_NOTSUP,
- dgettext(TEXT_DOMAIN, "cannot trim")));
- reported_errs = B_TRUE;
- }
-
- return (reported_errs);
-}
-
-/*
- * Begin, suspend, or cancel the TRIM (discarding of all free blocks) for
- * the given vdevs in the given pool.
- */
-int
-zpool_trim(zpool_handle_t *zhp, pool_trim_func_t cmd_type, nvlist_t *vds,
- trimflags_t *trim_flags)
-{
- int err;
- int retval = 0;
-
- nvlist_t *vdev_guids = fnvlist_alloc();
- nvlist_t *guids_to_paths = fnvlist_alloc();
- nvlist_t *errlist = NULL;
-
- err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
- guids_to_paths, &errlist);
- if (err != 0) {
- check_trim_errs(zhp, trim_flags, guids_to_paths, vds, errlist);
- retval = -1;
- goto out;
- }
-
- err = lzc_trim(zhp->zpool_name, cmd_type, trim_flags->rate,
- trim_flags->secure, vdev_guids, &errlist);
- if (err != 0) {
- nvlist_t *vd_errlist;
- if (errlist != NULL && nvlist_lookup_nvlist(errlist,
- ZPOOL_TRIM_VDEVS, &vd_errlist) == 0) {
- if (check_trim_errs(zhp, trim_flags, guids_to_paths,
- vds, vd_errlist)) {
- retval = -1;
- goto out;
- }
- } else {
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "operation failed"));
- zpool_standard_error(zhp->zpool_hdl, err, errbuf);
- retval = -1;
- goto out;
- }
- }
-
-
- if (trim_flags->wait)
- retval = zpool_trim_wait(zhp, vdev_guids);
-
-out:
- if (errlist != NULL)
- fnvlist_free(errlist);
- fnvlist_free(vdev_guids);
- fnvlist_free(guids_to_paths);
- return (retval);
-}
-
-/*
- * Scan the pool.
- */
-int
-zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd) {
- return (zpool_scan_range(zhp, func, cmd, 0, 0));
-}
-
-int
-zpool_scan_range(zpool_handle_t *zhp, pool_scan_func_t func,
- pool_scrub_cmd_t cmd, time_t date_start, time_t date_end)
-{
- char errbuf[ERRBUFLEN];
- int err;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- nvlist_t *args = fnvlist_alloc();
- fnvlist_add_uint64(args, "scan_type", (uint64_t)func);
- fnvlist_add_uint64(args, "scan_command", (uint64_t)cmd);
- fnvlist_add_uint64(args, "scan_date_start", (uint64_t)date_start);
- fnvlist_add_uint64(args, "scan_date_end", (uint64_t)date_end);
-
- err = lzc_scrub(ZFS_IOC_POOL_SCRUB, zhp->zpool_name, args, NULL);
- fnvlist_free(args);
-
- if (err == 0) {
- return (0);
- } else if (err == ZFS_ERR_IOC_CMD_UNAVAIL) {
- zfs_cmd_t zc = {"\0"};
- (void) strlcpy(zc.zc_name, zhp->zpool_name,
- sizeof (zc.zc_name));
- zc.zc_cookie = func;
- zc.zc_flags = cmd;
-
- if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0)
- return (0);
- }
-
- /*
- * An ECANCELED on a scrub means one of the following:
- * 1. we resumed a paused scrub.
- * 2. we resumed a paused error scrub.
- * 3. Error scrub is not run because of no error log.
- *
- * Note that we no longer return ECANCELED in case 1 or 2. However, in
- * order to prevent problems where we have a newer userland than
- * kernel, we keep this check in place. That prevents erroneous
- * failures when an older kernel returns ECANCELED in those cases.
- */
- if (err == ECANCELED && (func == POOL_SCAN_SCRUB ||
- func == POOL_SCAN_ERRORSCRUB) && cmd == POOL_SCRUB_NORMAL)
- return (0);
- /*
- * The following cases have been handled here:
- * 1. Paused a scrub/error scrub if there is none in progress.
- */
- if (err == ENOENT && func != POOL_SCAN_NONE && cmd ==
- POOL_SCRUB_PAUSE) {
- return (0);
- }
-
- ASSERT3U(func, >=, POOL_SCAN_NONE);
- ASSERT3U(func, <, POOL_SCAN_FUNCS);
-
- if (func == POOL_SCAN_SCRUB || func == POOL_SCAN_ERRORSCRUB) {
- if (cmd == POOL_SCRUB_PAUSE) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot pause scrubbing %s"),
- zhp->zpool_name);
- } else {
- assert(cmd == POOL_SCRUB_NORMAL);
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot scrub %s"),
- zhp->zpool_name);
- }
- } else if (func == POOL_SCAN_RESILVER) {
- assert(cmd == POOL_SCRUB_NORMAL);
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot restart resilver on %s"), zhp->zpool_name);
- } else if (func == POOL_SCAN_NONE) {
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot cancel scrubbing %s"), zhp->zpool_name);
- } else {
- assert(!"unexpected result");
- }
-
- /*
- * With EBUSY, six cases are possible:
- *
- * Current state Requested
- * 1. Normal Scrub Running Normal Scrub or Error Scrub
- * 2. Normal Scrub Paused Error Scrub
- * 3. Normal Scrub Paused Pause Normal Scrub
- * 4. Error Scrub Running Normal Scrub or Error Scrub
- * 5. Error Scrub Paused Pause Error Scrub
- * 6. Resilvering Anything else
- */
- if (err == EBUSY) {
- nvlist_t *nvroot;
- pool_scan_stat_t *ps = NULL;
- uint_t psc;
-
- nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE);
- (void) nvlist_lookup_uint64_array(nvroot,
- ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
- if (ps && ps->pss_func == POOL_SCAN_SCRUB &&
- ps->pss_state == DSS_SCANNING) {
- if (ps->pss_pass_scrub_pause == 0) {
- /* handles case 1 */
- assert(cmd == POOL_SCRUB_NORMAL);
- return (zfs_error(hdl, EZFS_SCRUBBING,
- errbuf));
- } else {
- if (func == POOL_SCAN_ERRORSCRUB) {
- /* handles case 2 */
- ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL);
- return (zfs_error(hdl,
- EZFS_SCRUB_PAUSED_TO_CANCEL,
- errbuf));
- } else {
- /* handles case 3 */
- ASSERT3U(func, ==, POOL_SCAN_SCRUB);
- ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE);
- return (zfs_error(hdl,
- EZFS_SCRUB_PAUSED, errbuf));
- }
- }
- } else if (ps &&
- ps->pss_error_scrub_func == POOL_SCAN_ERRORSCRUB &&
- ps->pss_error_scrub_state == DSS_ERRORSCRUBBING) {
- if (ps->pss_pass_error_scrub_pause == 0) {
- /* handles case 4 */
- ASSERT3U(cmd, ==, POOL_SCRUB_NORMAL);
- return (zfs_error(hdl, EZFS_ERRORSCRUBBING,
- errbuf));
- } else {
- /* handles case 5 */
- ASSERT3U(func, ==, POOL_SCAN_ERRORSCRUB);
- ASSERT3U(cmd, ==, POOL_SCRUB_PAUSE);
- return (zfs_error(hdl, EZFS_ERRORSCRUB_PAUSED,
- errbuf));
- }
- } else {
- /* handles case 6 */
- return (zfs_error(hdl, EZFS_RESILVERING, errbuf));
- }
- } else if (err == ENOENT) {
- return (zfs_error(hdl, EZFS_NO_SCRUB, errbuf));
- } else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) {
- return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, errbuf));
- } else {
- return (zpool_standard_error(hdl, err, errbuf));
- }
-}
-
-/*
- * Find a vdev that matches the search criteria specified. We use the
- * the nvpair name to determine how we should look for the device.
- * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
- * spare; but FALSE if its an INUSE spare.
- *
- * If 'return_parent' is set, then return the *parent* of the vdev you're
- * searching for rather than the vdev itself.
- */
-static nvlist_t *
-vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
- boolean_t *l2cache, boolean_t *log, boolean_t return_parent)
-{
- uint_t c, children;
- nvlist_t **child;
- nvlist_t *ret;
- uint64_t is_log;
- const char *srchkey;
- nvpair_t *pair = nvlist_next_nvpair(search, NULL);
- const char *tmp = NULL;
- boolean_t is_root;
-
- /* Nothing to look for */
- if (search == NULL || pair == NULL)
- return (NULL);
-
- /* Obtain the key we will use to search */
- srchkey = nvpair_name(pair);
-
- nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &tmp);
- if (strcmp(tmp, "root") == 0)
- is_root = B_TRUE;
- else
- is_root = B_FALSE;
-
- switch (nvpair_type(pair)) {
- case DATA_TYPE_UINT64:
- if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
- uint64_t srchval = fnvpair_value_uint64(pair);
- uint64_t theguid = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_GUID);
- if (theguid == srchval)
- return (nv);
- }
- break;
-
- case DATA_TYPE_STRING: {
- const char *srchval, *val;
-
- srchval = fnvpair_value_string(pair);
- if (nvlist_lookup_string(nv, srchkey, &val) != 0)
- break;
-
- /*
- * Search for the requested value. Special cases:
- *
- * - ZPOOL_CONFIG_PATH for whole disk entries. These end in
- * "-part1", or "p1". The suffix is hidden from the user,
- * but included in the string, so this matches around it.
- * - ZPOOL_CONFIG_PATH for short names zfs_strcmp_shortname()
- * is used to check all possible expanded paths.
- * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
- *
- * Otherwise, all other searches are simple string compares.
- */
- if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0) {
- uint64_t wholedisk = 0;
-
- (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
- &wholedisk);
- if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0)
- return (nv);
-
- } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0) {
- char *type, *idx, *end, *p;
- uint64_t id, vdev_id;
-
- /*
- * Determine our vdev type, keeping in mind
- * that the srchval is composed of a type and
- * vdev id pair (i.e. mirror-4).
- */
- if ((type = strdup(srchval)) == NULL)
- return (NULL);
-
- if ((p = strrchr(type, '-')) == NULL) {
- free(type);
- break;
- }
- idx = p + 1;
- *p = '\0';
-
- /*
- * draid names are presented like: draid2:4d:6c:0s
- * We match them up to the first ':' so we can still
- * do the parity check below, but the other params
- * are ignored.
- */
- if ((p = strchr(type, ':')) != NULL) {
- if (strncmp(type, VDEV_TYPE_DRAID,
- strlen(VDEV_TYPE_DRAID)) == 0)
- *p = '\0';
- }
-
- /*
- * If the types don't match then keep looking.
- */
- if (strncmp(val, type, strlen(val)) != 0) {
- free(type);
- break;
- }
-
- verify(zpool_vdev_is_interior(type));
-
- id = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID);
- errno = 0;
- vdev_id = strtoull(idx, &end, 10);
-
- /*
- * If we are looking for a raidz and a parity is
- * specified, make sure it matches.
- */
- int rzlen = strlen(VDEV_TYPE_RAIDZ);
- assert(rzlen == strlen(VDEV_TYPE_DRAID));
- int typlen = strlen(type);
- if ((strncmp(type, VDEV_TYPE_RAIDZ, rzlen) == 0 ||
- strncmp(type, VDEV_TYPE_DRAID, rzlen) == 0) &&
- typlen != rzlen) {
- uint64_t vdev_parity;
- int parity = *(type + rzlen) - '0';
-
- if (parity <= 0 || parity > 3 ||
- (typlen - rzlen) != 1) {
- /*
- * Nonsense parity specified, can
- * never match
- */
- free(type);
- return (NULL);
- }
- vdev_parity = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_NPARITY);
- if ((int)vdev_parity != parity) {
- free(type);
- break;
- }
- }
-
- free(type);
- if (errno != 0)
- return (NULL);
-
- /*
- * Now verify that we have the correct vdev id.
- */
- if (vdev_id == id)
- return (nv);
- }
-
- /*
- * Common case
- */
- if (strcmp(srchval, val) == 0)
- return (nv);
- break;
- }
-
- default:
- break;
- }
-
- if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
- &child, &children) != 0)
- return (NULL);
-
- for (c = 0; c < children; c++) {
- if ((ret = vdev_to_nvlist_iter(child[c], search,
- avail_spare, l2cache, NULL, return_parent)) != NULL) {
- /*
- * The 'is_log' value is only set for the toplevel
- * vdev, not the leaf vdevs. So we always lookup the
- * log device from the root of the vdev tree (where
- * 'log' is non-NULL).
- */
- if (log != NULL &&
- nvlist_lookup_uint64(child[c],
- ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
- is_log) {
- *log = B_TRUE;
- }
- return (ret && return_parent && !is_root ? nv : ret);
- }
- }
-
- if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
- &child, &children) == 0) {
- for (c = 0; c < children; c++) {
- if ((ret = vdev_to_nvlist_iter(child[c], search,
- avail_spare, l2cache, NULL, return_parent))
- != NULL) {
- *avail_spare = B_TRUE;
- return (ret && return_parent &&
- !is_root ? nv : ret);
- }
- }
- }
-
- if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
- &child, &children) == 0) {
- for (c = 0; c < children; c++) {
- if ((ret = vdev_to_nvlist_iter(child[c], search,
- avail_spare, l2cache, NULL, return_parent))
- != NULL) {
- *l2cache = B_TRUE;
- return (ret && return_parent &&
- !is_root ? nv : ret);
- }
- }
- }
-
- return (NULL);
-}
-
-/*
- * Given a physical path or guid, find the associated vdev.
- */
-nvlist_t *
-zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
- boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
-{
- nvlist_t *search, *nvroot, *ret;
- uint64_t guid;
- char *end;
-
- search = fnvlist_alloc();
-
- guid = strtoull(ppath, &end, 0);
- if (guid != 0 && *end == '\0') {
- fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
- } else {
- fnvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath);
- }
-
- nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE);
-
- *avail_spare = B_FALSE;
- *l2cache = B_FALSE;
- if (log != NULL)
- *log = B_FALSE;
- ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log,
- B_FALSE);
- fnvlist_free(search);
-
- return (ret);
-}
-
-/*
- * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
- */
-static boolean_t
-zpool_vdev_is_interior(const char *name)
-{
- if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
- strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 ||
- strncmp(name,
- VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 ||
- strncmp(name, VDEV_TYPE_ROOT, strlen(VDEV_TYPE_ROOT)) == 0 ||
- strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
- return (B_TRUE);
-
- if (strncmp(name, VDEV_TYPE_DRAID, strlen(VDEV_TYPE_DRAID)) == 0 &&
- !zpool_is_draid_spare(name))
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-/*
- * Lookup the nvlist for a given vdev or vdev's parent (depending on
- * if 'return_parent' is set).
- */
-static nvlist_t *
-__zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
- boolean_t *l2cache, boolean_t *log, boolean_t return_parent)
-{
- char *end;
- nvlist_t *nvroot, *search, *ret;
- uint64_t guid;
- boolean_t __avail_spare, __l2cache, __log;
-
- search = fnvlist_alloc();
-
- guid = strtoull(path, &end, 0);
- if (guid != 0 && *end == '\0') {
- fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
- } else if (zpool_vdev_is_interior(path)) {
- fnvlist_add_string(search, ZPOOL_CONFIG_TYPE, path);
- } else {
- fnvlist_add_string(search, ZPOOL_CONFIG_PATH, path);
- }
-
- nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE);
-
- /*
- * User can pass NULL for avail_spare, l2cache, and log, but
- * we still need to provide variables to vdev_to_nvlist_iter(), so
- * just point them to junk variables here.
- */
- if (!avail_spare)
- avail_spare = &__avail_spare;
- if (!l2cache)
- l2cache = &__l2cache;
- if (!log)
- log = &__log;
-
- *avail_spare = B_FALSE;
- *l2cache = B_FALSE;
- if (log != NULL)
- *log = B_FALSE;
- ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log,
- return_parent);
- fnvlist_free(search);
-
- return (ret);
-}
-
-nvlist_t *
-zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
- boolean_t *l2cache, boolean_t *log)
-{
- return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log,
- B_FALSE));
-}
-
-/* Given a vdev path, return its parent's nvlist */
-nvlist_t *
-zpool_find_parent_vdev(zpool_handle_t *zhp, const char *path,
- boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
-{
- return (__zpool_find_vdev(zhp, path, avail_spare, l2cache, log,
- B_TRUE));
-}
-
-/*
- * Convert a vdev path to a GUID. Returns GUID or 0 on error.
- *
- * If is_spare, is_l2cache, or is_log is non-NULL, then store within it
- * if the VDEV is a spare, l2cache, or log device. If they're NULL then
- * ignore them.
- */
-static uint64_t
-zpool_vdev_path_to_guid_impl(zpool_handle_t *zhp, const char *path,
- boolean_t *is_spare, boolean_t *is_l2cache, boolean_t *is_log)
-{
- boolean_t spare = B_FALSE, l2cache = B_FALSE, log = B_FALSE;
- nvlist_t *tgt;
-
- if ((tgt = zpool_find_vdev(zhp, path, &spare, &l2cache,
- &log)) == NULL)
- return (0);
-
- if (is_spare != NULL)
- *is_spare = spare;
- if (is_l2cache != NULL)
- *is_l2cache = l2cache;
- if (is_log != NULL)
- *is_log = log;
-
- return (fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID));
-}
-
-/* Convert a vdev path to a GUID. Returns GUID or 0 on error. */
-uint64_t
-zpool_vdev_path_to_guid(zpool_handle_t *zhp, const char *path)
-{
- return (zpool_vdev_path_to_guid_impl(zhp, path, NULL, NULL, NULL));
-}
-
-/*
- * Bring the specified vdev online. The 'flags' parameter is a set of the
- * ZFS_ONLINE_* flags.
- */
-int
-zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
- vdev_state_t *newstate)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache, islog;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- if (flags & ZFS_ONLINE_EXPAND) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
- } else {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot online %s"), path);
- }
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- &islog)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
-
- if (!(flags & ZFS_ONLINE_SPARE) && avail_spare)
- return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
-
-#ifndef __FreeBSD__
- const char *pathname;
- if ((flags & ZFS_ONLINE_EXPAND ||
- zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) &&
- nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &pathname) == 0) {
- uint64_t wholedisk = 0;
-
- (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
- &wholedisk);
-
- /*
- * XXX - L2ARC 1.0 devices can't support expansion.
- */
- if (l2cache) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot expand cache devices"));
- return (zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf));
- }
-
- if (wholedisk) {
- const char *fullpath = path;
- char buf[MAXPATHLEN];
- int error;
-
- if (path[0] != '/') {
- error = zfs_resolve_shortname(path, buf,
- sizeof (buf));
- if (error != 0)
- return (zfs_error(hdl, EZFS_NODEVICE,
- errbuf));
-
- fullpath = buf;
- }
-
- error = zpool_relabel_disk(hdl, fullpath, errbuf);
- if (error != 0)
- return (error);
- }
- }
-#endif
-
- zc.zc_cookie = VDEV_STATE_ONLINE;
- zc.zc_obj = flags;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
- if (errno == EINVAL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
- "from this pool into a new one. Use '%s' "
- "instead"), "zpool detach");
- return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, errbuf));
- }
- return (zpool_standard_error(hdl, errno, errbuf));
- }
-
- *newstate = zc.zc_cookie;
- return (0);
-}
-
-/*
- * Take the specified vdev offline
- */
-int
-zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- NULL)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
-
- if (avail_spare)
- return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
-
- zc.zc_cookie = VDEV_STATE_OFFLINE;
- zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
- return (0);
-
- switch (errno) {
- case EBUSY:
-
- /*
- * There are no other replicas of this device.
- */
- return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf));
-
- case EEXIST:
- /*
- * The log device has unplayed logs
- */
- return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, errbuf));
-
- default:
- return (zpool_standard_error(hdl, errno, errbuf));
- }
-}
-
-/*
- * Remove the specified vdev asynchronously from the configuration, so
- * that it may come ONLINE if reinserted. This is called from zed on
- * Udev remove event.
- * Note: We also have a similar function zpool_vdev_remove() that
- * removes the vdev from the pool.
- */
-int
-zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- NULL)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
-
- zc.zc_cookie = VDEV_STATE_REMOVED;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
- return (0);
-
- return (zpool_standard_error(hdl, errno, errbuf));
-}
-
-/*
- * Mark the given vdev faulted.
- */
-int
-zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot fault %llu"), (u_longlong_t)guid);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_guid = guid;
- zc.zc_cookie = VDEV_STATE_FAULTED;
- zc.zc_obj = aux;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
- return (0);
-
- switch (errno) {
- case EBUSY:
-
- /*
- * There are no other replicas of this device.
- */
- return (zfs_error(hdl, EZFS_NOREPLICAS, errbuf));
-
- default:
- return (zpool_standard_error(hdl, errno, errbuf));
- }
-
-}
-
-/*
- * Generic set vdev state function
- */
-static int
-zpool_vdev_set_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux,
- vdev_state_t state)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set %s %llu"),
- zpool_state_to_name(state, aux), (u_longlong_t)guid);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_guid = guid;
- zc.zc_cookie = state;
- zc.zc_obj = aux;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
- return (0);
-
- return (zpool_standard_error(hdl, errno, errbuf));
-}
-
-/*
- * Mark the given vdev degraded.
- */
-int
-zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
-{
- return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_DEGRADED));
-}
-
-/*
- * Mark the given vdev as in a removed state (as if the device does not exist).
- *
- * This is different than zpool_vdev_remove() which does a removal of a device
- * from the pool (but the device does exist).
- */
-int
-zpool_vdev_set_removed_state(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
-{
- return (zpool_vdev_set_state(zhp, guid, aux, VDEV_STATE_REMOVED));
-}
-
-/*
- * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
- * a hot spare.
- */
-static boolean_t
-is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
-{
- nvlist_t **child;
- uint_t c, children;
-
- if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
- &children) == 0) {
- const char *type = fnvlist_lookup_string(search,
- ZPOOL_CONFIG_TYPE);
- if ((strcmp(type, VDEV_TYPE_SPARE) == 0 ||
- strcmp(type, VDEV_TYPE_DRAID_SPARE) == 0) &&
- children == 2 && child[which] == tgt)
- return (B_TRUE);
-
- for (c = 0; c < children; c++)
- if (is_replacing_spare(child[c], tgt, which))
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-/*
- * Attach new_disk (fully described by nvroot) to old_disk.
- * If 'replacing' is specified, the new disk will replace the old one.
- */
-int
-zpool_vdev_attach(zpool_handle_t *zhp, const char *old_disk,
- const char *new_disk, nvlist_t *nvroot, int replacing, boolean_t rebuild)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- int ret;
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache, islog;
- uint64_t val;
- char *newname;
- const char *type;
- nvlist_t **child;
- uint_t children;
- nvlist_t *config_root;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- if (replacing)
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot replace %s with %s"), old_disk, new_disk);
- else
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot attach %s to %s"), new_disk, old_disk);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
- &islog)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- if (avail_spare)
- return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
-
- if (l2cache)
- return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
- zc.zc_cookie = replacing;
- zc.zc_simple = rebuild;
-
- if (rebuild &&
- zfeature_lookup_guid("org.openzfs:device_rebuild", NULL) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "the loaded zfs module doesn't support device rebuilds"));
- return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
- }
-
- type = fnvlist_lookup_string(tgt, ZPOOL_CONFIG_TYPE);
- if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 &&
- zfeature_lookup_guid("org.openzfs:raidz_expansion", NULL) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "the loaded zfs module doesn't support raidz expansion"));
- return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
- }
-
- if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
- &child, &children) != 0 || children != 1) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "new device must be a single disk"));
- return (zfs_error(hdl, EZFS_INVALCONFIG, errbuf));
- }
-
- config_root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
- ZPOOL_CONFIG_VDEV_TREE);
-
- if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL)
- return (-1);
-
- /*
- * If the target is a hot spare that has been swapped in, we can only
- * replace it with another hot spare.
- */
- if (replacing &&
- nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
- (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
- NULL) == NULL || !avail_spare) &&
- is_replacing_spare(config_root, tgt, 1)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "can only be replaced by another hot spare"));
- free(newname);
- return (zfs_error(hdl, EZFS_BADTARGET, errbuf));
- }
-
- free(newname);
-
- zcmd_write_conf_nvlist(hdl, &zc, nvroot);
-
- ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
-
- zcmd_free_nvlists(&zc);
-
- if (ret == 0)
- return (0);
-
- switch (errno) {
- case ENOTSUP:
- /*
- * Can't attach to or replace this type of vdev.
- */
- if (replacing) {
- uint64_t version = zpool_get_prop_int(zhp,
- ZPOOL_PROP_VERSION, NULL);
-
- if (islog) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot replace a log with a spare"));
- } else if (rebuild) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "only mirror and dRAID vdevs support "
- "sequential reconstruction"));
- } else if (zpool_is_draid_spare(new_disk)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dRAID spares can only replace child "
- "devices in their parent's dRAID vdev"));
- } else if (version >= SPA_VERSION_MULTI_REPLACE) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "already in replacing/spare config; wait "
- "for completion or use 'zpool detach'"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot replace a replacing device"));
- }
- } else if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "raidz_expansion feature must be enabled "
- "in order to attach a device to raidz"));
- } else {
- char status[64] = {0};
- zpool_prop_get_feature(zhp,
- "feature@device_rebuild", status, 63);
- if (rebuild &&
- strncmp(status, ZFS_FEATURE_DISABLED, 64) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "device_rebuild feature must be enabled "
- "in order to use sequential "
- "reconstruction"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "can only attach to mirrors and top-level "
- "disks"));
- }
- }
- (void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
- break;
-
- case EINVAL:
- /*
- * The new device must be a single disk.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "new device must be a single disk"));
- (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
- break;
-
- case EBUSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
- new_disk);
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case EOVERFLOW:
- /*
- * The new device is too small.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "device is too small"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case EDOM:
- /*
- * The new device has a different optimal sector size.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "new device has a different optimal sector size; use the "
- "option '-o ashift=N' to override the optimal size"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
-
- case ENAMETOOLONG:
- /*
- * The resulting top-level vdev spec won't fit in the label.
- */
- (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf);
- break;
-
- case ENXIO:
- /*
- * The existing raidz vdev has offline children
- */
- if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "raidz vdev has devices that are are offline or "
- "being replaced"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- break;
- } else {
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
- break;
-
- case EADDRINUSE:
- /*
- * The boot reserved area is already being used (FreeBSD)
- */
- if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "the reserved boot area needed for the expansion "
- "is already being used by a boot loader"));
- (void) zfs_error(hdl, EZFS_BADDEV, errbuf);
- } else {
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
- break;
-
- case ZFS_ERR_ASHIFT_MISMATCH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "The new device cannot have a higher alignment requirement "
- "than the top-level vdev."));
- (void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
- break;
- default:
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
-
- return (-1);
-}
-
-/*
- * Detach the specified device.
- */
-int
-zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- NULL)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- if (avail_spare)
- return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
-
- if (l2cache)
- return (zfs_error(hdl, EZFS_ISL2CACHE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
- return (0);
-
- switch (errno) {
-
- case ENOTSUP:
- /*
- * Can't detach from this type of vdev.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
- "applicable to mirror and replacing vdevs"));
- (void) zfs_error(hdl, EZFS_BADTARGET, errbuf);
- break;
-
- case EBUSY:
- /*
- * There are no other replicas of this device.
- */
- (void) zfs_error(hdl, EZFS_NOREPLICAS, errbuf);
- break;
-
- default:
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
-
- return (-1);
-}
-
-/*
- * Find a mirror vdev in the source nvlist.
- *
- * The mchild array contains a list of disks in one of the top-level mirrors
- * of the source pool. The schild array contains a list of disks that the
- * user specified on the command line. We loop over the mchild array to
- * see if any entry in the schild array matches.
- *
- * If a disk in the mchild array is found in the schild array, we return
- * the index of that entry. Otherwise we return -1.
- */
-static int
-find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
- nvlist_t **schild, uint_t schildren)
-{
- uint_t mc;
-
- for (mc = 0; mc < mchildren; mc++) {
- uint_t sc;
- char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
- mchild[mc], 0);
-
- for (sc = 0; sc < schildren; sc++) {
- char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
- schild[sc], 0);
- boolean_t result = (strcmp(mpath, spath) == 0);
-
- free(spath);
- if (result) {
- free(mpath);
- return (mc);
- }
- }
-
- free(mpath);
- }
-
- return (-1);
-}
-
-/*
- * Split a mirror pool. If newroot points to null, then a new nvlist
- * is generated and it is the responsibility of the caller to free it.
- */
-int
-zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
- nvlist_t *props, splitflags_t flags)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- const char *bias;
- nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
- nvlist_t **varray = NULL, *zc_props = NULL;
- uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- uint64_t vers, readonly = B_FALSE;
- boolean_t freelist = B_FALSE, memory_err = B_TRUE;
- int retval = 0;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
-
- if (!zpool_name_valid(hdl, B_FALSE, newname))
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
-
- if ((config = zpool_get_config(zhp, NULL)) == NULL) {
- (void) fprintf(stderr, gettext("Internal error: unable to "
- "retrieve pool configuration\n"));
- return (-1);
- }
-
- tree = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
- vers = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
-
- if (props) {
- prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
- if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
- props, vers, flags, errbuf)) == NULL)
- return (-1);
- (void) nvlist_lookup_uint64(zc_props,
- zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly);
- if (readonly) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property %s can only be set at import time"),
- zpool_prop_to_name(ZPOOL_PROP_READONLY));
- return (-1);
- }
- }
-
- if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
- &children) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Source pool is missing vdev tree"));
- nvlist_free(zc_props);
- return (-1);
- }
-
- varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
- vcount = 0;
-
- if (*newroot == NULL ||
- nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
- &newchild, &newchildren) != 0)
- newchildren = 0;
-
- for (c = 0; c < children; c++) {
- uint64_t is_log = B_FALSE, is_hole = B_FALSE;
- boolean_t is_special = B_FALSE, is_dedup = B_FALSE;
- const char *type;
- nvlist_t **mchild, *vdev;
- uint_t mchildren;
- int entry;
-
- /*
- * Unlike cache & spares, slogs are stored in the
- * ZPOOL_CONFIG_CHILDREN array. We filter them out here.
- */
- (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
- &is_log);
- (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
- &is_hole);
- if (is_log || is_hole) {
- /*
- * Create a hole vdev and put it in the config.
- */
- if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
- goto out;
- if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
- VDEV_TYPE_HOLE) != 0)
- goto out;
- if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
- 1) != 0)
- goto out;
- if (lastlog == 0)
- lastlog = vcount;
- varray[vcount++] = vdev;
- continue;
- }
- lastlog = 0;
- type = fnvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE);
-
- if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) {
- vdev = child[c];
- if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
- goto out;
- continue;
- } else if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Source pool must be composed only of mirrors\n"));
- retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
- goto out;
- }
-
- if (nvlist_lookup_string(child[c],
- ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0) {
- if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0)
- is_special = B_TRUE;
- else if (strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0)
- is_dedup = B_TRUE;
- }
- verify(nvlist_lookup_nvlist_array(child[c],
- ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
-
- /* find or add an entry for this top-level vdev */
- if (newchildren > 0 &&
- (entry = find_vdev_entry(zhp, mchild, mchildren,
- newchild, newchildren)) >= 0) {
- /* We found a disk that the user specified. */
- vdev = mchild[entry];
- ++found;
- } else {
- /* User didn't specify a disk for this vdev. */
- vdev = mchild[mchildren - 1];
- }
-
- if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
- goto out;
-
- if (flags.dryrun != 0) {
- if (is_dedup == B_TRUE) {
- if (nvlist_add_string(varray[vcount - 1],
- ZPOOL_CONFIG_ALLOCATION_BIAS,
- VDEV_ALLOC_BIAS_DEDUP) != 0)
- goto out;
- } else if (is_special == B_TRUE) {
- if (nvlist_add_string(varray[vcount - 1],
- ZPOOL_CONFIG_ALLOCATION_BIAS,
- VDEV_ALLOC_BIAS_SPECIAL) != 0)
- goto out;
- }
- }
- }
-
- /* did we find every disk the user specified? */
- if (found != newchildren) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
- "include at most one disk from each mirror"));
- retval = zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
- goto out;
- }
-
- /* Prepare the nvlist for populating. */
- if (*newroot == NULL) {
- if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
- goto out;
- freelist = B_TRUE;
- if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
- VDEV_TYPE_ROOT) != 0)
- goto out;
- } else {
- verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
- }
-
- /* Add all the children we found */
- if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
- (const nvlist_t **)varray, lastlog == 0 ? vcount : lastlog) != 0)
- goto out;
-
- /*
- * If we're just doing a dry run, exit now with success.
- */
- if (flags.dryrun) {
- memory_err = B_FALSE;
- freelist = B_FALSE;
- goto out;
- }
-
- /* now build up the config list & call the ioctl */
- if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
- goto out;
-
- if (nvlist_add_nvlist(newconfig,
- ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
- nvlist_add_string(newconfig,
- ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
- nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
- goto out;
-
- /*
- * The new pool is automatically part of the namespace unless we
- * explicitly export it.
- */
- if (!flags.import)
- zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
- zcmd_write_conf_nvlist(hdl, &zc, newconfig);
- if (zc_props != NULL)
- zcmd_write_src_nvlist(hdl, &zc, zc_props);
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
- retval = zpool_standard_error(hdl, errno, errbuf);
- goto out;
- }
-
- freelist = B_FALSE;
- memory_err = B_FALSE;
-
-out:
- if (varray != NULL) {
- int v;
-
- for (v = 0; v < vcount; v++)
- nvlist_free(varray[v]);
- free(varray);
- }
- zcmd_free_nvlists(&zc);
- nvlist_free(zc_props);
- nvlist_free(newconfig);
- if (freelist) {
- nvlist_free(*newroot);
- *newroot = NULL;
- }
-
- if (retval != 0)
- return (retval);
-
- if (memory_err)
- return (no_memory(hdl));
-
- return (0);
-}
-
-/*
- * Remove the given device.
- */
-int
-zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache, islog;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- uint64_t version;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
-
- if (zpool_is_draid_spare(path)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dRAID spares cannot be removed"));
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
- }
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- &islog)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
- if (islog && version < SPA_VERSION_HOLES) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded to support log removal"));
- return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
- }
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
- return (0);
-
- switch (errno) {
-
- case EALREADY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "removal for this vdev is already in progress."));
- (void) zfs_error(hdl, EZFS_BUSY, errbuf);
- break;
-
- case EINVAL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid config; all top-level vdevs must "
- "have the same sector size and not be raidz."));
- (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
- break;
-
- case EBUSY:
- if (islog) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Mount encrypted datasets to replay logs."));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Pool busy; removal may already be in progress"));
- }
- (void) zfs_error(hdl, EZFS_BUSY, errbuf);
- break;
-
- case EACCES:
- if (islog) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Mount encrypted datasets to replay logs."));
- (void) zfs_error(hdl, EZFS_BUSY, errbuf);
- } else {
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
- break;
-
- default:
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
- return (-1);
-}
-
-int
-zpool_vdev_remove_cancel(zpool_handle_t *zhp)
-{
- zfs_cmd_t zc = {{0}};
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot cancel removal"));
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_cookie = 1;
-
- if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
- return (0);
-
- return (zpool_standard_error(hdl, errno, errbuf));
-}
-
-int
-zpool_vdev_indirect_size(zpool_handle_t *zhp, const char *path,
- uint64_t *sizep)
-{
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache, islog;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot determine indirect size of %s"),
- path);
-
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
- &islog)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- if (avail_spare || l2cache || islog) {
- *sizep = 0;
- return (0);
- }
-
- if (nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_INDIRECT_SIZE, sizep) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "indirect size not available"));
- return (zfs_error(hdl, EINVAL, errbuf));
- }
- return (0);
-}
-
-/*
- * Clear the errors for the pool, or the particular device if specified.
- */
-int
-zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- nvlist_t *tgt;
- zpool_load_policy_t policy;
- boolean_t avail_spare, l2cache;
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- nvlist_t *nvi = NULL;
- int error;
-
- if (path)
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
- path);
- else
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
- zhp->zpool_name);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- if (path) {
- if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
- &l2cache, NULL)) == NULL)
- return (zfs_error(hdl, EZFS_NODEVICE, errbuf));
-
- /*
- * Don't allow error clearing for hot spares. Do allow
- * error clearing for l2cache devices.
- */
- if (avail_spare)
- return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
-
- zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
- }
-
- zpool_get_load_policy(rewindnvl, &policy);
- zc.zc_cookie = policy.zlp_rewind;
-
- zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2);
- zcmd_write_src_nvlist(hdl, &zc, rewindnvl);
-
- while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
- errno == ENOMEM)
- zcmd_expand_dst_nvlist(hdl, &zc);
-
- if (!error || ((policy.zlp_rewind & ZPOOL_TRY_REWIND) &&
- errno != EPERM && errno != EACCES)) {
- if (policy.zlp_rewind &
- (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
- (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
- zpool_rewind_exclaim(hdl, zc.zc_name,
- ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0),
- nvi);
- nvlist_free(nvi);
- }
- zcmd_free_nvlists(&zc);
- return (0);
- }
-
- zcmd_free_nvlists(&zc);
- return (zpool_standard_error(hdl, errno, errbuf));
-}
-
-/*
- * Similar to zpool_clear(), but takes a GUID (used by fmd).
- */
-int
-zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
-{
- zfs_cmd_t zc = {"\0"};
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
- (u_longlong_t)guid);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_guid = guid;
- zc.zc_cookie = ZPOOL_NO_REWIND;
-
- if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0)
- return (0);
-
- return (zpool_standard_error(hdl, errno, errbuf));
-}
-
-/*
- * Change the GUID for a pool.
- *
- * Similar to zpool_reguid(), but may take a GUID.
- *
- * If the guid argument is NULL, then no GUID is passed in the nvlist to the
- * ioctl().
- */
-int
-zpool_set_guid(zpool_handle_t *zhp, const uint64_t *guid)
-{
- char errbuf[ERRBUFLEN];
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- nvlist_t *nvl = NULL;
- zfs_cmd_t zc = {"\0"};
- int error;
-
- if (guid != NULL) {
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(hdl));
-
- if (nvlist_add_uint64(nvl, ZPOOL_REGUID_GUID, *guid) != 0) {
- nvlist_free(nvl);
- return (no_memory(hdl));
- }
-
- zcmd_write_src_nvlist(hdl, &zc, nvl);
- }
-
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- error = zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc);
- if (error) {
- return (zpool_standard_error(hdl, errno, errbuf));
- }
- if (guid != NULL) {
- zcmd_free_nvlists(&zc);
- nvlist_free(nvl);
- }
- return (0);
-}
-
-/*
- * Change the GUID for a pool.
- */
-int
-zpool_reguid(zpool_handle_t *zhp)
-{
- return (zpool_set_guid(zhp, NULL));
-}
-
-/*
- * Reopen the pool.
- */
-int
-zpool_reopen_one(zpool_handle_t *zhp, void *data)
-{
- libzfs_handle_t *hdl = zpool_get_handle(zhp);
- const char *pool_name = zpool_get_name(zhp);
- boolean_t *scrub_restart = data;
- int error;
-
- error = lzc_reopen(pool_name, *scrub_restart);
- if (error) {
- return (zpool_standard_error_fmt(hdl, error,
- dgettext(TEXT_DOMAIN, "cannot reopen '%s'"), pool_name));
- }
-
- return (0);
-}
-
-/* call into libzfs_core to execute the sync IOCTL per pool */
-int
-zpool_sync_one(zpool_handle_t *zhp, void *data)
-{
- int ret;
- libzfs_handle_t *hdl = zpool_get_handle(zhp);
- const char *pool_name = zpool_get_name(zhp);
- boolean_t *force = data;
- nvlist_t *innvl = fnvlist_alloc();
-
- fnvlist_add_boolean_value(innvl, "force", *force);
- if ((ret = lzc_sync(pool_name, innvl, NULL)) != 0) {
- nvlist_free(innvl);
- return (zpool_standard_error_fmt(hdl, ret,
- dgettext(TEXT_DOMAIN, "sync '%s' failed"), pool_name));
- }
- nvlist_free(innvl);
-
- return (0);
-}
-
-#define PATH_BUF_LEN 64
-
-/*
- * Given a vdev, return the name to display in iostat. If the vdev has a path,
- * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
- * We also check if this is a whole disk, in which case we strip off the
- * trailing 's0' slice name.
- *
- * This routine is also responsible for identifying when disks have been
- * reconfigured in a new location. The kernel will have opened the device by
- * devid, but the path will still refer to the old location. To catch this, we
- * first do a path -> devid translation (which is fast for the common case). If
- * the devid matches, we're done. If not, we do a reverse devid -> path
- * translation and issue the appropriate ioctl() to update the path of the vdev.
- * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
- * of these checks.
- */
-char *
-zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
- int name_flags)
-{
- const char *type, *tpath;
- const char *path;
- uint64_t value;
- char buf[PATH_BUF_LEN];
- char tmpbuf[PATH_BUF_LEN * 2];
-
- /*
- * vdev_name will be "root"/"root-0" for the root vdev, but it is the
- * zpool name that will be displayed to the user.
- */
- type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE);
- if (zhp != NULL && strcmp(type, "root") == 0)
- return (zfs_strdup(hdl, zpool_get_name(zhp)));
-
- if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_PATH"))
- name_flags |= VDEV_NAME_PATH;
- if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_GUID"))
- name_flags |= VDEV_NAME_GUID;
- if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_FOLLOW_LINKS"))
- name_flags |= VDEV_NAME_FOLLOW_LINKS;
-
- if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
- name_flags & VDEV_NAME_GUID) {
- (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
- (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
- path = buf;
- } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &tpath) == 0) {
- path = tpath;
-
- if (name_flags & VDEV_NAME_FOLLOW_LINKS) {
- char *rp = realpath(path, NULL);
- if (rp) {
- strlcpy(buf, rp, sizeof (buf));
- path = buf;
- free(rp);
- }
- }
-
- /*
- * For a block device only use the name.
- */
- if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
- !(name_flags & VDEV_NAME_PATH)) {
- path = zfs_strip_path(path);
- }
-
- /*
- * Remove the partition from the path if this is a whole disk.
- */
- if (strcmp(type, VDEV_TYPE_DRAID_SPARE) != 0 &&
- nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
- == 0 && value && !(name_flags & VDEV_NAME_PATH)) {
- return (zfs_strip_partition(path));
- }
- } else {
- path = type;
-
- /*
- * If it's a raidz device, we need to stick in the parity level.
- */
- if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
- value = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY);
- (void) snprintf(buf, sizeof (buf), "%s%llu", path,
- (u_longlong_t)value);
- path = buf;
- }
-
- /*
- * If it's a dRAID device, we add parity, groups, and spares.
- */
- if (strcmp(path, VDEV_TYPE_DRAID) == 0) {
- uint64_t ndata, nparity, nspares;
- nvlist_t **child;
- uint_t children;
-
- verify(nvlist_lookup_nvlist_array(nv,
- ZPOOL_CONFIG_CHILDREN, &child, &children) == 0);
- nparity = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_NPARITY);
- ndata = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_DRAID_NDATA);
- nspares = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_DRAID_NSPARES);
-
- path = zpool_draid_name(buf, sizeof (buf), ndata,
- nparity, nspares, children);
- }
-
- /*
- * We identify each top-level vdev by using a <type-id>
- * naming convention.
- */
- if (name_flags & VDEV_NAME_TYPE_ID) {
- uint64_t id = fnvlist_lookup_uint64(nv,
- ZPOOL_CONFIG_ID);
- (void) snprintf(tmpbuf, sizeof (tmpbuf), "%s-%llu",
- path, (u_longlong_t)id);
- path = tmpbuf;
- }
- }
-
- return (zfs_strdup(hdl, path));
-}
-
-static int
-zbookmark_mem_compare(const void *a, const void *b)
-{
- return (memcmp(a, b, sizeof (zbookmark_phys_t)));
-}
-
-void
-zpool_add_propname(zpool_handle_t *zhp, const char *propname)
-{
- assert(zhp->zpool_n_propnames < ZHP_MAX_PROPNAMES);
- zhp->zpool_propnames[zhp->zpool_n_propnames] = propname;
- zhp->zpool_n_propnames++;
-}
-
-/*
- * Retrieve the persistent error log, uniquify the members, and return to the
- * caller.
- */
-int
-zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- zbookmark_phys_t *buf;
- uint64_t buflen = 10000; /* approx. 1MB of RAM */
-
- if (fnvlist_lookup_uint64(zhp->zpool_config,
- ZPOOL_CONFIG_ERRCOUNT) == 0)
- return (0);
-
- /*
- * Retrieve the raw error list from the kernel. If it doesn't fit,
- * allocate a larger buffer and retry.
- */
- (void) strcpy(zc.zc_name, zhp->zpool_name);
- for (;;) {
- buf = zfs_alloc(zhp->zpool_hdl,
- buflen * sizeof (zbookmark_phys_t));
- zc.zc_nvlist_dst = (uintptr_t)buf;
- zc.zc_nvlist_dst_size = buflen;
- if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_ERROR_LOG,
- &zc) != 0) {
- free(buf);
- if (errno == ENOMEM) {
- buflen *= 2;
- } else {
- return (zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN, "errors: List of "
- "errors unavailable")));
- }
- } else {
- break;
- }
- }
-
- /*
- * Sort the resulting bookmarks. This is a little confusing due to the
- * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last
- * to first, and 'zc_nvlist_dst_size' indicates the number of bookmarks
- * _not_ copied as part of the process. So we point the start of our
- * array appropriate and decrement the total number of elements.
- */
- zbookmark_phys_t *zb = buf + zc.zc_nvlist_dst_size;
- uint64_t zblen = buflen - zc.zc_nvlist_dst_size;
-
- qsort(zb, zblen, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
-
- verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
-
- /*
- * Fill in the nverrlistp with nvlist's of dataset and object numbers.
- */
- for (uint64_t i = 0; i < zblen; i++) {
- nvlist_t *nv;
-
- /* ignoring zb_blkid and zb_level for now */
- if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
- zb[i-1].zb_object == zb[i].zb_object)
- continue;
-
- if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
- goto nomem;
- if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
- zb[i].zb_objset) != 0) {
- nvlist_free(nv);
- goto nomem;
- }
- if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
- zb[i].zb_object) != 0) {
- nvlist_free(nv);
- goto nomem;
- }
- if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
- nvlist_free(nv);
- goto nomem;
- }
- nvlist_free(nv);
- }
-
- free(buf);
- return (0);
-
-nomem:
- free(buf);
- return (no_memory(zhp->zpool_hdl));
-}
-
-/*
- * Upgrade a ZFS pool to the latest on-disk version.
- */
-int
-zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) strcpy(zc.zc_name, zhp->zpool_name);
- zc.zc_cookie = new_version;
-
- if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
- return (zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
- zhp->zpool_name));
- return (0);
-}
-
-void
-zfs_save_arguments(int argc, char **argv, char *string, int len)
-{
- int i;
-
- (void) strlcpy(string, zfs_basename(argv[0]), len);
- for (i = 1; i < argc; i++) {
- (void) strlcat(string, " ", len);
- (void) strlcat(string, argv[i], len);
- }
-}
-
-int
-zpool_log_history(libzfs_handle_t *hdl, const char *message)
-{
- zfs_cmd_t zc = {"\0"};
- nvlist_t *args;
-
- args = fnvlist_alloc();
- fnvlist_add_string(args, "message", message);
- zcmd_write_src_nvlist(hdl, &zc, args);
- int err = zfs_ioctl(hdl, ZFS_IOC_LOG_HISTORY, &zc);
- nvlist_free(args);
- zcmd_free_nvlists(&zc);
- return (err);
-}
-
-/*
- * Perform ioctl to get some command history of a pool.
- *
- * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the
- * logical offset of the history buffer to start reading from.
- *
- * Upon return, 'off' is the next logical offset to read from and
- * 'len' is the actual amount of bytes read into 'buf'.
- */
-static int
-get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zpool_hdl;
-
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
-
- zc.zc_history = (uint64_t)(uintptr_t)buf;
- zc.zc_history_len = *len;
- zc.zc_history_offset = *off;
-
- if (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
- switch (errno) {
- case EPERM:
- return (zfs_error_fmt(hdl, EZFS_PERM,
- dgettext(TEXT_DOMAIN,
- "cannot show history for pool '%s'"),
- zhp->zpool_name));
- case ENOENT:
- return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
- dgettext(TEXT_DOMAIN, "cannot get history for pool "
- "'%s'"), zhp->zpool_name));
- case ENOTSUP:
- return (zfs_error_fmt(hdl, EZFS_BADVERSION,
- dgettext(TEXT_DOMAIN, "cannot get history for pool "
- "'%s', pool must be upgraded"), zhp->zpool_name));
- default:
- return (zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN,
- "cannot get history for '%s'"), zhp->zpool_name));
- }
- }
-
- *len = zc.zc_history_len;
- *off = zc.zc_history_offset;
-
- return (0);
-}
-
-/*
- * Retrieve the command history of a pool.
- */
-int
-zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
- boolean_t *eof)
-{
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char *buf;
- int buflen = 128 * 1024;
- nvlist_t **records = NULL;
- uint_t numrecords = 0;
- int err = 0, i;
- uint64_t start = *off;
-
- buf = zfs_alloc(hdl, buflen);
-
- /* process about 1MiB a time */
- while (*off - start < 1024 * 1024) {
- uint64_t bytes_read = buflen;
- uint64_t leftover;
-
- if ((err = get_history(zhp, buf, off, &bytes_read)) != 0)
- break;
-
- /* if nothing else was read in, we're at EOF, just return */
- if (!bytes_read) {
- *eof = B_TRUE;
- break;
- }
-
- if ((err = zpool_history_unpack(buf, bytes_read,
- &leftover, &records, &numrecords)) != 0) {
- zpool_standard_error_fmt(hdl, err,
- dgettext(TEXT_DOMAIN,
- "cannot get history for '%s'"), zhp->zpool_name);
- break;
- }
- *off -= leftover;
- if (leftover == bytes_read) {
- /*
- * no progress made, because buffer is not big enough
- * to hold this record; resize and retry.
- */
- buflen *= 2;
- free(buf);
- buf = zfs_alloc(hdl, buflen);
- }
- }
-
- free(buf);
-
- if (!err) {
- *nvhisp = fnvlist_alloc();
- fnvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
- (const nvlist_t **)records, numrecords);
- }
- for (i = 0; i < numrecords; i++)
- nvlist_free(records[i]);
- free(records);
-
- return (err);
-}
-
-/*
- * Retrieve the next event given the passed 'zevent_fd' file descriptor.
- * If there is a new event available 'nvp' will contain a newly allocated
- * nvlist and 'dropped' will be set to the number of missed events since
- * the last call to this function. When 'nvp' is set to NULL it indicates
- * no new events are available. In either case the function returns 0 and
- * it is up to the caller to free 'nvp'. In the case of a fatal error the
- * function will return a non-zero value. When the function is called in
- * blocking mode (the default, unless the ZEVENT_NONBLOCK flag is passed),
- * it will not return until a new event is available.
- */
-int
-zpool_events_next(libzfs_handle_t *hdl, nvlist_t **nvp,
- int *dropped, unsigned flags, int zevent_fd)
-{
- zfs_cmd_t zc = {"\0"};
- int error = 0;
-
- *nvp = NULL;
- *dropped = 0;
- zc.zc_cleanup_fd = zevent_fd;
-
- if (flags & ZEVENT_NONBLOCK)
- zc.zc_guid = ZEVENT_NONBLOCK;
-
- zcmd_alloc_dst_nvlist(hdl, &zc, ZEVENT_SIZE);
-
-retry:
- if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_NEXT, &zc) != 0) {
- switch (errno) {
- case ESHUTDOWN:
- error = zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
- dgettext(TEXT_DOMAIN, "zfs shutdown"));
- goto out;
- case ENOENT:
- /* Blocking error case should not occur */
- if (!(flags & ZEVENT_NONBLOCK))
- error = zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot get event"));
-
- goto out;
- case ENOMEM:
- zcmd_expand_dst_nvlist(hdl, &zc);
- goto retry;
- default:
- error = zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot get event"));
- goto out;
- }
- }
-
- error = zcmd_read_dst_nvlist(hdl, &zc, nvp);
- if (error != 0)
- goto out;
-
- *dropped = (int)zc.zc_cookie;
-out:
- zcmd_free_nvlists(&zc);
-
- return (error);
-}
-
-/*
- * Clear all events.
- */
-int
-zpool_events_clear(libzfs_handle_t *hdl, int *count)
-{
- zfs_cmd_t zc = {"\0"};
-
- if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0)
- return (zpool_standard_error(hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot clear events")));
-
- if (count != NULL)
- *count = (int)zc.zc_cookie; /* # of events cleared */
-
- return (0);
-}
-
-/*
- * Seek to a specific EID, ZEVENT_SEEK_START, or ZEVENT_SEEK_END for
- * the passed zevent_fd file handle. On success zero is returned,
- * otherwise -1 is returned and hdl->libzfs_error is set to the errno.
- */
-int
-zpool_events_seek(libzfs_handle_t *hdl, uint64_t eid, int zevent_fd)
-{
- zfs_cmd_t zc = {"\0"};
- int error = 0;
-
- zc.zc_guid = eid;
- zc.zc_cleanup_fd = zevent_fd;
-
- if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_SEEK, &zc) != 0) {
- switch (errno) {
- case ENOENT:
- error = zfs_error_fmt(hdl, EZFS_NOENT,
- dgettext(TEXT_DOMAIN, "cannot get event"));
- break;
-
- case ENOMEM:
- error = zfs_error_fmt(hdl, EZFS_NOMEM,
- dgettext(TEXT_DOMAIN, "cannot get event"));
- break;
-
- default:
- error = zpool_standard_error_fmt(hdl, errno,
- dgettext(TEXT_DOMAIN, "cannot get event"));
- break;
- }
- }
-
- return (error);
-}
-
-static void
-zpool_obj_to_path_impl(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
- char *pathname, size_t len, boolean_t always_unmounted)
-{
- zfs_cmd_t zc = {"\0"};
- boolean_t mounted = B_FALSE;
- char *mntpnt = NULL;
- char dsname[ZFS_MAX_DATASET_NAME_LEN];
-
- if (dsobj == 0) {
- /* special case for the MOS */
- (void) snprintf(pathname, len, "<metadata>:<0x%llx>",
- (longlong_t)obj);
- return;
- }
-
- /* get the dataset's name */
- (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
- zc.zc_obj = dsobj;
- if (zfs_ioctl(zhp->zpool_hdl,
- ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
- /* just write out a path of two object numbers */
- (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
- (longlong_t)dsobj, (longlong_t)obj);
- return;
- }
- (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
-
- /* find out if the dataset is mounted */
- mounted = !always_unmounted && is_mounted(zhp->zpool_hdl, dsname,
- &mntpnt);
-
- /* get the corrupted object's path */
- (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
- zc.zc_obj = obj;
- if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_OBJ_TO_PATH,
- &zc) == 0) {
- if (mounted) {
- (void) snprintf(pathname, len, "%s%s", mntpnt,
- zc.zc_value);
- } else {
- (void) snprintf(pathname, len, "%s:%s",
- dsname, zc.zc_value);
- }
- } else {
- (void) snprintf(pathname, len, "%s:<0x%llx>", dsname,
- (longlong_t)obj);
- }
- free(mntpnt);
-}
-
-void
-zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
- char *pathname, size_t len)
-{
- zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_FALSE);
-}
-
-void
-zpool_obj_to_path_ds(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
- char *pathname, size_t len)
-{
- zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_TRUE);
-}
-/*
- * Wait while the specified activity is in progress in the pool.
- */
-int
-zpool_wait(zpool_handle_t *zhp, zpool_wait_activity_t activity)
-{
- boolean_t missing;
-
- int error = zpool_wait_status(zhp, activity, &missing, NULL);
-
- if (missing) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl, ENOENT,
- dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
- zhp->zpool_name);
- return (ENOENT);
- } else {
- return (error);
- }
-}
-
-/*
- * Wait for the given activity and return the status of the wait (whether or not
- * any waiting was done) in the 'waited' parameter. Non-existent pools are
- * reported via the 'missing' parameter, rather than by printing an error
- * message. This is convenient when this function is called in a loop over a
- * long period of time (as it is, for example, by zpool's wait cmd). In that
- * scenario, a pool being exported or destroyed should be considered a normal
- * event, so we don't want to print an error when we find that the pool doesn't
- * exist.
- */
-int
-zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity,
- boolean_t *missing, boolean_t *waited)
-{
- int error = lzc_wait(zhp->zpool_name, activity, waited);
- *missing = (error == ENOENT);
- if (*missing)
- return (0);
-
- if (error != 0) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
- dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
- zhp->zpool_name);
- }
-
- return (error);
-}
-
-int
-zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap)
-{
- int error = lzc_set_bootenv(zhp->zpool_name, envmap);
- if (error != 0) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
- dgettext(TEXT_DOMAIN,
- "error setting bootenv in pool '%s'"), zhp->zpool_name);
- }
-
- return (error);
-}
-
-int
-zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp)
-{
- nvlist_t *nvl;
- int error;
-
- nvl = NULL;
- error = lzc_get_bootenv(zhp->zpool_name, &nvl);
- if (error != 0) {
- (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
- dgettext(TEXT_DOMAIN,
- "error getting bootenv in pool '%s'"), zhp->zpool_name);
- } else {
- *nvlp = nvl;
- }
-
- return (error);
-}
-
-/*
- * Attempt to read and parse feature file(s) (from "compatibility" property).
- * Files contain zpool feature names, comma or whitespace-separated.
- * Comments (# character to next newline) are discarded.
- *
- * Arguments:
- * compatibility : string containing feature filenames
- * features : either NULL or pointer to array of boolean
- * 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,
- * or relative to:
- * 1) ZPOOL_SYSCONF_COMPAT_D (eg: /etc/zfs/compatibility.d) or
- * 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.
- *
- * "report" if not NULL will be populated with a suitable status message.
- *
- * Return values:
- * ZPOOL_COMPATIBILITY_OK : files read and parsed ok
- * ZPOOL_COMPATIBILITY_BADFILE : file too big or not a text file
- * 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 *compat, boolean_t *features, char *report,
- size_t rlen)
-{
- int sdirfd, ddirfd, featfd;
- struct stat fs;
- char *fc;
- char *ps, *ls, *ws;
- char *file, *line, *word;
-
- 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 (compat == NULL || compat[0] == '\0' ||
- strcmp(compat, ZPOOL_COMPAT_OFF) == 0) {
- if (features != NULL) {
- 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(compat, ZPOOL_COMPAT_LEGACY) == 0) {
- if (features != NULL)
- 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);
- }
-
- /*
- * Start with all true; will be ANDed with results from each file
- */
- if (features != NULL)
- for (uint_t i = 0; i < SPA_FEATURES; i++)
- features[i] = B_TRUE;
-
- char err_badfile[ZFS_MAXPROPLEN] = "";
- char err_badtoken[ZFS_MAXPROPLEN] = "";
-
- /*
- * We ignore errors from the directory open()
- * as they're only needed if the filename is relative
- * which will be checked during the openat().
- */
-
-/* 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
-#define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_RDONLY)
-#endif
-
- 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 */
- source = Z_SYSCONF;
- if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) {
- featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC);
- source = Z_DATA;
- }
-
- /* 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);
- 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,
- ZC_MMAP_FLAGS, featfd, 0);
- (void) close(featfd);
-
- /* map ok, and last character == newline? */
- if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') {
- (void) munmap((void *) fc, fs.st_size);
- strlcat(err_badfile, file, ZFS_MAXPROPLEN);
- strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
- ret_badfile = B_TRUE;
- continue;
- }
-
- 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 (line = strtok_r(fc, "\n", &ls);
- line != NULL;
- line = strtok_r(NULL, "\n", &ls)) {
- /* discard comments */
- char *r = strchr(line, '#');
- if (r != NULL)
- *r = '\0';
-
- for (word = strtok_r(line, ", \t", &ws);
- word != NULL;
- word = strtok_r(NULL, ", \t", &ws)) {
- /* Find matching feature name */
- uint_t f;
- for (f = 0; f < SPA_FEATURES; f++) {
- zfeature_info_t *fi =
- &spa_feature_table[f];
- if (strcmp(word, fi->fi_uname) == 0) {
- l_features[f] = B_TRUE;
- break;
- }
- }
- 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;
- }
- }
- (void) munmap((void *) fc, fs.st_size);
-
- if (features != NULL)
- for (uint_t i = 0; i < SPA_FEATURES; i++)
- features[i] &= l_features[i];
- }
- (void) close(sdirfd);
- (void) close(ddirfd);
-
- /* 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);
-}
-
-static int
-zpool_vdev_guid(zpool_handle_t *zhp, const char *vdevname, uint64_t *vdev_guid)
-{
- nvlist_t *tgt;
- boolean_t avail_spare, l2cache;
-
- verify(zhp != NULL);
- if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "pool is in an unavailable state"));
- return (zfs_error(zhp->zpool_hdl, EZFS_POOLUNAVAIL, errbuf));
- }
-
- if ((tgt = zpool_find_vdev(zhp, vdevname, &avail_spare, &l2cache,
- NULL)) == NULL) {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "can not find %s in %s"),
- vdevname, zhp->zpool_name);
- return (zfs_error(zhp->zpool_hdl, EZFS_NODEVICE, errbuf));
- }
-
- *vdev_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
- return (0);
-}
-
-/*
- * Get a vdev property value for 'prop' and return the value in
- * a pre-allocated buffer.
- */
-int
-zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name,
- char *buf, size_t len, zprop_source_t *srctype, boolean_t literal)
-{
- nvlist_t *nv;
- const char *strval;
- uint64_t intval;
- zprop_source_t src = ZPROP_SRC_NONE;
-
- if (prop == VDEV_PROP_USERPROP) {
- /* user property, prop_name must contain the property name */
- assert(prop_name != NULL);
- if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
- src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
- } else {
- /* user prop not found */
- src = ZPROP_SRC_DEFAULT;
- strval = "-";
- }
- (void) strlcpy(buf, strval, len);
- if (srctype)
- *srctype = src;
- return (0);
- }
-
- if (prop_name == NULL)
- prop_name = (char *)vdev_prop_to_name(prop);
-
- switch (vdev_prop_get_type(prop)) {
- case PROP_TYPE_STRING:
- if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
- src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
- } else {
- src = ZPROP_SRC_DEFAULT;
- if ((strval = vdev_prop_default_string(prop)) == NULL)
- strval = "-";
- }
- (void) strlcpy(buf, strval, len);
- break;
-
- case PROP_TYPE_NUMBER:
- if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
- src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
- } else {
- src = ZPROP_SRC_DEFAULT;
- intval = vdev_prop_default_numeric(prop);
- }
-
- switch (prop) {
- case VDEV_PROP_ASIZE:
- case VDEV_PROP_PSIZE:
- case VDEV_PROP_SIZE:
- case VDEV_PROP_BOOTSIZE:
- case VDEV_PROP_ALLOCATED:
- case VDEV_PROP_FREE:
- case VDEV_PROP_READ_ERRORS:
- case VDEV_PROP_WRITE_ERRORS:
- case VDEV_PROP_CHECKSUM_ERRORS:
- case VDEV_PROP_INITIALIZE_ERRORS:
- case VDEV_PROP_TRIM_ERRORS:
- case VDEV_PROP_SLOW_IOS:
- case VDEV_PROP_OPS_NULL:
- case VDEV_PROP_OPS_READ:
- case VDEV_PROP_OPS_WRITE:
- case VDEV_PROP_OPS_FREE:
- case VDEV_PROP_OPS_CLAIM:
- case VDEV_PROP_OPS_TRIM:
- case VDEV_PROP_BYTES_NULL:
- case VDEV_PROP_BYTES_READ:
- case VDEV_PROP_BYTES_WRITE:
- case VDEV_PROP_BYTES_FREE:
- case VDEV_PROP_BYTES_CLAIM:
- case VDEV_PROP_BYTES_TRIM:
- if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) zfs_nicenum(intval, buf, len);
- }
- break;
- case VDEV_PROP_EXPANDSZ:
- if (intval == 0) {
- (void) strlcpy(buf, "-", len);
- } else if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) zfs_nicenum(intval, buf, len);
- }
- break;
- case VDEV_PROP_CAPACITY:
- if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) snprintf(buf, len, "%llu%%",
- (u_longlong_t)intval);
- }
- break;
- case VDEV_PROP_CHECKSUM_N:
- case VDEV_PROP_CHECKSUM_T:
- case VDEV_PROP_IO_N:
- case VDEV_PROP_IO_T:
- case VDEV_PROP_SLOW_IO_N:
- case VDEV_PROP_SLOW_IO_T:
- if (intval == UINT64_MAX) {
- (void) strlcpy(buf, "-", len);
- } else {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- }
- break;
- case VDEV_PROP_FRAGMENTATION:
- if (intval == UINT64_MAX) {
- (void) strlcpy(buf, "-", len);
- } else {
- (void) snprintf(buf, len, "%llu%%",
- (u_longlong_t)intval);
- }
- break;
- case VDEV_PROP_STATE:
- if (literal) {
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- } else {
- (void) strlcpy(buf, zpool_state_to_name(intval,
- VDEV_AUX_NONE), len);
- }
- break;
- default:
- (void) snprintf(buf, len, "%llu",
- (u_longlong_t)intval);
- }
- break;
-
- case PROP_TYPE_INDEX:
- if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
- src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
- intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
- } else {
- /* 'trim_support' only valid for leaf vdevs */
- if (prop == VDEV_PROP_TRIM_SUPPORT) {
- (void) strlcpy(buf, "-", len);
- break;
- }
- src = ZPROP_SRC_DEFAULT;
- intval = vdev_prop_default_numeric(prop);
- /* Only use if provided by the RAIDZ VDEV above */
- if (prop == VDEV_PROP_RAIDZ_EXPANDING)
- return (ENOENT);
- if (prop == VDEV_PROP_SIT_OUT)
- return (ENOENT);
- }
- if (vdev_prop_index_to_string(prop, intval,
- (const char **)&strval) != 0)
- return (-1);
- (void) strlcpy(buf, strval, len);
- break;
-
- default:
- abort();
- }
-
- if (srctype)
- *srctype = src;
-
- return (0);
-}
-
-/*
- * Get a vdev property value for 'prop_name' and return the value in
- * a pre-allocated buffer.
- */
-int
-zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
- char *prop_name, char *buf, size_t len, zprop_source_t *srctype,
- boolean_t literal)
-{
- nvlist_t *reqnvl, *reqprops;
- nvlist_t *retprops = NULL;
- uint64_t vdev_guid = 0;
- int ret;
-
- if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
- return (ret);
-
- if (nvlist_alloc(&reqnvl, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
- if (nvlist_alloc(&reqprops, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
-
- fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
-
- if (prop != VDEV_PROP_USERPROP) {
- /* prop_name overrides prop value */
- if (prop_name != NULL)
- prop = vdev_name_to_prop(prop_name);
- else
- prop_name = (char *)vdev_prop_to_name(prop);
- assert(prop < VDEV_NUM_PROPS);
- }
-
- assert(prop_name != NULL);
- if (nvlist_add_uint64(reqprops, prop_name, prop) != 0) {
- nvlist_free(reqnvl);
- nvlist_free(reqprops);
- return (no_memory(zhp->zpool_hdl));
- }
-
- fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_PROPS_GET_PROPS, reqprops);
-
- ret = lzc_get_vdev_prop(zhp->zpool_name, reqnvl, &retprops);
-
- if (ret == 0) {
- ret = zpool_get_vdev_prop_value(retprops, prop, prop_name, buf,
- len, srctype, literal);
- } else {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot get vdev property %s from"
- " %s in %s"), prop_name, vdevname, zhp->zpool_name);
- (void) zpool_standard_error(zhp->zpool_hdl, ret, errbuf);
- }
-
- nvlist_free(reqnvl);
- nvlist_free(reqprops);
- nvlist_free(retprops);
-
- return (ret);
-}
-
-/*
- * Get all vdev properties
- */
-int
-zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname,
- nvlist_t **outnvl)
-{
- nvlist_t *nvl = NULL;
- uint64_t vdev_guid = 0;
- int ret;
-
- if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
- return (ret);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
-
- fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
-
- ret = lzc_get_vdev_prop(zhp->zpool_name, nvl, outnvl);
-
- nvlist_free(nvl);
-
- if (ret) {
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot get vdev properties for"
- " %s in %s"), vdevname, zhp->zpool_name);
- (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
- }
-
- return (ret);
-}
-
-/*
- * Set vdev property
- */
-int
-zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
- const char *propname, const char *propval)
-{
- int ret;
- nvlist_t *nvl = NULL;
- nvlist_t *outnvl = NULL;
- nvlist_t *props;
- nvlist_t *realprops;
- prop_flags_t flags = { 0 };
- uint64_t version;
- uint64_t vdev_guid;
-
- if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
- return (ret);
-
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
- if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
- return (no_memory(zhp->zpool_hdl));
-
- fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_SET_VDEV, vdev_guid);
-
- if (nvlist_add_string(props, propname, propval) != 0) {
- nvlist_free(props);
- return (no_memory(zhp->zpool_hdl));
- }
-
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot set property %s for %s on %s"),
- propname, vdevname, zhp->zpool_name);
-
- flags.vdevprop = 1;
- version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
- if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
- zhp->zpool_name, props, version, flags, errbuf)) == NULL) {
- nvlist_free(props);
- nvlist_free(nvl);
- return (-1);
- }
-
- nvlist_free(props);
- props = realprops;
-
- fnvlist_add_nvlist(nvl, ZPOOL_VDEV_PROPS_SET_PROPS, props);
-
- ret = lzc_set_vdev_prop(zhp->zpool_name, nvl, &outnvl);
-
- nvlist_free(props);
- nvlist_free(nvl);
- nvlist_free(outnvl);
-
- if (ret) {
- if (errno == ENOTSUP) {
- zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
- "property not supported for this vdev"));
- (void) zfs_error(zhp->zpool_hdl, EZFS_PROPTYPE, errbuf);
- } else {
- (void) zpool_standard_error(zhp->zpool_hdl, errno,
- errbuf);
- }
- }
-
- return (ret);
-}
-
-/*
- * Prune older entries from the DDT to reclaim space under the quota
- */
-int
-zpool_ddt_prune(zpool_handle_t *zhp, zpool_ddt_prune_unit_t unit,
- uint64_t amount)
-{
- int error = lzc_ddt_prune(zhp->zpool_name, unit, amount);
- if (error != 0) {
- libzfs_handle_t *hdl = zhp->zpool_hdl;
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot prune dedup table on '%s'"), zhp->zpool_name);
-
- if (error == EALREADY) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "a prune operation is already in progress"));
- (void) zfs_error(hdl, EZFS_BUSY, errbuf);
- } else {
- (void) zpool_standard_error(hdl, errno, errbuf);
- }
- return (-1);
- }
-
- return (0);
-}
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
deleted file mode 100644
index 77134d197904..000000000000
--- a/lib/libzfs/libzfs_sendrecv.c
+++ /dev/null
@@ -1,5647 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
- * All rights reserved
- * Copyright (c) 2013 Steven Hartland. All rights reserved.
- * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
- * Copyright (c) 2019 Datto Inc.
- * Copyright (c) 2024, Klara, Inc.
- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <sys/mount.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/avl.h>
-#include <sys/debug.h>
-#include <sys/stat.h>
-#include <pthread.h>
-#include <umem.h>
-#include <time.h>
-
-#include <libzfs.h>
-#include <libzfs_core.h>
-#include <libzutil.h>
-
-#include "zfs_namecheck.h"
-#include "zfs_prop.h"
-#include "zfs_fletcher.h"
-#include "libzfs_impl.h"
-#include <cityhash.h>
-#include <zlib.h>
-#include <sys/zio_checksum.h>
-#include <sys/dsl_crypt.h>
-#include <sys/ddt.h>
-#include <sys/socket.h>
-#include <sys/sha2.h>
-
-static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
- recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **,
- const char *, nvlist_t *);
-static int guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
- uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
- uint64_t num_redact_snaps, char *name);
-static int guid_to_name(libzfs_handle_t *, const char *,
- uint64_t, boolean_t, char *);
-
-typedef struct progress_arg {
- zfs_handle_t *pa_zhp;
- int pa_fd;
- boolean_t pa_parsable;
- boolean_t pa_estimate;
- int pa_verbosity;
- boolean_t pa_astitle;
- boolean_t pa_progress;
- uint64_t pa_size;
-} progress_arg_t;
-
-static int
-dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
- zio_cksum_t *zc, int outfd)
-{
- ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
- ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
- fletcher_4_incremental_native(drr,
- offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
- if (drr->drr_type != DRR_BEGIN) {
- ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
- drr_checksum.drr_checksum));
- drr->drr_u.drr_checksum.drr_checksum = *zc;
- }
- fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
- sizeof (zio_cksum_t), zc);
- if (write(outfd, drr, sizeof (*drr)) == -1)
- return (errno);
- if (payload_len != 0) {
- fletcher_4_incremental_native(payload, payload_len, zc);
- if (write(outfd, payload, payload_len) == -1)
- return (errno);
- }
- return (0);
-}
-
-/*
- * Routines for dealing with the AVL tree of fs-nvlists
- */
-typedef struct fsavl_node {
- avl_node_t fn_node;
- nvlist_t *fn_nvfs;
- const char *fn_snapname;
- uint64_t fn_guid;
-} fsavl_node_t;
-
-static int
-fsavl_compare(const void *arg1, const void *arg2)
-{
- const fsavl_node_t *fn1 = (const fsavl_node_t *)arg1;
- const fsavl_node_t *fn2 = (const fsavl_node_t *)arg2;
-
- return (TREE_CMP(fn1->fn_guid, fn2->fn_guid));
-}
-
-/*
- * Given the GUID of a snapshot, find its containing filesystem and
- * (optionally) name.
- */
-static nvlist_t *
-fsavl_find(avl_tree_t *avl, uint64_t snapguid, const char **snapname)
-{
- fsavl_node_t fn_find;
- fsavl_node_t *fn;
-
- fn_find.fn_guid = snapguid;
-
- fn = avl_find(avl, &fn_find, NULL);
- if (fn) {
- if (snapname)
- *snapname = fn->fn_snapname;
- return (fn->fn_nvfs);
- }
- return (NULL);
-}
-
-static void
-fsavl_destroy(avl_tree_t *avl)
-{
- fsavl_node_t *fn;
- void *cookie;
-
- if (avl == NULL)
- return;
-
- cookie = NULL;
- while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
- free(fn);
- avl_destroy(avl);
- free(avl);
-}
-
-/*
- * Given an nvlist, produce an avl tree of snapshots, ordered by guid
- */
-static avl_tree_t *
-fsavl_create(nvlist_t *fss)
-{
- avl_tree_t *fsavl;
- nvpair_t *fselem = NULL;
-
- if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
- return (NULL);
-
- avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
- offsetof(fsavl_node_t, fn_node));
-
- while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
- nvlist_t *nvfs, *snaps;
- nvpair_t *snapelem = NULL;
-
- nvfs = fnvpair_value_nvlist(fselem);
- snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
-
- while ((snapelem =
- nvlist_next_nvpair(snaps, snapelem)) != NULL) {
- fsavl_node_t *fn;
-
- if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
- fsavl_destroy(fsavl);
- return (NULL);
- }
- fn->fn_nvfs = nvfs;
- fn->fn_snapname = nvpair_name(snapelem);
- fn->fn_guid = fnvpair_value_uint64(snapelem);
-
- /*
- * Note: if there are multiple snaps with the
- * same GUID, we ignore all but one.
- */
- avl_index_t where = 0;
- if (avl_find(fsavl, fn, &where) == NULL)
- avl_insert(fsavl, fn, where);
- else
- free(fn);
- }
- }
-
- return (fsavl);
-}
-
-/*
- * Routines for dealing with the giant nvlist of fs-nvlists, etc.
- */
-typedef struct send_data {
- /*
- * assigned inside every recursive call,
- * restored from *_save on return:
- *
- * guid of fromsnap snapshot in parent dataset
- * txg of fromsnap snapshot in current dataset
- * txg of tosnap snapshot in current dataset
- */
-
- uint64_t parent_fromsnap_guid;
- uint64_t fromsnap_txg;
- uint64_t tosnap_txg;
-
- /* the nvlists get accumulated during depth-first traversal */
- nvlist_t *parent_snaps;
- nvlist_t *fss;
- nvlist_t *snapprops;
- nvlist_t *snapholds; /* user holds */
-
- /* send-receive configuration, does not change during traversal */
- const char *fsname;
- const char *fromsnap;
- const char *tosnap;
- boolean_t recursive;
- boolean_t raw;
- boolean_t doall;
- boolean_t replicate;
- boolean_t skipmissing;
- boolean_t verbose;
- boolean_t backup;
- boolean_t seenfrom;
- boolean_t seento;
- boolean_t holds; /* were holds requested with send -h */
- boolean_t props;
-
- /*
- * The header nvlist is of the following format:
- * {
- * "tosnap" -> string
- * "fromsnap" -> string (if incremental)
- * "fss" -> {
- * id -> {
- *
- * "name" -> string (full name; for debugging)
- * "parentfromsnap" -> number (guid of fromsnap in parent)
- *
- * "props" -> { name -> value (only if set here) }
- * "snaps" -> { name (lastname) -> number (guid) }
- * "snapprops" -> { name (lastname) -> { name -> value } }
- * "snapholds" -> { name (lastname) -> { holdname -> crtime } }
- *
- * "origin" -> number (guid) (if clone)
- * "is_encroot" -> boolean
- * "sent" -> boolean (not on-disk)
- * }
- * }
- * }
- *
- */
-} send_data_t;
-
-static void
-send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv);
-
-/*
- * Collect guid, valid props, optionally holds, etc. of a snapshot.
- * This interface is intended for use as a zfs_iter_snapshots_v2_sorted visitor.
- */
-static int
-send_iterate_snap(zfs_handle_t *zhp, void *arg)
-{
- send_data_t *sd = arg;
- uint64_t guid = zhp->zfs_dmustats.dds_guid;
- uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
- boolean_t isfromsnap, istosnap, istosnapwithnofrom;
- char *snapname;
- const char *from = sd->fromsnap;
- const char *to = sd->tosnap;
-
- snapname = strrchr(zhp->zfs_name, '@');
- assert(snapname != NULL);
- ++snapname;
-
- isfromsnap = (from != NULL && strcmp(from, snapname) == 0);
- istosnap = (to != NULL && strcmp(to, snapname) == 0);
- istosnapwithnofrom = (istosnap && from == NULL);
-
- if (sd->tosnap_txg != 0 && txg > sd->tosnap_txg) {
- if (sd->verbose) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "skipping snapshot %s because it was created "
- "after the destination snapshot (%s)\n"),
- zhp->zfs_name, to);
- }
- zfs_close(zhp);
- return (0);
- }
-
- fnvlist_add_uint64(sd->parent_snaps, snapname, guid);
-
- /*
- * NB: if there is no fromsnap here (it's a newly created fs in
- * an incremental replication), we will substitute the tosnap.
- */
- if (isfromsnap || (sd->parent_fromsnap_guid == 0 && istosnap))
- sd->parent_fromsnap_guid = guid;
-
- if (!sd->recursive) {
- /*
- * To allow a doall stream to work properly
- * with a NULL fromsnap
- */
- if (sd->doall && from == NULL && !sd->seenfrom)
- sd->seenfrom = B_TRUE;
-
- if (!sd->seenfrom && isfromsnap) {
- sd->seenfrom = B_TRUE;
- zfs_close(zhp);
- return (0);
- }
-
- if ((sd->seento || !sd->seenfrom) && !istosnapwithnofrom) {
- zfs_close(zhp);
- return (0);
- }
-
- if (istosnap)
- sd->seento = B_TRUE;
- }
-
- nvlist_t *nv = fnvlist_alloc();
- send_iterate_prop(zhp, sd->backup, nv);
- fnvlist_add_nvlist(sd->snapprops, snapname, nv);
- fnvlist_free(nv);
-
- if (sd->holds) {
- nvlist_t *holds;
- if (lzc_get_holds(zhp->zfs_name, &holds) == 0) {
- fnvlist_add_nvlist(sd->snapholds, snapname, holds);
- fnvlist_free(holds);
- }
- }
-
- zfs_close(zhp);
- return (0);
-}
-
-/*
- * Collect all valid props from the handle snap into an nvlist.
- */
-static void
-send_iterate_prop(zfs_handle_t *zhp, boolean_t received_only, nvlist_t *nv)
-{
- nvlist_t *props;
-
- if (received_only)
- props = zfs_get_recvd_props(zhp);
- else
- props = zhp->zfs_props;
-
- nvpair_t *elem = NULL;
- while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
- const char *propname = nvpair_name(elem);
- zfs_prop_t prop = zfs_name_to_prop(propname);
-
- if (!zfs_prop_user(propname)) {
- /*
- * Realistically, this should never happen. However,
- * we want the ability to add DSL properties without
- * needing to make incompatible version changes. We
- * need to ignore unknown properties to allow older
- * software to still send datasets containing these
- * properties, with the unknown properties elided.
- */
- if (prop == ZPROP_INVAL)
- continue;
-
- if (zfs_prop_readonly(prop))
- continue;
- }
-
- nvlist_t *propnv = fnvpair_value_nvlist(elem);
-
- boolean_t isspacelimit = (prop == ZFS_PROP_QUOTA ||
- prop == ZFS_PROP_RESERVATION ||
- prop == ZFS_PROP_REFQUOTA ||
- prop == ZFS_PROP_REFRESERVATION);
- if (isspacelimit && zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
- continue;
-
- const char *source;
- if (nvlist_lookup_string(propnv, ZPROP_SOURCE, &source) == 0) {
- if (strcmp(source, zhp->zfs_name) != 0 &&
- strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
- continue;
- } else {
- /*
- * May have no source before SPA_VERSION_RECVD_PROPS,
- * but is still modifiable.
- */
- if (!isspacelimit)
- continue;
- }
-
- if (zfs_prop_user(propname) ||
- zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
- const char *value;
- value = fnvlist_lookup_string(propnv, ZPROP_VALUE);
- fnvlist_add_string(nv, propname, value);
- } else {
- uint64_t value;
- value = fnvlist_lookup_uint64(propnv, ZPROP_VALUE);
- fnvlist_add_uint64(nv, propname, value);
- }
- }
-}
-
-/*
- * returns snapshot guid
- * and returns 0 if the snapshot does not exist
- */
-static uint64_t
-get_snap_guid(libzfs_handle_t *hdl, const char *fs, const char *snap)
-{
- char name[MAXPATHLEN + 1];
- uint64_t guid = 0;
-
- if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
- return (guid);
-
- (void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
- zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
- if (zhp != NULL) {
- guid = zfs_prop_get_int(zhp, ZFS_PROP_GUID);
- zfs_close(zhp);
- }
-
- return (guid);
-}
-
-/*
- * returns snapshot creation txg
- * and returns 0 if the snapshot does not exist
- */
-static uint64_t
-get_snap_txg(libzfs_handle_t *hdl, const char *fs, const char *snap)
-{
- char name[ZFS_MAX_DATASET_NAME_LEN];
- uint64_t txg = 0;
-
- if (fs == NULL || fs[0] == '\0' || snap == NULL || snap[0] == '\0')
- return (txg);
-
- (void) snprintf(name, sizeof (name), "%s@%s", fs, snap);
- if (zfs_dataset_exists(hdl, name, ZFS_TYPE_SNAPSHOT)) {
- zfs_handle_t *zhp = zfs_open(hdl, name, ZFS_TYPE_SNAPSHOT);
- if (zhp != NULL) {
- txg = zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG);
- zfs_close(zhp);
- }
- }
-
- return (txg);
-}
-
-/*
- * Recursively generate nvlists describing datasets. See comment
- * for the data structure send_data_t above for description of contents
- * of the nvlist.
- */
-static int
-send_iterate_fs(zfs_handle_t *zhp, void *arg)
-{
- send_data_t *sd = arg;
- nvlist_t *nvfs = NULL, *nv = NULL;
- int rv = 0;
- uint64_t min_txg = 0, max_txg = 0;
- uint64_t txg = zhp->zfs_dmustats.dds_creation_txg;
- uint64_t guid = zhp->zfs_dmustats.dds_guid;
- uint64_t fromsnap_txg, tosnap_txg;
- char guidstring[64];
-
- /* These fields are restored on return from a recursive call. */
- uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
- uint64_t fromsnap_txg_save = sd->fromsnap_txg;
- uint64_t tosnap_txg_save = sd->tosnap_txg;
-
- fromsnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->fromsnap);
- if (fromsnap_txg != 0)
- sd->fromsnap_txg = fromsnap_txg;
-
- tosnap_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name, sd->tosnap);
- if (tosnap_txg != 0)
- sd->tosnap_txg = tosnap_txg;
-
- /*
- * On the send side, if the current dataset does not have tosnap,
- * perform two additional checks:
- *
- * - 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, 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) {
- if (sd->verbose) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "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 "
- "exist\n"), sd->fsname, sd->tosnap, sd->recursive ?
- dgettext(TEXT_DOMAIN, " recursively") : "",
- zhp->zfs_name, sd->tosnap);
- rv = EZFS_NOENT;
- }
- goto out;
- }
-
- nvfs = fnvlist_alloc();
- fnvlist_add_string(nvfs, "name", zhp->zfs_name);
- fnvlist_add_uint64(nvfs, "parentfromsnap", sd->parent_fromsnap_guid);
-
- if (zhp->zfs_dmustats.dds_origin[0] != '\0') {
- zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
- zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
- if (origin == NULL) {
- rv = -1;
- goto out;
- }
- fnvlist_add_uint64(nvfs, "origin",
- origin->zfs_dmustats.dds_guid);
- zfs_close(origin);
- }
-
- /* Iterate over props. */
- if (sd->props || sd->backup || sd->recursive) {
- nv = fnvlist_alloc();
- send_iterate_prop(zhp, sd->backup, nv);
- fnvlist_add_nvlist(nvfs, "props", nv);
- }
- if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) != ZIO_CRYPT_OFF) {
- boolean_t encroot;
-
- /* Determine if this dataset is an encryption root. */
- if (zfs_crypto_get_encryption_root(zhp, &encroot, NULL) != 0) {
- rv = -1;
- goto out;
- }
-
- if (encroot)
- fnvlist_add_boolean(nvfs, "is_encroot");
-
- /*
- * Encrypted datasets can only be sent with properties if
- * the raw flag is specified because the receive side doesn't
- * currently have a mechanism for recursively asking the user
- * for new encryption parameters.
- */
- if (!sd->raw) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "cannot send %s@%s: encrypted dataset %s may not "
- "be sent with properties without the raw flag\n"),
- sd->fsname, sd->tosnap, zhp->zfs_name);
- rv = -1;
- goto out;
- }
-
- }
-
- /*
- * Iterate over snaps, and set sd->parent_fromsnap_guid.
- *
- * If this is a "doall" send, a replicate send or we're just trying
- * to gather a list of previous snapshots, iterate through all the
- * snaps in the txg range. Otherwise just look at the one we're
- * interested in.
- */
- sd->parent_fromsnap_guid = 0;
- sd->parent_snaps = fnvlist_alloc();
- sd->snapprops = fnvlist_alloc();
- if (sd->holds)
- sd->snapholds = fnvlist_alloc();
- if (sd->doall || sd->replicate || sd->tosnap == NULL) {
- if (!sd->replicate && fromsnap_txg != 0)
- min_txg = fromsnap_txg;
- if (!sd->replicate && tosnap_txg != 0)
- max_txg = tosnap_txg;
- (void) zfs_iter_snapshots_sorted_v2(zhp, 0, send_iterate_snap,
- sd, min_txg, max_txg);
- } else {
- char snapname[MAXPATHLEN] = { 0 };
- zfs_handle_t *snap;
-
- (void) snprintf(snapname, sizeof (snapname), "%s@%s",
- zhp->zfs_name, sd->tosnap);
- if (sd->fromsnap != NULL)
- sd->seenfrom = B_TRUE;
- snap = zfs_open(zhp->zfs_hdl, snapname, ZFS_TYPE_SNAPSHOT);
- if (snap != NULL)
- (void) send_iterate_snap(snap, sd);
- }
-
- fnvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps);
- fnvlist_free(sd->parent_snaps);
- fnvlist_add_nvlist(nvfs, "snapprops", sd->snapprops);
- fnvlist_free(sd->snapprops);
- if (sd->holds) {
- fnvlist_add_nvlist(nvfs, "snapholds", sd->snapholds);
- fnvlist_free(sd->snapholds);
- }
-
- /* Do not allow the size of the properties list to exceed the limit */
- if ((fnvlist_size(nvfs) + fnvlist_size(sd->fss)) >
- zhp->zfs_hdl->libzfs_max_nvlist) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "warning: cannot send %s@%s: the size of the list of "
- "snapshots and properties is too large to be received "
- "successfully.\n"
- "Select a smaller number of snapshots to send.\n"),
- zhp->zfs_name, sd->tosnap);
- rv = EZFS_NOSPC;
- goto out;
- }
- /* Add this fs to nvlist. */
- (void) snprintf(guidstring, sizeof (guidstring),
- "0x%llx", (longlong_t)guid);
- fnvlist_add_nvlist(sd->fss, guidstring, nvfs);
-
- /* Iterate over children. */
- if (sd->recursive)
- rv = zfs_iter_filesystems_v2(zhp, 0, send_iterate_fs, sd);
-
-out:
- /* Restore saved fields. */
- sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
- sd->fromsnap_txg = fromsnap_txg_save;
- sd->tosnap_txg = tosnap_txg_save;
-
- fnvlist_free(nv);
- fnvlist_free(nvfs);
-
- zfs_close(zhp);
- return (rv);
-}
-
-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 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 };
- int error;
-
- zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL)
- return (EZFS_BADTYPE);
-
- sd.fss = fnvlist_alloc();
- sd.fsname = fsname;
- sd.fromsnap = fromsnap;
- sd.tosnap = tosnap;
- sd.recursive = recursive;
- sd.raw = raw;
- sd.doall = doall;
- sd.replicate = replicate;
- sd.skipmissing = skipmissing;
- sd.verbose = verbose;
- sd.backup = backup;
- sd.holds = holds;
- sd.props = props;
-
- if ((error = send_iterate_fs(zhp, &sd)) != 0) {
- fnvlist_free(sd.fss);
- if (avlp != NULL)
- *avlp = NULL;
- *nvlp = NULL;
- return (error);
- }
-
- if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
- fnvlist_free(sd.fss);
- *nvlp = NULL;
- return (EZFS_NOMEM);
- }
-
- *nvlp = sd.fss;
- return (0);
-}
-
-/*
- * Routines specific to "zfs send"
- */
-typedef struct send_dump_data {
- /* these are all just the short snapname (the part after the @) */
- const char *fromsnap;
- const char *tosnap;
- char prevsnap[ZFS_MAX_DATASET_NAME_LEN];
- uint64_t prevsnap_obj;
- boolean_t seenfrom, seento, replicate, doall, fromorigin;
- boolean_t dryrun, parsable, progress, embed_data, std_out;
- boolean_t large_block, compress, raw, holds;
- boolean_t progressastitle;
- int outfd;
- boolean_t err;
- nvlist_t *fss;
- nvlist_t *snapholds;
- avl_tree_t *fsavl;
- snapfilter_cb_t *filter_cb;
- void *filter_cb_arg;
- nvlist_t *debugnv;
- char holdtag[ZFS_MAX_DATASET_NAME_LEN];
- int cleanup_fd;
- int verbosity;
- uint64_t size;
-} send_dump_data_t;
-
-static int
-zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from,
- enum lzc_send_flags flags, uint64_t *spacep)
-{
- assert(snapname != NULL);
-
- int error = lzc_send_space(snapname, from, flags, spacep);
- if (error == 0)
- return (0);
-
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot estimate space for '%s'"), snapname);
-
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- switch (error) {
- case EXDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not an earlier snapshot from the same fs"));
- return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
-
- case ENOENT:
- if (zfs_dataset_exists(hdl, snapname,
- ZFS_TYPE_SNAPSHOT)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source (%s) does not exist"),
- snapname);
- }
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
-
- case EDQUOT:
- case EFBIG:
- case EIO:
- case ENOLINK:
- case ENOSPC:
- case ENOSTR:
- case ENXIO:
- case EPIPE:
- case ERANGE:
- case EFAULT:
- case EROFS:
- case EINVAL:
- zfs_error_aux(hdl, "%s", zfs_strerror(error));
- return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
-
- default:
- return (zfs_standard_error(hdl, error, errbuf));
- }
-}
-
-/*
- * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
- * NULL) to the file descriptor specified by outfd.
- */
-static int
-dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
- boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
- nvlist_t *debugnv)
-{
- zfs_cmd_t zc = {"\0"};
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvlist_t *thisdbg;
-
- assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
- assert(fromsnap_obj == 0 || !fromorigin);
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- zc.zc_cookie = outfd;
- zc.zc_obj = fromorigin;
- zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
- zc.zc_fromobj = fromsnap_obj;
- zc.zc_flags = flags;
-
- if (debugnv != NULL) {
- thisdbg = fnvlist_alloc();
- if (fromsnap != NULL && fromsnap[0] != '\0')
- fnvlist_add_string(thisdbg, "fromsnap", fromsnap);
- }
-
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
- char errbuf[ERRBUFLEN];
- int error = errno;
-
- (void) snprintf(errbuf, sizeof (errbuf), "%s '%s'",
- dgettext(TEXT_DOMAIN, "warning: cannot send"),
- zhp->zfs_name);
-
- if (debugnv != NULL) {
- fnvlist_add_uint64(thisdbg, "error", error);
- fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
- fnvlist_free(thisdbg);
- }
-
- switch (error) {
- case EXDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not an earlier snapshot from the same fs"));
- return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
-
- case EACCES:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "source key must be loaded"));
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
-
- case ENOENT:
- if (zfs_dataset_exists(hdl, zc.zc_name,
- ZFS_TYPE_SNAPSHOT)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source (@%s) does not exist"),
- zc.zc_value);
- }
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
-
- case EDQUOT:
- case EFBIG:
- case EIO:
- case ENOLINK:
- case ENOSPC:
- case ENOSTR:
- case ENXIO:
- case EPIPE:
- case ERANGE:
- case EFAULT:
- case EROFS:
- case EINVAL:
- zfs_error_aux(hdl, "%s", zfs_strerror(errno));
- return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
-
- default:
- return (zfs_standard_error(hdl, errno, errbuf));
- }
- }
-
- if (debugnv != NULL) {
- fnvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg);
- fnvlist_free(thisdbg);
- }
-
- return (0);
-}
-
-static void
-gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
-{
- assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
-
- /*
- * zfs_send() only sets snapholds for sends that need them,
- * e.g. replication and doall.
- */
- if (sdd->snapholds == NULL)
- return;
-
- fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
-}
-
-int
-zfs_send_progress(zfs_handle_t *zhp, int fd, uint64_t *bytes_written,
- uint64_t *blocks_visited)
-{
- zfs_cmd_t zc = {"\0"};
-
- if (bytes_written != NULL)
- *bytes_written = 0;
- if (blocks_visited != NULL)
- *blocks_visited = 0;
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- zc.zc_cookie = fd;
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
- return (errno);
- if (bytes_written != NULL)
- *bytes_written = zc.zc_cookie;
- if (blocks_visited != NULL)
- *blocks_visited = zc.zc_objset_type;
- return (0);
-}
-
-static volatile boolean_t send_progress_thread_signal_duetotimer;
-static void
-send_progress_thread_act(int sig, siginfo_t *info, void *ucontext)
-{
- (void) sig, (void) ucontext;
- send_progress_thread_signal_duetotimer = info->si_code == SI_TIMER;
-}
-
-struct timer_desirability {
- timer_t timer;
- boolean_t desired;
-};
-static void
-timer_delete_cleanup(void *timer)
-{
- struct timer_desirability *td = timer;
- if (td->desired)
- timer_delete(td->timer);
-}
-
-#ifdef SIGINFO
-#define SEND_PROGRESS_THREAD_PARENT_BLOCK_SIGINFO sigaddset(&new, SIGINFO)
-#else
-#define SEND_PROGRESS_THREAD_PARENT_BLOCK_SIGINFO
-#endif
-#define SEND_PROGRESS_THREAD_PARENT_BLOCK(old) { \
- sigset_t new; \
- sigemptyset(&new); \
- sigaddset(&new, SIGUSR1); \
- SEND_PROGRESS_THREAD_PARENT_BLOCK_SIGINFO; \
- pthread_sigmask(SIG_BLOCK, &new, old); \
-}
-
-static void *
-send_progress_thread(void *arg)
-{
- progress_arg_t *pa = arg;
- zfs_handle_t *zhp = pa->pa_zhp;
- uint64_t bytes;
- uint64_t blocks;
- uint64_t total = pa->pa_size / 100;
- char buf[16];
- time_t t;
- struct tm tm;
- int err;
-
- const struct sigaction signal_action =
- {.sa_sigaction = send_progress_thread_act, .sa_flags = SA_SIGINFO};
- struct sigevent timer_cfg =
- {.sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGUSR1};
- const struct itimerspec timer_time =
- {.it_value = {.tv_sec = 1}, .it_interval = {.tv_sec = 1}};
- struct timer_desirability timer = {};
-
- sigaction(SIGUSR1, &signal_action, NULL);
-#ifdef SIGINFO
- sigaction(SIGINFO, &signal_action, NULL);
-#endif
-
- if ((timer.desired = pa->pa_progress || pa->pa_astitle)) {
- if (timer_create(CLOCK_MONOTONIC, &timer_cfg, &timer.timer))
- return ((void *)(uintptr_t)errno);
- (void) timer_settime(timer.timer, 0, &timer_time, NULL);
- }
- pthread_cleanup_push(timer_delete_cleanup, &timer);
-
- if (!pa->pa_parsable && pa->pa_progress) {
- (void) fprintf(stderr,
- "TIME %s %sSNAPSHOT %s\n",
- pa->pa_estimate ? "BYTES" : " SENT",
- pa->pa_verbosity >= 2 ? " BLOCKS " : "",
- zhp->zfs_name);
- }
-
- /*
- * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
- */
- for (;;) {
- pause();
- if ((err = zfs_send_progress(zhp, pa->pa_fd, &bytes,
- &blocks)) != 0) {
- if (err == EINTR || err == ENOENT)
- err = 0;
- pthread_exit(((void *)(uintptr_t)err));
- }
-
- (void) time(&t);
- localtime_r(&t, &tm);
-
- if (pa->pa_astitle) {
- char buf_bytes[16];
- char buf_size[16];
- int pct;
- zfs_nicenum(bytes, buf_bytes, sizeof (buf_bytes));
- zfs_nicenum(pa->pa_size, buf_size, sizeof (buf_size));
- pct = (total > 0) ? bytes / total : 100;
- zfs_setproctitle("sending %s (%d%%: %s/%s)",
- zhp->zfs_name, MIN(pct, 100), buf_bytes, buf_size);
- }
-
- if (pa->pa_verbosity >= 2 && pa->pa_parsable) {
- (void) fprintf(stderr,
- "%02d:%02d:%02d\t%llu\t%llu\t%s\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- (u_longlong_t)bytes, (u_longlong_t)blocks,
- zhp->zfs_name);
- } else if (pa->pa_verbosity >= 2) {
- zfs_nicenum(bytes, buf, sizeof (buf));
- (void) fprintf(stderr,
- "%02d:%02d:%02d %5s %8llu %s\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- buf, (u_longlong_t)blocks, zhp->zfs_name);
- } else if (pa->pa_parsable) {
- (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- (u_longlong_t)bytes, zhp->zfs_name);
- } else if (pa->pa_progress ||
- !send_progress_thread_signal_duetotimer) {
- zfs_nicebytes(bytes, buf, sizeof (buf));
- (void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- buf, zhp->zfs_name);
- }
- }
- pthread_cleanup_pop(B_TRUE);
- return (NULL);
-}
-
-static boolean_t
-send_progress_thread_exit(
- libzfs_handle_t *hdl, pthread_t ptid, sigset_t *oldmask)
-{
- void *status = NULL;
- (void) pthread_cancel(ptid);
- (void) pthread_join(ptid, &status);
- pthread_sigmask(SIG_SETMASK, oldmask, NULL);
- int error = (int)(uintptr_t)status;
- if (error != 0 && status != PTHREAD_CANCELED)
- return (zfs_standard_error(hdl, error,
- dgettext(TEXT_DOMAIN, "progress thread exited nonzero")));
- else
- return (B_FALSE);
-}
-
-static void
-send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
- uint64_t size, boolean_t parsable)
-{
- if (parsable) {
- if (fromsnap != NULL) {
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "incremental\t%s\t%s"), fromsnap, tosnap);
- } else {
-/*
- * Workaround for GCC 12+ with UBSan enabled deficencies.
- *
- * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code
- * below as violating -Wformat-overflow.
- */
-#if defined(__GNUC__) && !defined(__clang__) && \
- defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-overflow"
-#endif
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "full\t%s"), tosnap);
-#if defined(__GNUC__) && !defined(__clang__) && \
- defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW)
-#pragma GCC diagnostic pop
-#endif
- }
- (void) fprintf(fout, "\t%llu", (longlong_t)size);
- } else {
- if (fromsnap != NULL) {
- if (strchr(fromsnap, '@') == NULL &&
- strchr(fromsnap, '#') == NULL) {
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "send from @%s to %s"), fromsnap, tosnap);
- } else {
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "send from %s to %s"), fromsnap, tosnap);
- }
- } else {
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "full send of %s"), tosnap);
- }
- if (size != 0) {
- char buf[16];
- zfs_nicebytes(size, buf, sizeof (buf));
-/*
- * Workaround for GCC 12+ with UBSan enabled deficencies.
- *
- * GCC 12+ invoked with -fsanitize=undefined incorrectly reports the code
- * below as violating -Wformat-overflow.
- */
-#if defined(__GNUC__) && !defined(__clang__) && \
- defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-overflow"
-#endif
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- " estimated size is %s"), buf);
-#if defined(__GNUC__) && !defined(__clang__) && \
- defined(ZFS_UBSAN_ENABLED) && defined(HAVE_FORMAT_OVERFLOW)
-#pragma GCC diagnostic pop
-#endif
- }
- }
- (void) fprintf(fout, "\n");
-}
-
-/*
- * Send a single filesystem snapshot, updating the send dump data.
- * This interface is intended for use as a zfs_iter_snapshots_v2_sorted visitor.
- */
-static int
-dump_snapshot(zfs_handle_t *zhp, void *arg)
-{
- send_dump_data_t *sdd = arg;
- progress_arg_t pa = { 0 };
- pthread_t tid;
- char *thissnap;
- enum lzc_send_flags flags = 0;
- int err;
- boolean_t isfromsnap, istosnap, fromorigin;
- boolean_t exclude = B_FALSE;
- FILE *fout = sdd->std_out ? stdout : stderr;
-
- err = 0;
- thissnap = strchr(zhp->zfs_name, '@') + 1;
- isfromsnap = (sdd->fromsnap != NULL &&
- strcmp(sdd->fromsnap, thissnap) == 0);
-
- if (!sdd->seenfrom && isfromsnap) {
- gather_holds(zhp, sdd);
- sdd->seenfrom = B_TRUE;
- (void) strlcpy(sdd->prevsnap, thissnap, sizeof (sdd->prevsnap));
- sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
- zfs_close(zhp);
- return (0);
- }
-
- if (sdd->seento || !sdd->seenfrom) {
- zfs_close(zhp);
- return (0);
- }
-
- istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
- if (istosnap)
- sdd->seento = B_TRUE;
-
- if (sdd->large_block)
- flags |= LZC_SEND_FLAG_LARGE_BLOCK;
- if (sdd->embed_data)
- flags |= LZC_SEND_FLAG_EMBED_DATA;
- if (sdd->compress)
- flags |= LZC_SEND_FLAG_COMPRESS;
- if (sdd->raw)
- flags |= LZC_SEND_FLAG_RAW;
-
- if (!sdd->doall && !isfromsnap && !istosnap) {
- if (sdd->replicate) {
- const char *snapname;
- nvlist_t *snapprops;
- /*
- * Filter out all intermediate snapshots except origin
- * snapshots needed to replicate clones.
- */
- nvlist_t *nvfs = fsavl_find(sdd->fsavl,
- zhp->zfs_dmustats.dds_guid, &snapname);
-
- if (nvfs != NULL) {
- snapprops = fnvlist_lookup_nvlist(nvfs,
- "snapprops");
- snapprops = fnvlist_lookup_nvlist(snapprops,
- thissnap);
- exclude = !nvlist_exists(snapprops,
- "is_clone_origin");
- }
- } else {
- exclude = B_TRUE;
- }
- }
-
- /*
- * If a filter function exists, call it to determine whether
- * this snapshot will be sent.
- */
- if (exclude || (sdd->filter_cb != NULL &&
- sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
- /*
- * This snapshot is filtered out. Don't send it, and don't
- * set prevsnap_obj, so it will be as if this snapshot didn't
- * exist, and the next accepted snapshot will be sent as
- * an incremental from the last accepted one, or as the
- * first (and full) snapshot in the case of a replication,
- * non-incremental send.
- */
- zfs_close(zhp);
- return (0);
- }
-
- gather_holds(zhp, sdd);
- fromorigin = sdd->prevsnap[0] == '\0' &&
- (sdd->fromorigin || sdd->replicate);
-
- if (sdd->verbosity != 0) {
- uint64_t size = 0;
- char fromds[ZFS_MAX_DATASET_NAME_LEN];
-
- if (sdd->prevsnap[0] != '\0') {
- (void) strlcpy(fromds, zhp->zfs_name, sizeof (fromds));
- *(strchr(fromds, '@') + 1) = '\0';
- (void) strlcat(fromds, sdd->prevsnap, sizeof (fromds));
- }
- if (zfs_send_space(zhp, zhp->zfs_name,
- sdd->prevsnap[0] ? fromds : NULL, flags, &size) == 0) {
- send_print_verbose(fout, zhp->zfs_name,
- sdd->prevsnap[0] ? sdd->prevsnap : NULL,
- size, sdd->parsable);
- sdd->size += size;
- }
- }
-
- if (!sdd->dryrun) {
- /*
- * If progress reporting is requested, spawn a new thread to
- * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
- */
- sigset_t oldmask;
- {
- pa.pa_zhp = zhp;
- pa.pa_fd = sdd->outfd;
- pa.pa_parsable = sdd->parsable;
- pa.pa_estimate = B_FALSE;
- pa.pa_verbosity = sdd->verbosity;
- pa.pa_size = sdd->size;
- pa.pa_astitle = sdd->progressastitle;
- pa.pa_progress = sdd->progress;
-
- if ((err = pthread_create(&tid, NULL,
- send_progress_thread, &pa)) != 0) {
- zfs_close(zhp);
- return (err);
- }
- SEND_PROGRESS_THREAD_PARENT_BLOCK(&oldmask);
- }
-
- err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
- fromorigin, sdd->outfd, flags, sdd->debugnv);
-
- if (send_progress_thread_exit(zhp->zfs_hdl, tid, &oldmask))
- return (-1);
- }
-
- (void) strlcpy(sdd->prevsnap, thissnap, sizeof (sdd->prevsnap));
- sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
- zfs_close(zhp);
- return (err);
-}
-
-/*
- * Send all snapshots for a filesystem, updating the send dump data.
- */
-static int
-dump_filesystem(zfs_handle_t *zhp, send_dump_data_t *sdd)
-{
- int rv = 0;
- boolean_t missingfrom = B_FALSE;
- zfs_cmd_t zc = {"\0"};
- uint64_t min_txg = 0, max_txg = 0;
-
- /*
- * Make sure the tosnap exists.
- */
- (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
- zhp->zfs_name, sdd->tosnap);
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "WARNING: could not send %s@%s: does not exist\n"),
- zhp->zfs_name, sdd->tosnap);
- sdd->err = B_TRUE;
- return (0);
- }
-
- /*
- * If this fs does not have fromsnap, and we're doing
- * recursive, we need to send a full stream from the
- * beginning (or an incremental from the origin if this
- * is a clone). If we're doing non-recursive, then let
- * them get the error.
- */
- if (sdd->replicate && sdd->fromsnap) {
- /*
- * Make sure the fromsnap exists.
- */
- (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
- zhp->zfs_name, sdd->fromsnap);
- if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0)
- missingfrom = B_TRUE;
- }
-
- sdd->seenfrom = sdd->seento = B_FALSE;
- sdd->prevsnap[0] = '\0';
- sdd->prevsnap_obj = 0;
- if (sdd->fromsnap == NULL || missingfrom)
- sdd->seenfrom = B_TRUE;
-
- /*
- * Iterate through all snapshots and process the ones we will be
- * sending. If we only have a "from" and "to" snapshot to deal
- * with, we can avoid iterating through all the other snapshots.
- */
- if (sdd->doall || sdd->replicate || sdd->tosnap == NULL) {
- if (!sdd->replicate) {
- if (sdd->fromsnap != NULL) {
- min_txg = get_snap_txg(zhp->zfs_hdl,
- zhp->zfs_name, sdd->fromsnap);
- }
- if (sdd->tosnap != NULL) {
- max_txg = get_snap_txg(zhp->zfs_hdl,
- zhp->zfs_name, sdd->tosnap);
- }
- }
- rv = zfs_iter_snapshots_sorted_v2(zhp, 0, dump_snapshot, sdd,
- min_txg, max_txg);
- } else {
- char snapname[MAXPATHLEN] = { 0 };
- zfs_handle_t *snap;
-
- /* Dump fromsnap. */
- if (!sdd->seenfrom) {
- (void) snprintf(snapname, sizeof (snapname),
- "%s@%s", zhp->zfs_name, sdd->fromsnap);
- snap = zfs_open(zhp->zfs_hdl, snapname,
- ZFS_TYPE_SNAPSHOT);
- if (snap != NULL)
- rv = dump_snapshot(snap, sdd);
- else
- rv = errno;
- }
-
- /* Dump tosnap. */
- if (rv == 0) {
- (void) snprintf(snapname, sizeof (snapname),
- "%s@%s", zhp->zfs_name, sdd->tosnap);
- snap = zfs_open(zhp->zfs_hdl, snapname,
- ZFS_TYPE_SNAPSHOT);
- if (snap != NULL)
- rv = dump_snapshot(snap, sdd);
- else
- rv = errno;
- }
- }
-
- if (!sdd->seenfrom) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "WARNING: could not send %s@%s:\n"
- "incremental source (%s@%s) does not exist\n"),
- zhp->zfs_name, sdd->tosnap,
- zhp->zfs_name, sdd->fromsnap);
- sdd->err = B_TRUE;
- } else if (!sdd->seento) {
- if (sdd->fromsnap) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "WARNING: could not send %s@%s:\n"
- "incremental source (%s@%s) "
- "is not earlier than it\n"),
- zhp->zfs_name, sdd->tosnap,
- zhp->zfs_name, sdd->fromsnap);
- } else {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "WARNING: "
- "could not send %s@%s: does not exist\n"),
- zhp->zfs_name, sdd->tosnap);
- }
- sdd->err = B_TRUE;
- }
-
- return (rv);
-}
-
-/*
- * Send all snapshots for all filesystems in sdd.
- */
-static int
-dump_filesystems(zfs_handle_t *rzhp, send_dump_data_t *sdd)
-{
- nvpair_t *fspair;
- boolean_t needagain, progress;
-
- if (!sdd->replicate)
- return (dump_filesystem(rzhp, sdd));
-
- /* Mark the clone origin snapshots. */
- for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
- fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
- nvlist_t *nvfs;
- uint64_t origin_guid = 0;
-
- nvfs = fnvpair_value_nvlist(fspair);
- (void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
- if (origin_guid != 0) {
- const char *snapname;
- nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
- origin_guid, &snapname);
- if (origin_nv != NULL) {
- nvlist_t *snapprops;
- snapprops = fnvlist_lookup_nvlist(origin_nv,
- "snapprops");
- snapprops = fnvlist_lookup_nvlist(snapprops,
- snapname);
- fnvlist_add_boolean(snapprops,
- "is_clone_origin");
- }
- }
- }
-again:
- needagain = progress = B_FALSE;
- for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
- fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
- nvlist_t *fslist, *parent_nv;
- const char *fsname;
- zfs_handle_t *zhp;
- int err;
- uint64_t origin_guid = 0;
- uint64_t parent_guid = 0;
-
- fslist = fnvpair_value_nvlist(fspair);
- if (nvlist_lookup_boolean(fslist, "sent") == 0)
- continue;
-
- fsname = fnvlist_lookup_string(fslist, "name");
- (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
- (void) nvlist_lookup_uint64(fslist, "parentfromsnap",
- &parent_guid);
-
- if (parent_guid != 0) {
- parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
- if (!nvlist_exists(parent_nv, "sent")) {
- /* Parent has not been sent; skip this one. */
- needagain = B_TRUE;
- continue;
- }
- }
-
- if (origin_guid != 0) {
- nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
- origin_guid, NULL);
- if (origin_nv != NULL &&
- !nvlist_exists(origin_nv, "sent")) {
- /*
- * Origin has not been sent yet;
- * skip this clone.
- */
- needagain = B_TRUE;
- continue;
- }
- }
-
- zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
- if (zhp == NULL)
- return (-1);
- err = dump_filesystem(zhp, sdd);
- fnvlist_add_boolean(fslist, "sent");
- progress = B_TRUE;
- zfs_close(zhp);
- if (err)
- return (err);
- }
- if (needagain) {
- assert(progress);
- goto again;
- }
-
- /* Clean out the sent flags in case we reuse this fss. */
- for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
- fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
- nvlist_t *fslist;
-
- fslist = fnvpair_value_nvlist(fspair);
- (void) nvlist_remove_all(fslist, "sent");
- }
-
- return (0);
-}
-
-nvlist_t *
-zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token)
-{
- unsigned int version;
- int nread, i;
- unsigned long long checksum, packed_len;
-
- /*
- * Decode token header, which is:
- * <token version>-<checksum of payload>-<uncompressed payload length>
- * Note that the only supported token version is 1.
- */
- nread = sscanf(token, "%u-%llx-%llx-",
- &version, &checksum, &packed_len);
- if (nread != 3) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt (invalid format)"));
- return (NULL);
- }
-
- if (version != ZFS_SEND_RESUME_TOKEN_VERSION) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt (invalid version %u)"),
- version);
- return (NULL);
- }
-
- /* Convert hexadecimal representation to binary. */
- token = strrchr(token, '-') + 1;
- int len = strlen(token) / 2;
- unsigned char *compressed = zfs_alloc(hdl, len);
- for (i = 0; i < len; i++) {
- nread = sscanf(token + i * 2, "%2hhx", compressed + i);
- if (nread != 1) {
- free(compressed);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt "
- "(payload is not hex-encoded)"));
- return (NULL);
- }
- }
-
- /* Verify checksum. */
- zio_cksum_t cksum;
- fletcher_4_native_varsize(compressed, len, &cksum);
- if (cksum.zc_word[0] != checksum) {
- free(compressed);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt (incorrect checksum)"));
- return (NULL);
- }
-
- /* Uncompress. */
- void *packed = zfs_alloc(hdl, packed_len);
- uLongf packed_len_long = packed_len;
- if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK ||
- packed_len_long != packed_len) {
- free(packed);
- free(compressed);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt (decompression failed)"));
- return (NULL);
- }
-
- /* Unpack nvlist. */
- nvlist_t *nv;
- int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP);
- free(packed);
- free(compressed);
- if (error != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt (nvlist_unpack failed)"));
- return (NULL);
- }
- return (nv);
-}
-
-static enum lzc_send_flags
-lzc_flags_from_sendflags(const sendflags_t *flags)
-{
- enum lzc_send_flags lzc_flags = 0;
-
- if (flags->largeblock)
- lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
- if (flags->embed_data)
- lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
- if (flags->compress)
- lzc_flags |= LZC_SEND_FLAG_COMPRESS;
- if (flags->raw)
- lzc_flags |= LZC_SEND_FLAG_RAW;
- if (flags->saved)
- lzc_flags |= LZC_SEND_FLAG_SAVED;
-
- return (lzc_flags);
-}
-
-static int
-estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
- uint64_t resumeobj, uint64_t resumeoff, uint64_t bytes,
- const char *redactbook, char *errbuf, uint64_t *sizep)
-{
- uint64_t size;
- FILE *fout = flags->dryrun ? stdout : stderr;
- progress_arg_t pa = { 0 };
- int err = 0;
- pthread_t ptid;
- sigset_t oldmask;
-
- {
- pa.pa_zhp = zhp;
- pa.pa_fd = fd;
- pa.pa_parsable = flags->parsable;
- pa.pa_estimate = B_TRUE;
- pa.pa_verbosity = flags->verbosity;
-
- err = pthread_create(&ptid, NULL,
- send_progress_thread, &pa);
- if (err != 0) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno));
- return (zfs_error(zhp->zfs_hdl,
- EZFS_THREADCREATEFAILED, errbuf));
- }
- SEND_PROGRESS_THREAD_PARENT_BLOCK(&oldmask);
- }
-
- err = lzc_send_space_resume_redacted(zhp->zfs_name, from,
- lzc_flags_from_sendflags(flags), resumeobj, resumeoff, bytes,
- redactbook, fd, &size);
- *sizep = size;
-
- if (send_progress_thread_exit(zhp->zfs_hdl, ptid, &oldmask))
- return (-1);
-
- if (!flags->progress && !flags->parsable)
- return (err);
-
- if (err != 0) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(err));
- return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
- errbuf));
- }
- send_print_verbose(fout, zhp->zfs_name, from, size,
- flags->parsable);
-
- if (flags->parsable) {
- (void) fprintf(fout, "size\t%llu\n", (longlong_t)size);
- } else {
- char buf[16];
- zfs_nicenum(size, buf, sizeof (buf));
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "total estimated size is %s\n"), buf);
- }
- return (0);
-}
-
-static boolean_t
-redact_snaps_contains(const uint64_t *snaps, uint64_t num_snaps, uint64_t guid)
-{
- for (int i = 0; i < num_snaps; i++) {
- if (snaps[i] == guid)
- return (B_TRUE);
- }
- return (B_FALSE);
-}
-
-static boolean_t
-redact_snaps_equal(const uint64_t *snaps1, uint64_t num_snaps1,
- const uint64_t *snaps2, uint64_t num_snaps2)
-{
- if (num_snaps1 != num_snaps2)
- return (B_FALSE);
- for (int i = 0; i < num_snaps1; i++) {
- if (!redact_snaps_contains(snaps2, num_snaps2, snaps1[i]))
- return (B_FALSE);
- }
- return (B_TRUE);
-}
-
-static int
-get_bookmarks(const char *path, nvlist_t **bmarksp)
-{
- nvlist_t *props = fnvlist_alloc();
- int error;
-
- fnvlist_add_boolean(props, "redact_complete");
- fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
- error = lzc_get_bookmarks(path, props, bmarksp);
- fnvlist_free(props);
- return (error);
-}
-
-static nvpair_t *
-find_redact_pair(nvlist_t *bmarks, const uint64_t *redact_snap_guids,
- int num_redact_snaps)
-{
- nvpair_t *pair;
-
- for (pair = nvlist_next_nvpair(bmarks, NULL); pair;
- pair = nvlist_next_nvpair(bmarks, pair)) {
-
- nvlist_t *bmark = fnvpair_value_nvlist(pair);
- nvlist_t *vallist = fnvlist_lookup_nvlist(bmark,
- zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
- uint_t len = 0;
- uint64_t *bmarksnaps = fnvlist_lookup_uint64_array(vallist,
- ZPROP_VALUE, &len);
- if (redact_snaps_equal(redact_snap_guids,
- num_redact_snaps, bmarksnaps, len)) {
- break;
- }
- }
- return (pair);
-}
-
-static boolean_t
-get_redact_complete(nvpair_t *pair)
-{
- nvlist_t *bmark = fnvpair_value_nvlist(pair);
- nvlist_t *vallist = fnvlist_lookup_nvlist(bmark, "redact_complete");
- boolean_t complete = fnvlist_lookup_boolean_value(vallist,
- ZPROP_VALUE);
-
- return (complete);
-}
-
-/*
- * Check that the list of redaction snapshots in the bookmark matches the send
- * we're resuming, and return whether or not it's complete.
- *
- * Note that the caller needs to free the contents of *bookname with free() if
- * this function returns successfully.
- */
-static int
-find_redact_book(libzfs_handle_t *hdl, const char *path,
- const uint64_t *redact_snap_guids, int num_redact_snaps,
- char **bookname)
-{
- char errbuf[ERRBUFLEN];
- nvlist_t *bmarks;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot resume send"));
-
- int error = get_bookmarks(path, &bmarks);
- if (error != 0) {
- if (error == ESRCH) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "nonexistent redaction bookmark provided"));
- } else if (error == ENOENT) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset to be sent no longer exists"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "unknown error: %s"), zfs_strerror(error));
- }
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
- nvpair_t *pair = find_redact_pair(bmarks, redact_snap_guids,
- num_redact_snaps);
- if (pair == NULL) {
- fnvlist_free(bmarks);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "no appropriate redaction bookmark exists"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
- boolean_t complete = get_redact_complete(pair);
- if (!complete) {
- fnvlist_free(bmarks);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incomplete redaction bookmark provided"));
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
- }
- *bookname = strndup(nvpair_name(pair), ZFS_MAX_DATASET_NAME_LEN);
- ASSERT3P(*bookname, !=, NULL);
- fnvlist_free(bmarks);
- return (0);
-}
-
-static enum lzc_send_flags
-lzc_flags_from_resume_nvl(nvlist_t *resume_nvl)
-{
- enum lzc_send_flags lzc_flags = 0;
-
- if (nvlist_exists(resume_nvl, "largeblockok"))
- lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
- if (nvlist_exists(resume_nvl, "embedok"))
- lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
- if (nvlist_exists(resume_nvl, "compressok"))
- lzc_flags |= LZC_SEND_FLAG_COMPRESS;
- if (nvlist_exists(resume_nvl, "rawok"))
- lzc_flags |= LZC_SEND_FLAG_RAW;
- if (nvlist_exists(resume_nvl, "savedok"))
- lzc_flags |= LZC_SEND_FLAG_SAVED;
-
- return (lzc_flags);
-}
-
-static int
-zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
- int outfd, nvlist_t *resume_nvl)
-{
- char errbuf[ERRBUFLEN];
- const char *toname;
- const char *fromname = NULL;
- uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
- zfs_handle_t *zhp;
- int error = 0;
- char name[ZFS_MAX_DATASET_NAME_LEN];
- FILE *fout = (flags->verbosity > 0 && flags->dryrun) ? stdout : stderr;
- uint64_t *redact_snap_guids = NULL;
- int num_redact_snaps = 0;
- char *redact_book = NULL;
- uint64_t size = 0;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot resume send"));
-
- if (flags->verbosity != 0) {
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "resume token contents:\n"));
- nvlist_print(fout, resume_nvl);
- }
-
- if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "resume token is corrupt"));
- return (zfs_error(hdl, EZFS_FAULT, errbuf));
- }
- fromguid = 0;
- (void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);
-
- if (flags->saved) {
- (void) strlcpy(name, toname, sizeof (name));
- } else {
- error = guid_to_name(hdl, toname, toguid, B_FALSE, name);
- if (error != 0) {
- if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is no longer the same snapshot "
- "used in the initial send"), toname);
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' used in the initial send no "
- "longer exists"), toname);
- }
- return (zfs_error(hdl, EZFS_BADPATH, errbuf));
- }
- }
-
- zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "unable to access '%s'"), name);
- return (zfs_error(hdl, EZFS_BADPATH, errbuf));
- }
-
- if (nvlist_lookup_uint64_array(resume_nvl, "book_redact_snaps",
- &redact_snap_guids, (uint_t *)&num_redact_snaps) != 0) {
- num_redact_snaps = -1;
- }
-
- if (fromguid != 0) {
- if (guid_to_name_redact_snaps(hdl, toname, fromguid, B_TRUE,
- redact_snap_guids, num_redact_snaps, name) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source %#llx no longer exists"),
- (longlong_t)fromguid);
- return (zfs_error(hdl, EZFS_BADPATH, errbuf));
- }
- fromname = name;
- }
-
- redact_snap_guids = NULL;
-
- if (nvlist_lookup_uint64_array(resume_nvl,
- zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &redact_snap_guids,
- (uint_t *)&num_redact_snaps) == 0) {
- char path[ZFS_MAX_DATASET_NAME_LEN];
-
- (void) strlcpy(path, toname, sizeof (path));
- char *at = strchr(path, '@');
- ASSERT3P(at, !=, NULL);
-
- *at = '\0';
-
- if ((error = find_redact_book(hdl, path, redact_snap_guids,
- num_redact_snaps, &redact_book)) != 0) {
- return (error);
- }
- }
-
- enum lzc_send_flags lzc_flags = lzc_flags_from_sendflags(flags) |
- lzc_flags_from_resume_nvl(resume_nvl);
-
- if (flags->verbosity != 0 || flags->progressastitle) {
- /*
- * Some of these may have come from the resume token, set them
- * here for size estimate purposes.
- */
- sendflags_t tmpflags = *flags;
- if (lzc_flags & LZC_SEND_FLAG_LARGE_BLOCK)
- tmpflags.largeblock = B_TRUE;
- if (lzc_flags & LZC_SEND_FLAG_COMPRESS)
- tmpflags.compress = B_TRUE;
- if (lzc_flags & LZC_SEND_FLAG_EMBED_DATA)
- tmpflags.embed_data = B_TRUE;
- if (lzc_flags & LZC_SEND_FLAG_RAW)
- tmpflags.raw = B_TRUE;
- if (lzc_flags & LZC_SEND_FLAG_SAVED)
- tmpflags.saved = B_TRUE;
- error = estimate_size(zhp, fromname, outfd, &tmpflags,
- resumeobj, resumeoff, bytes, redact_book, errbuf, &size);
- }
-
- if (!flags->dryrun) {
- progress_arg_t pa = { 0 };
- pthread_t tid;
- sigset_t oldmask;
- /*
- * If progress reporting is requested, spawn a new thread to
- * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
- */
- {
- pa.pa_zhp = zhp;
- pa.pa_fd = outfd;
- pa.pa_parsable = flags->parsable;
- pa.pa_estimate = B_FALSE;
- pa.pa_verbosity = flags->verbosity;
- pa.pa_size = size;
- pa.pa_astitle = flags->progressastitle;
- pa.pa_progress = flags->progress;
-
- error = pthread_create(&tid, NULL,
- send_progress_thread, &pa);
- if (error != 0) {
- if (redact_book != NULL)
- free(redact_book);
- zfs_close(zhp);
- return (error);
- }
- SEND_PROGRESS_THREAD_PARENT_BLOCK(&oldmask);
- }
-
- error = lzc_send_resume_redacted(zhp->zfs_name, fromname, outfd,
- lzc_flags, resumeobj, resumeoff, redact_book);
- if (redact_book != NULL)
- free(redact_book);
-
- if (send_progress_thread_exit(hdl, tid, &oldmask)) {
- zfs_close(zhp);
- return (-1);
- }
-
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot send '%s'"), zhp->zfs_name);
-
- zfs_close(zhp);
-
- switch (error) {
- case 0:
- return (0);
- case EACCES:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "source key must be loaded"));
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
- case ESRCH:
- if (lzc_exists(zhp->zfs_name)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source could not be found"));
- }
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
-
- case EXDEV:
- case ENOENT:
- case EDQUOT:
- case EFBIG:
- case EIO:
- case ENOLINK:
- case ENOSPC:
- case ENOSTR:
- case ENXIO:
- case EPIPE:
- case ERANGE:
- case EFAULT:
- case EROFS:
- zfs_error_aux(hdl, "%s", zfs_strerror(errno));
- return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
-
- default:
- return (zfs_standard_error(hdl, errno, errbuf));
- }
- } else {
- if (redact_book != NULL)
- free(redact_book);
- }
-
- zfs_close(zhp);
-
- return (error);
-}
-
-struct zfs_send_resume_impl {
- libzfs_handle_t *hdl;
- sendflags_t *flags;
- nvlist_t *resume_nvl;
-};
-
-static int
-zfs_send_resume_impl_cb(int outfd, void *arg)
-{
- struct zfs_send_resume_impl *zsri = arg;
- return (zfs_send_resume_impl_cb_impl(zsri->hdl, zsri->flags, outfd,
- zsri->resume_nvl));
-}
-
-static int
-zfs_send_resume_impl(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
- nvlist_t *resume_nvl)
-{
- struct zfs_send_resume_impl zsri = {
- .hdl = hdl,
- .flags = flags,
- .resume_nvl = resume_nvl,
- };
- return (lzc_send_wrapper(zfs_send_resume_impl_cb, outfd, &zsri));
-}
-
-int
-zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
- const char *resume_token)
-{
- int ret;
- char errbuf[ERRBUFLEN];
- nvlist_t *resume_nvl;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot resume send"));
-
- resume_nvl = zfs_send_resume_token_to_nvlist(hdl, resume_token);
- if (resume_nvl == NULL) {
- /*
- * zfs_error_aux has already been set by
- * zfs_send_resume_token_to_nvlist()
- */
- return (zfs_error(hdl, EZFS_FAULT, errbuf));
- }
-
- ret = zfs_send_resume_impl(hdl, flags, outfd, resume_nvl);
- fnvlist_free(resume_nvl);
-
- return (ret);
-}
-
-int
-zfs_send_saved(zfs_handle_t *zhp, sendflags_t *flags, int outfd,
- const char *resume_token)
-{
- int ret;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- nvlist_t *saved_nvl = NULL, *resume_nvl = NULL;
- uint64_t saved_guid = 0, resume_guid = 0;
- uint64_t obj = 0, off = 0, bytes = 0;
- char token_buf[ZFS_MAXPROPLEN];
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "saved send failed"));
-
- ret = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
- token_buf, sizeof (token_buf), NULL, NULL, 0, B_TRUE);
- if (ret != 0)
- goto out;
-
- saved_nvl = zfs_send_resume_token_to_nvlist(hdl, token_buf);
- if (saved_nvl == NULL) {
- /*
- * zfs_error_aux has already been set by
- * zfs_send_resume_token_to_nvlist()
- */
- ret = zfs_error(hdl, EZFS_FAULT, errbuf);
- goto out;
- }
-
- /*
- * If a resume token is provided we use the object and offset
- * from that instead of the default, which starts from the
- * beginning.
- */
- if (resume_token != NULL) {
- resume_nvl = zfs_send_resume_token_to_nvlist(hdl,
- resume_token);
- if (resume_nvl == NULL) {
- ret = zfs_error(hdl, EZFS_FAULT, errbuf);
- goto out;
- }
-
- if (nvlist_lookup_uint64(resume_nvl, "object", &obj) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "offset", &off) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
- nvlist_lookup_uint64(resume_nvl, "toguid",
- &resume_guid) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "provided resume token is corrupt"));
- ret = zfs_error(hdl, EZFS_FAULT, errbuf);
- goto out;
- }
-
- if (nvlist_lookup_uint64(saved_nvl, "toguid",
- &saved_guid)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset's resume token is corrupt"));
- ret = zfs_error(hdl, EZFS_FAULT, errbuf);
- goto out;
- }
-
- if (resume_guid != saved_guid) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "provided resume token does not match dataset"));
- ret = zfs_error(hdl, EZFS_BADBACKUP, errbuf);
- goto out;
- }
- }
-
- (void) nvlist_remove_all(saved_nvl, "object");
- fnvlist_add_uint64(saved_nvl, "object", obj);
-
- (void) nvlist_remove_all(saved_nvl, "offset");
- fnvlist_add_uint64(saved_nvl, "offset", off);
-
- (void) nvlist_remove_all(saved_nvl, "bytes");
- fnvlist_add_uint64(saved_nvl, "bytes", bytes);
-
- (void) nvlist_remove_all(saved_nvl, "toname");
- fnvlist_add_string(saved_nvl, "toname", zhp->zfs_name);
-
- ret = zfs_send_resume_impl(hdl, flags, outfd, saved_nvl);
-
-out:
- fnvlist_free(saved_nvl);
- fnvlist_free(resume_nvl);
- return (ret);
-}
-
-/*
- * This function informs the target system that the recursive send is complete.
- * The record is also expected in the case of a send -p.
- */
-static int
-send_conclusion_record(int fd, zio_cksum_t *zc)
-{
- dmu_replay_record_t drr;
- memset(&drr, 0, sizeof (dmu_replay_record_t));
- drr.drr_type = DRR_END;
- if (zc != NULL)
- drr.drr_u.drr_end.drr_checksum = *zc;
- if (write(fd, &drr, sizeof (drr)) == -1) {
- return (errno);
- }
- return (0);
-}
-
-/*
- * This function is responsible for sending the records that contain the
- * necessary information for the target system's libzfs to be able to set the
- * properties of the filesystem being received, or to be able to prepare for
- * a recursive receive.
- *
- * The "zhp" argument is the handle of the snapshot we are sending
- * (the "tosnap"). The "from" argument is the short snapshot name (the part
- * after the @) of the incremental source.
- */
-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 skipmissing,
- boolean_t backup, boolean_t holds, boolean_t props, boolean_t doall,
- nvlist_t **fssp, avl_tree_t **fsavlp)
-{
- int err = 0;
- char *packbuf = NULL;
- size_t buflen = 0;
- zio_cksum_t zc = { {0} };
- int featureflags = 0;
- /* name of filesystem/volume that contains snapshot we are sending */
- char tofs[ZFS_MAX_DATASET_NAME_LEN];
- /* short name of snap we are sending */
- const char *tosnap = "";
-
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot send '%s'"), zhp->zfs_name);
- if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM && zfs_prop_get_int(zhp,
- ZFS_PROP_VERSION) >= ZPL_VERSION_SA) {
- featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
- }
-
- if (holds)
- featureflags |= DMU_BACKUP_FEATURE_HOLDS;
-
- (void) strlcpy(tofs, zhp->zfs_name, ZFS_MAX_DATASET_NAME_LEN);
- char *at = strchr(tofs, '@');
- if (at != NULL) {
- *at = '\0';
- tosnap = at + 1;
- }
-
- if (gather_props) {
- nvlist_t *hdrnv = fnvlist_alloc();
- nvlist_t *fss = NULL;
-
- if (from != NULL)
- fnvlist_add_string(hdrnv, "fromsnap", from);
- fnvlist_add_string(hdrnv, "tosnap", tosnap);
- if (!recursive)
- fnvlist_add_boolean(hdrnv, "not_recursive");
-
- if (raw) {
- fnvlist_add_boolean(hdrnv, "raw");
- }
-
- if (gather_nvlist(zhp->zfs_hdl, tofs,
- from, tosnap, recursive, raw, doall, replicate, skipmissing,
- verbose, backup, holds, props, &fss, fsavlp) != 0) {
- return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
- errbuf));
- }
- /*
- * Do not allow the size of the properties list to exceed
- * the limit
- */
- if ((fnvlist_size(fss) + fnvlist_size(hdrnv)) >
- zhp->zfs_hdl->libzfs_max_nvlist) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "warning: cannot send '%s': "
- "the size of the list of snapshots and properties "
- "is too large to be received successfully.\n"
- "Select a smaller number of snapshots to send.\n"),
- zhp->zfs_name);
- return (zfs_error(zhp->zfs_hdl, EZFS_NOSPC,
- errbuf));
- }
- fnvlist_add_nvlist(hdrnv, "fss", fss);
- VERIFY0(nvlist_pack(hdrnv, &packbuf, &buflen, NV_ENCODE_XDR,
- 0));
- if (fssp != NULL) {
- *fssp = fss;
- } else {
- fnvlist_free(fss);
- }
- fnvlist_free(hdrnv);
- }
-
- if (!dryrun) {
- dmu_replay_record_t drr;
- memset(&drr, 0, sizeof (dmu_replay_record_t));
- /* write first begin record */
- drr.drr_type = DRR_BEGIN;
- drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
- DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
- drr_versioninfo, DMU_COMPOUNDSTREAM);
- DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
- drr_versioninfo, featureflags);
- if (snprintf(drr.drr_u.drr_begin.drr_toname,
- sizeof (drr.drr_u.drr_begin.drr_toname), "%s@%s", tofs,
- tosnap) >= sizeof (drr.drr_u.drr_begin.drr_toname)) {
- return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
- errbuf));
- }
- drr.drr_payloadlen = buflen;
-
- err = dump_record(&drr, packbuf, buflen, &zc, fd);
- free(packbuf);
- if (err != 0) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_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, "%s", zfs_strerror(err));
- return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
- errbuf));
- }
- }
- return (0);
-}
-
-/*
- * Generate a send stream. The "zhp" argument is the filesystem/volume
- * that contains the snapshot to send. The "fromsnap" argument is the
- * short name (the part after the '@') of the snapshot that is the
- * incremental source to send from (if non-NULL). The "tosnap" argument
- * is the short name of the snapshot to send.
- *
- * The content of the send stream is the snapshot identified by
- * 'tosnap'. Incremental streams are requested in two ways:
- * - from the snapshot identified by "fromsnap" (if non-null) or
- * - from the origin of the dataset identified by zhp, which must
- * be a clone. In this case, "fromsnap" is null and "fromorigin"
- * is TRUE.
- *
- * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
- * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
- * if "replicate" is set. If "doall" is set, dump all the intermediate
- * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
- * case too. If "props" is set, send properties.
- *
- * Pre-wrapped (cf. lzc_send_wrapper()).
- */
-static int
-zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
- sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
- void *cb_arg, nvlist_t **debugnvp)
-{
- char errbuf[ERRBUFLEN];
- send_dump_data_t sdd = { 0 };
- int err = 0;
- nvlist_t *fss = NULL;
- avl_tree_t *fsavl = NULL;
- static uint64_t holdseq;
- int spa_version;
- FILE *fout;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot send '%s'"), zhp->zfs_name);
-
- if (fromsnap && fromsnap[0] == '\0') {
- zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
- "zero-length incremental source"));
- return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
- }
-
- if (fromsnap) {
- char full_fromsnap_name[ZFS_MAX_DATASET_NAME_LEN];
- if (snprintf(full_fromsnap_name, sizeof (full_fromsnap_name),
- "%s@%s", zhp->zfs_name, fromsnap) >=
- sizeof (full_fromsnap_name)) {
- err = EINVAL;
- goto stderr_out;
- }
- zfs_handle_t *fromsnapn = zfs_open(zhp->zfs_hdl,
- full_fromsnap_name, ZFS_TYPE_SNAPSHOT);
- if (fromsnapn == NULL) {
- err = -1;
- goto err_out;
- }
- zfs_close(fromsnapn);
- }
-
- if (flags->replicate || flags->doall || flags->props ||
- flags->holds || flags->backup) {
- char full_tosnap_name[ZFS_MAX_DATASET_NAME_LEN];
- if (snprintf(full_tosnap_name, sizeof (full_tosnap_name),
- "%s@%s", zhp->zfs_name, tosnap) >=
- sizeof (full_tosnap_name)) {
- err = EINVAL;
- goto stderr_out;
- }
- zfs_handle_t *tosnap = zfs_open(zhp->zfs_hdl,
- full_tosnap_name, ZFS_TYPE_SNAPSHOT);
- if (tosnap == NULL) {
- err = -1;
- goto err_out;
- }
- 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->skipmissing,
- flags->backup, flags->holds, flags->props, flags->doall,
- &fss, &fsavl);
- zfs_close(tosnap);
- if (err != 0)
- goto err_out;
- }
-
- /* dump each stream */
- sdd.fromsnap = fromsnap;
- sdd.tosnap = tosnap;
- sdd.outfd = outfd;
- sdd.replicate = flags->replicate;
- sdd.doall = flags->doall;
- sdd.fromorigin = flags->fromorigin;
- sdd.fss = fss;
- sdd.fsavl = fsavl;
- sdd.verbosity = flags->verbosity;
- sdd.parsable = flags->parsable;
- sdd.progress = flags->progress;
- sdd.progressastitle = flags->progressastitle;
- sdd.dryrun = flags->dryrun;
- sdd.large_block = flags->largeblock;
- sdd.embed_data = flags->embed_data;
- sdd.compress = flags->compress;
- sdd.raw = flags->raw;
- sdd.holds = flags->holds;
- sdd.filter_cb = filter_func;
- sdd.filter_cb_arg = cb_arg;
- if (debugnvp)
- sdd.debugnv = *debugnvp;
- if (sdd.verbosity != 0 && sdd.dryrun)
- sdd.std_out = B_TRUE;
- fout = sdd.std_out ? stdout : stderr;
-
- /*
- * Some flags require that we place user holds on the datasets that are
- * being sent so they don't get destroyed during the send. We can skip
- * this step if the pool is imported read-only since the datasets cannot
- * be destroyed.
- */
- if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
- ZPOOL_PROP_READONLY, NULL) &&
- zfs_spa_version(zhp, &spa_version) == 0 &&
- spa_version >= SPA_VERSION_USERREFS &&
- (flags->doall || flags->replicate)) {
- ++holdseq;
- (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
- ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
- sdd.cleanup_fd = open(ZFS_DEV, O_RDWR | O_CLOEXEC);
- if (sdd.cleanup_fd < 0) {
- err = errno;
- goto stderr_out;
- }
- sdd.snapholds = fnvlist_alloc();
- } else {
- sdd.cleanup_fd = -1;
- sdd.snapholds = NULL;
- }
-
- if (flags->verbosity != 0 || sdd.snapholds != NULL) {
- /*
- * Do a verbose no-op dry run to get all the verbose output
- * or to gather snapshot hold's before generating any data,
- * then do a non-verbose real run to generate the streams.
- */
- sdd.dryrun = B_TRUE;
- err = dump_filesystems(zhp, &sdd);
-
- if (err != 0)
- goto stderr_out;
-
- if (flags->verbosity != 0) {
- if (flags->parsable) {
- (void) fprintf(fout, "size\t%llu\n",
- (longlong_t)sdd.size);
- } else {
- char buf[16];
- zfs_nicebytes(sdd.size, buf, sizeof (buf));
- (void) fprintf(fout, dgettext(TEXT_DOMAIN,
- "total estimated size is %s\n"), buf);
- }
- }
-
- /* Ensure no snaps found is treated as an error. */
- if (!sdd.seento) {
- err = ENOENT;
- goto err_out;
- }
-
- /* Skip the second run if dryrun was requested. */
- if (flags->dryrun)
- goto err_out;
-
- if (sdd.snapholds != NULL) {
- err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
- if (err != 0)
- goto stderr_out;
-
- fnvlist_free(sdd.snapholds);
- sdd.snapholds = NULL;
- }
-
- sdd.dryrun = B_FALSE;
- sdd.verbosity = 0;
- }
-
- err = dump_filesystems(zhp, &sdd);
- fsavl_destroy(fsavl);
- fnvlist_free(fss);
-
- /* Ensure no snaps found is treated as an error. */
- if (err == 0 && !sdd.seento)
- err = ENOENT;
-
- if (sdd.cleanup_fd != -1) {
- VERIFY0(close(sdd.cleanup_fd));
- sdd.cleanup_fd = -1;
- }
-
- if (!flags->dryrun && (flags->replicate || flags->doall ||
- flags->props || flags->backup || flags->holds)) {
- /*
- * write final end record. NB: want to do this even if
- * there was some error, because it might not be totally
- * failed.
- */
- int err2 = send_conclusion_record(outfd, NULL);
- if (err2 != 0)
- return (zfs_standard_error(zhp->zfs_hdl, err2, errbuf));
- }
-
- return (err || sdd.err);
-
-stderr_out:
- err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
-err_out:
- fsavl_destroy(fsavl);
- fnvlist_free(fss);
- fnvlist_free(sdd.snapholds);
-
- if (sdd.cleanup_fd != -1)
- VERIFY0(close(sdd.cleanup_fd));
- return (err);
-}
-
-struct zfs_send {
- zfs_handle_t *zhp;
- const char *fromsnap;
- const char *tosnap;
- sendflags_t *flags;
- snapfilter_cb_t *filter_func;
- void *cb_arg;
- nvlist_t **debugnvp;
-};
-
-static int
-zfs_send_cb(int outfd, void *arg)
-{
- struct zfs_send *zs = arg;
- return (zfs_send_cb_impl(zs->zhp, zs->fromsnap, zs->tosnap, zs->flags,
- outfd, zs->filter_func, zs->cb_arg, zs->debugnvp));
-}
-
-int
-zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
- sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
- void *cb_arg, nvlist_t **debugnvp)
-{
- struct zfs_send arg = {
- .zhp = zhp,
- .fromsnap = fromsnap,
- .tosnap = tosnap,
- .flags = flags,
- .filter_func = filter_func,
- .cb_arg = cb_arg,
- .debugnvp = debugnvp,
- };
- return (lzc_send_wrapper(zfs_send_cb, outfd, &arg));
-}
-
-
-static zfs_handle_t *
-name_to_dir_handle(libzfs_handle_t *hdl, const char *snapname)
-{
- char dirname[ZFS_MAX_DATASET_NAME_LEN];
- (void) strlcpy(dirname, snapname, ZFS_MAX_DATASET_NAME_LEN);
- char *c = strchr(dirname, '@');
- if (c != NULL)
- *c = '\0';
- return (zfs_open(hdl, dirname, ZFS_TYPE_DATASET));
-}
-
-/*
- * Returns B_TRUE if earlier is an earlier snapshot in later's timeline; either
- * an earlier snapshot in the same filesystem, or a snapshot before later's
- * origin, or it's origin's origin, etc.
- */
-static boolean_t
-snapshot_is_before(zfs_handle_t *earlier, zfs_handle_t *later)
-{
- boolean_t ret;
- uint64_t later_txg =
- (later->zfs_type == ZFS_TYPE_FILESYSTEM ||
- later->zfs_type == ZFS_TYPE_VOLUME ?
- UINT64_MAX : zfs_prop_get_int(later, ZFS_PROP_CREATETXG));
- uint64_t earlier_txg = zfs_prop_get_int(earlier, ZFS_PROP_CREATETXG);
-
- if (earlier_txg >= later_txg)
- return (B_FALSE);
-
- zfs_handle_t *earlier_dir = name_to_dir_handle(earlier->zfs_hdl,
- earlier->zfs_name);
- zfs_handle_t *later_dir = name_to_dir_handle(later->zfs_hdl,
- later->zfs_name);
-
- if (strcmp(earlier_dir->zfs_name, later_dir->zfs_name) == 0) {
- zfs_close(earlier_dir);
- zfs_close(later_dir);
- return (B_TRUE);
- }
-
- char clonename[ZFS_MAX_DATASET_NAME_LEN];
- if (zfs_prop_get(later_dir, ZFS_PROP_ORIGIN, clonename,
- ZFS_MAX_DATASET_NAME_LEN, NULL, NULL, 0, B_TRUE) != 0) {
- zfs_close(earlier_dir);
- zfs_close(later_dir);
- return (B_FALSE);
- }
-
- zfs_handle_t *origin = zfs_open(earlier->zfs_hdl, clonename,
- ZFS_TYPE_DATASET);
- uint64_t origin_txg = zfs_prop_get_int(origin, ZFS_PROP_CREATETXG);
-
- /*
- * If "earlier" is exactly the origin, then
- * snapshot_is_before(earlier, origin) will return false (because
- * they're the same).
- */
- if (origin_txg == earlier_txg &&
- strcmp(origin->zfs_name, earlier->zfs_name) == 0) {
- zfs_close(earlier_dir);
- zfs_close(later_dir);
- zfs_close(origin);
- return (B_TRUE);
- }
- zfs_close(earlier_dir);
- zfs_close(later_dir);
-
- ret = snapshot_is_before(earlier, origin);
- zfs_close(origin);
- return (ret);
-}
-
-/*
- * The "zhp" argument is the handle of the dataset to send (typically a
- * snapshot). The "from" argument is the full name of the snapshot or
- * bookmark that is the incremental source.
- *
- * Pre-wrapped (cf. lzc_send_wrapper()).
- */
-static int
-zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
- sendflags_t *flags, const char *redactbook)
-{
- int err;
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- char *name = zhp->zfs_name;
- pthread_t ptid;
- progress_arg_t pa = { 0 };
- uint64_t size = 0;
-
- char errbuf[ERRBUFLEN];
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "warning: cannot send '%s'"), name);
-
- if (from != NULL && strchr(from, '@')) {
- zfs_handle_t *from_zhp = zfs_open(hdl, from,
- ZFS_TYPE_DATASET);
- if (from_zhp == NULL)
- return (-1);
- if (!snapshot_is_before(from_zhp, zhp)) {
- zfs_close(from_zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not an earlier snapshot from the same fs"));
- return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
- }
- zfs_close(from_zhp);
- }
-
- if (redactbook != NULL) {
- char bookname[ZFS_MAX_DATASET_NAME_LEN];
- nvlist_t *redact_snaps;
- zfs_handle_t *book_zhp;
- char *at, *pound;
- int dsnamelen;
-
- pound = strchr(redactbook, '#');
- if (pound != NULL)
- redactbook = pound + 1;
- at = strchr(name, '@');
- if (at == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot do a redacted send to a filesystem"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- }
- dsnamelen = at - name;
- if (snprintf(bookname, sizeof (bookname), "%.*s#%s",
- dsnamelen, name, redactbook)
- >= sizeof (bookname)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid bookmark name"));
- return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
- }
- book_zhp = zfs_open(hdl, bookname, ZFS_TYPE_BOOKMARK);
- if (book_zhp == NULL)
- return (-1);
- if (nvlist_lookup_nvlist(book_zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS),
- &redact_snaps) != 0 || redact_snaps == NULL) {
- zfs_close(book_zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not a redaction bookmark"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- }
- zfs_close(book_zhp);
- }
-
- /*
- * Send fs properties
- */
- if (flags->props || flags->holds || flags->backup) {
- /*
- * Note: the header generated by send_prelim_records()
- * assumes that the incremental source is in the same
- * filesystem/volume as the target (which is a requirement
- * when doing "zfs send -R"). But that isn't always the
- * case here (e.g. send from snap in origin, or send from
- * bookmark). We pass from=NULL, which will omit this
- * information from the prelim records; it isn't used
- * when receiving this type of stream.
- */
- err = send_prelim_records(zhp, NULL, fd, B_TRUE, B_FALSE,
- flags->verbosity > 0, flags->dryrun, flags->raw,
- flags->replicate, B_FALSE, flags->backup, flags->holds,
- flags->props, flags->doall, NULL, NULL);
- if (err != 0)
- return (err);
- }
-
- /*
- * Perform size estimate if verbose was specified.
- */
- if (flags->verbosity != 0 || flags->progressastitle) {
- err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
- errbuf, &size);
- if (err != 0)
- return (err);
- }
-
- if (flags->dryrun)
- return (0);
-
- /*
- * If progress reporting is requested, spawn a new thread to poll
- * ZFS_IOC_SEND_PROGRESS at a regular interval.
- */
- sigset_t oldmask;
- {
- pa.pa_zhp = zhp;
- pa.pa_fd = fd;
- pa.pa_parsable = flags->parsable;
- pa.pa_estimate = B_FALSE;
- pa.pa_verbosity = flags->verbosity;
- pa.pa_size = size;
- pa.pa_astitle = flags->progressastitle;
- pa.pa_progress = flags->progress;
-
- err = pthread_create(&ptid, NULL,
- send_progress_thread, &pa);
- if (err != 0) {
- zfs_error_aux(zhp->zfs_hdl, "%s", zfs_strerror(errno));
- return (zfs_error(zhp->zfs_hdl,
- EZFS_THREADCREATEFAILED, errbuf));
- }
- SEND_PROGRESS_THREAD_PARENT_BLOCK(&oldmask);
- }
-
- err = lzc_send_redacted(name, from, fd,
- lzc_flags_from_sendflags(flags), redactbook);
-
- if (send_progress_thread_exit(hdl, ptid, &oldmask))
- return (-1);
-
- if (err == 0 && (flags->props || flags->holds || flags->backup)) {
- /* Write the final end record. */
- err = send_conclusion_record(fd, NULL);
- if (err != 0)
- return (zfs_standard_error(hdl, err, errbuf));
- }
- if (err != 0) {
- switch (errno) {
- case EXDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "not an earlier snapshot from the same fs"));
- return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
-
- case ENOENT:
- case ESRCH:
- if (lzc_exists(name)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental source (%s) does not exist"),
- from);
- }
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
-
- case EACCES:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset key must be loaded"));
- return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
-
- case EBUSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "target is busy; if a filesystem, "
- "it must not be mounted"));
- return (zfs_error(hdl, EZFS_BUSY, errbuf));
-
- case EDQUOT:
- case EFAULT:
- case EFBIG:
- case EINVAL:
- case EIO:
- case ENOLINK:
- case ENOSPC:
- case ENOSTR:
- case ENXIO:
- case EPIPE:
- case ERANGE:
- case EROFS:
- zfs_error_aux(hdl, "%s", zfs_strerror(errno));
- return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
- case ZFS_ERR_STREAM_LARGE_MICROZAP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "source snapshot contains large microzaps, "
- "need -L (--large-block) or -w (--raw) to "
- "generate stream"));
- return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
- default:
- return (zfs_standard_error(hdl, errno, errbuf));
- }
- }
- return (err != 0);
-}
-
-struct zfs_send_one {
- zfs_handle_t *zhp;
- const char *from;
- sendflags_t *flags;
- const char *redactbook;
-};
-
-static int
-zfs_send_one_cb(int fd, void *arg)
-{
- struct zfs_send_one *zso = arg;
- return (zfs_send_one_cb_impl(zso->zhp, zso->from, fd, zso->flags,
- zso->redactbook));
-}
-
-int
-zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
- const char *redactbook)
-{
- struct zfs_send_one zso = {
- .zhp = zhp,
- .from = from,
- .flags = flags,
- .redactbook = redactbook,
- };
- return (lzc_send_wrapper(zfs_send_one_cb, fd, &zso));
-}
-
-/*
- * Routines specific to "zfs recv"
- */
-
-static int
-recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
- boolean_t byteswap, zio_cksum_t *zc)
-{
- char *cp = buf;
- int rv;
- int len = ilen;
-
- do {
- rv = read(fd, cp, len);
- cp += rv;
- len -= rv;
- } while (rv > 0);
-
- if (rv < 0 || len != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "failed to read from stream"));
- return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
- "cannot receive")));
- }
-
- if (zc) {
- if (byteswap)
- fletcher_4_incremental_byteswap(buf, ilen, zc);
- else
- fletcher_4_incremental_native(buf, ilen, zc);
- }
- return (0);
-}
-
-static int
-recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
- boolean_t byteswap, zio_cksum_t *zc)
-{
- char *buf;
- int err;
-
- buf = zfs_alloc(hdl, len);
-
- if (len > hdl->libzfs_max_nvlist) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "nvlist too large"));
- free(buf);
- return (ENOMEM);
- }
-
- err = recv_read(hdl, fd, buf, len, byteswap, zc);
- if (err != 0) {
- free(buf);
- return (err);
- }
-
- err = nvlist_unpack(buf, len, nvp, 0);
- free(buf);
- if (err != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
- "stream (malformed nvlist)"));
- return (EINVAL);
- }
- return (0);
-}
-
-/*
- * Returns the grand origin (origin of origin of origin...) of a given handle.
- * If this dataset is not a clone, it simply returns a copy of the original
- * handle.
- */
-static zfs_handle_t *
-recv_open_grand_origin(zfs_handle_t *zhp)
-{
- char origin[ZFS_MAX_DATASET_NAME_LEN];
- zprop_source_t src;
- zfs_handle_t *ozhp = zfs_handle_dup(zhp);
-
- while (ozhp != NULL) {
- if (zfs_prop_get(ozhp, ZFS_PROP_ORIGIN, origin,
- sizeof (origin), &src, NULL, 0, B_FALSE) != 0)
- break;
-
- (void) zfs_close(ozhp);
- ozhp = zfs_open(zhp->zfs_hdl, origin, ZFS_TYPE_FILESYSTEM);
- }
-
- return (ozhp);
-}
-
-static int
-recv_rename_impl(zfs_handle_t *zhp, const char *name, const char *newname)
-{
- int err;
- zfs_handle_t *ozhp = NULL;
-
- /*
- * Attempt to rename the dataset. If it fails with EACCES we have
- * attempted to rename the dataset outside of its encryption root.
- * Force the dataset to become an encryption root and try again.
- */
- err = lzc_rename(name, newname);
- if (err == EACCES) {
- ozhp = recv_open_grand_origin(zhp);
- if (ozhp == NULL) {
- err = ENOENT;
- goto out;
- }
-
- err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
- NULL, NULL, 0);
- if (err != 0)
- goto out;
-
- err = lzc_rename(name, newname);
- }
-
-out:
- if (ozhp != NULL)
- zfs_close(ozhp);
- return (err);
-}
-
-static int
-recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
- int baselen, char *newname, recvflags_t *flags)
-{
- static int seq;
- int err;
- prop_changelist_t *clp = NULL;
- zfs_handle_t *zhp = NULL;
-
- zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- err = -1;
- goto out;
- }
- clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
- flags->force ? MS_FORCE : 0);
- if (clp == NULL) {
- err = -1;
- goto out;
- }
- err = changelist_prefix(clp);
- if (err)
- goto out;
-
- if (tryname) {
- (void) strlcpy(newname, tryname, ZFS_MAX_DATASET_NAME_LEN);
- if (flags->verbose) {
- (void) printf("attempting rename %s to %s\n",
- name, newname);
- }
- err = recv_rename_impl(zhp, name, newname);
- if (err == 0)
- changelist_rename(clp, name, tryname);
- } else {
- err = ENOENT;
- }
-
- if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
- seq++;
-
- (void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
- "%.*srecv-%u-%u", baselen, name, getpid(), seq);
-
- if (flags->verbose) {
- (void) printf("failed - trying rename %s to %s\n",
- name, newname);
- }
- err = recv_rename_impl(zhp, name, newname);
- if (err == 0)
- changelist_rename(clp, name, newname);
- if (err && flags->verbose) {
- (void) printf("failed (%u) - "
- "will try again on next pass\n", errno);
- }
- err = EAGAIN;
- } else if (flags->verbose) {
- if (err == 0)
- (void) printf("success\n");
- else
- (void) printf("failed (%u)\n", errno);
- }
-
- (void) changelist_postfix(clp);
-
-out:
- if (clp != NULL)
- changelist_free(clp);
- if (zhp != NULL)
- zfs_close(zhp);
-
- return (err);
-}
-
-static int
-recv_promote(libzfs_handle_t *hdl, const char *fsname,
- const char *origin_fsname, recvflags_t *flags)
-{
- int err;
- zfs_cmd_t zc = {"\0"};
- zfs_handle_t *zhp = NULL, *ozhp = NULL;
-
- if (flags->verbose)
- (void) printf("promoting %s\n", fsname);
-
- (void) strlcpy(zc.zc_value, origin_fsname, sizeof (zc.zc_value));
- (void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));
-
- /*
- * Attempt to promote the dataset. If it fails with EACCES the
- * promotion would cause this dataset to leave its encryption root.
- * Force the origin to become an encryption root and try again.
- */
- err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
- if (err == EACCES) {
- zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- err = -1;
- goto out;
- }
-
- ozhp = recv_open_grand_origin(zhp);
- if (ozhp == NULL) {
- err = -1;
- goto out;
- }
-
- err = lzc_change_key(ozhp->zfs_name, DCP_CMD_FORCE_NEW_KEY,
- NULL, NULL, 0);
- if (err != 0)
- goto out;
-
- err = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
- }
-
-out:
- if (zhp != NULL)
- zfs_close(zhp);
- if (ozhp != NULL)
- zfs_close(ozhp);
-
- return (err);
-}
-
-static int
-recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
- char *newname, recvflags_t *flags)
-{
- int err = 0;
- prop_changelist_t *clp;
- zfs_handle_t *zhp;
- boolean_t defer = B_FALSE;
- int spa_version;
-
- zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
- if (zhp == NULL)
- return (-1);
- zfs_type_t type = zfs_get_type(zhp);
- if (type == ZFS_TYPE_SNAPSHOT &&
- zfs_spa_version(zhp, &spa_version) == 0 &&
- spa_version >= SPA_VERSION_USERREFS)
- defer = B_TRUE;
- clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
- flags->force ? MS_FORCE : 0);
- zfs_close(zhp);
- if (clp == NULL)
- return (-1);
-
- err = changelist_prefix(clp);
- if (err)
- return (err);
-
- if (flags->verbose)
- (void) printf("attempting destroy %s\n", name);
- if (type == ZFS_TYPE_SNAPSHOT) {
- nvlist_t *nv = fnvlist_alloc();
- fnvlist_add_boolean(nv, name);
- err = lzc_destroy_snaps(nv, defer, NULL);
- fnvlist_free(nv);
- } else {
- err = lzc_destroy(name);
- }
- if (err == 0) {
- if (flags->verbose)
- (void) printf("success\n");
- changelist_remove(clp, name);
- }
-
- (void) changelist_postfix(clp);
- changelist_free(clp);
-
- /*
- * Deferred destroy might destroy the snapshot or only mark it to be
- * destroyed later, and it returns success in either case.
- */
- if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
- ZFS_TYPE_SNAPSHOT))) {
- err = recv_rename(hdl, name, NULL, baselen, newname, flags);
- }
-
- return (err);
-}
-
-typedef struct guid_to_name_data {
- uint64_t guid;
- boolean_t bookmark_ok;
- char *name;
- char *skip;
- uint64_t *redact_snap_guids;
- uint64_t num_redact_snaps;
-} guid_to_name_data_t;
-
-static boolean_t
-redact_snaps_match(zfs_handle_t *zhp, guid_to_name_data_t *gtnd)
-{
- uint64_t *bmark_snaps;
- uint_t bmark_num_snaps;
- nvlist_t *nvl;
- if (zhp->zfs_type != ZFS_TYPE_BOOKMARK)
- return (B_FALSE);
-
- nvl = fnvlist_lookup_nvlist(zhp->zfs_props,
- zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS));
- bmark_snaps = fnvlist_lookup_uint64_array(nvl, ZPROP_VALUE,
- &bmark_num_snaps);
- if (bmark_num_snaps != gtnd->num_redact_snaps)
- return (B_FALSE);
- int i = 0;
- for (; i < bmark_num_snaps; i++) {
- int j = 0;
- for (; j < bmark_num_snaps; j++) {
- if (bmark_snaps[i] == gtnd->redact_snap_guids[j])
- break;
- }
- if (j == bmark_num_snaps)
- break;
- }
- return (i == bmark_num_snaps);
-}
-
-static int
-guid_to_name_cb(zfs_handle_t *zhp, void *arg)
-{
- guid_to_name_data_t *gtnd = arg;
- const char *slash;
- int err;
-
- if (gtnd->skip != NULL &&
- (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
- strcmp(slash + 1, gtnd->skip) == 0) {
- zfs_close(zhp);
- return (0);
- }
-
- if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid &&
- (gtnd->num_redact_snaps == -1 || redact_snaps_match(zhp, gtnd))) {
- (void) strcpy(gtnd->name, zhp->zfs_name);
- zfs_close(zhp);
- return (EEXIST);
- }
-
- err = zfs_iter_children_v2(zhp, 0, guid_to_name_cb, gtnd);
- if (err != EEXIST && gtnd->bookmark_ok)
- err = zfs_iter_bookmarks_v2(zhp, 0, guid_to_name_cb, gtnd);
- zfs_close(zhp);
- return (err);
-}
-
-/*
- * Attempt to find the local dataset associated with this guid. In the case of
- * multiple matches, we attempt to find the "best" match by searching
- * progressively larger portions of the hierarchy. This allows one to send a
- * tree of datasets individually and guarantee that we will find the source
- * guid within that hierarchy, even if there are multiple matches elsewhere.
- *
- * If num_redact_snaps is not -1, we attempt to find a redaction bookmark with
- * the specified number of redaction snapshots. If num_redact_snaps isn't 0 or
- * -1, then redact_snap_guids will be an array of the guids of the snapshots the
- * redaction bookmark was created with. If num_redact_snaps is -1, then we will
- * attempt to find a snapshot or bookmark (if bookmark_ok is passed) with the
- * given guid. Note that a redaction bookmark can be returned if
- * num_redact_snaps == -1.
- */
-static int
-guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
- uint64_t guid, boolean_t bookmark_ok, uint64_t *redact_snap_guids,
- uint64_t num_redact_snaps, char *name)
-{
- char pname[ZFS_MAX_DATASET_NAME_LEN];
- guid_to_name_data_t gtnd;
-
- gtnd.guid = guid;
- gtnd.bookmark_ok = bookmark_ok;
- gtnd.name = name;
- gtnd.skip = NULL;
- gtnd.redact_snap_guids = redact_snap_guids;
- gtnd.num_redact_snaps = num_redact_snaps;
-
- /*
- * Search progressively larger portions of the hierarchy, starting
- * with the filesystem specified by 'parent'. This will
- * select the "most local" version of the origin snapshot in the case
- * that there are multiple matching snapshots in the system.
- */
- (void) strlcpy(pname, parent, sizeof (pname));
- char *cp = strrchr(pname, '@');
- if (cp == NULL)
- cp = strchr(pname, '\0');
- for (; cp != NULL; cp = strrchr(pname, '/')) {
- /* Chop off the last component and open the parent */
- *cp = '\0';
- zfs_handle_t *zhp = make_dataset_handle(hdl, pname);
-
- if (zhp == NULL)
- continue;
- int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
- if (err != EEXIST)
- err = zfs_iter_children_v2(zhp, 0, guid_to_name_cb,
- &gtnd);
- if (err != EEXIST && bookmark_ok)
- err = zfs_iter_bookmarks_v2(zhp, 0, guid_to_name_cb,
- &gtnd);
- zfs_close(zhp);
- if (err == EEXIST)
- return (0);
-
- /*
- * Remember the last portion of the dataset so we skip it next
- * time through (as we've already searched that portion of the
- * hierarchy).
- */
- gtnd.skip = strrchr(pname, '/') + 1;
- }
-
- return (ENOENT);
-}
-
-static int
-guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
- boolean_t bookmark_ok, char *name)
-{
- return (guid_to_name_redact_snaps(hdl, parent, guid, bookmark_ok, NULL,
- -1, name));
-}
-
-/*
- * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
- * guid1 is after guid2.
- */
-static int
-created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
- uint64_t guid1, uint64_t guid2)
-{
- nvlist_t *nvfs;
- const char *fsname = NULL, *snapname = NULL;
- char buf[ZFS_MAX_DATASET_NAME_LEN];
- int rv;
- zfs_handle_t *guid1hdl, *guid2hdl;
- uint64_t create1, create2;
-
- if (guid2 == 0)
- return (0);
- if (guid1 == 0)
- return (1);
-
- nvfs = fsavl_find(avl, guid1, &snapname);
- fsname = fnvlist_lookup_string(nvfs, "name");
- (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
- guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
- if (guid1hdl == NULL)
- return (-1);
-
- nvfs = fsavl_find(avl, guid2, &snapname);
- fsname = fnvlist_lookup_string(nvfs, "name");
- (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
- guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
- if (guid2hdl == NULL) {
- zfs_close(guid1hdl);
- return (-1);
- }
-
- create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
- create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
-
- if (create1 < create2)
- rv = -1;
- else if (create1 > create2)
- rv = +1;
- else
- rv = 0;
-
- zfs_close(guid1hdl);
- zfs_close(guid2hdl);
-
- return (rv);
-}
-
-/*
- * This function reestablishes the hierarchy of encryption roots after a
- * recursive incremental receive has completed. This must be done after the
- * second call to recv_incremental_replication() has renamed and promoted all
- * sent datasets to their final locations in the dataset hierarchy.
- */
-static int
-recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *top_zfs,
- nvlist_t *stream_nv, avl_tree_t *stream_avl)
-{
- int err;
- nvpair_t *fselem = NULL;
- nvlist_t *local_nv;
- avl_tree_t *local_avl;
- boolean_t recursive;
-
- recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
- ENOENT);
-
- /* Using top_zfs, gather the nvlists for all local filesystems. */
- if ((err = gather_nvlist(hdl, top_zfs, NULL, NULL,
- recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
- B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
- return (err);
-
- /*
- * Go through the nvlists of the local filesystems and check for
- * encryption roots.
- */
- while ((fselem = nvlist_next_nvpair(local_nv, fselem)) != NULL) {
- zfs_handle_t *zhp = NULL;
- uint64_t crypt;
- nvlist_t *stream_props, *snaps, *stream_nvfs = NULL,
- *nvfs = NULL;
- boolean_t is_encroot, is_clone, stream_encroot;
- const char *stream_keylocation = NULL, *fsname;
- char keylocation[MAXNAMELEN];
- nvpair_t *snapelem;
-
- nvfs = fnvpair_value_nvlist(fselem);
- snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
- fsname = fnvlist_lookup_string(nvfs, "name");
- zhp = zfs_open(hdl, fsname, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- err = ENOENT;
- goto error;
- }
-
- /* we don't need to do anything for unencrypted datasets */
- crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
- if (crypt == ZIO_CRYPT_OFF) {
- zfs_close(zhp);
- continue;
- }
-
- is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
- (void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
- keylocation[0] = '\0';
-
- /*
- * Go through the snapshots of the local filesystem and find
- * the stream's filesystem.
- */
- for (snapelem = nvlist_next_nvpair(snaps, NULL);
- snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
- uint64_t thisguid;
-
- thisguid = fnvpair_value_uint64(snapelem);
- stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
-
- if (stream_nvfs != NULL)
- break;
- }
-
- if (stream_nvfs == NULL)
- continue;
-
- stream_props = fnvlist_lookup_nvlist(stream_nvfs, "props");
- stream_encroot = nvlist_exists(stream_nvfs, "is_encroot");
-
- /*
- * If the dataset is flagged as an encryption root, was not
- * received as a clone and is not currently an encryption root,
- * force it to become one. Fixup the keylocation if necessary.
- */
- if (stream_encroot) {
- if (!is_clone && !is_encroot) {
- err = lzc_change_key(fsname,
- DCP_CMD_FORCE_NEW_KEY, NULL, NULL, 0);
- if (err != 0) {
- zfs_close(zhp);
- goto error;
- }
- }
-
- stream_keylocation = fnvlist_lookup_string(stream_props,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
-
- /*
- * Refresh the properties in case the call to
- * lzc_change_key() changed the value.
- */
- zfs_refresh_properties(zhp);
- err = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
- keylocation, sizeof (keylocation), NULL, NULL,
- 0, B_TRUE);
- if (err != 0) {
- zfs_close(zhp);
- goto error;
- }
-
- if (strcmp(keylocation, stream_keylocation) != 0) {
- err = zfs_prop_set(zhp,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
- stream_keylocation);
- if (err != 0) {
- zfs_close(zhp);
- goto error;
- }
- }
- }
-
- /*
- * If the dataset is not flagged as an encryption root and is
- * currently an encryption root, force it to inherit from its
- * parent. The root of a raw send should never be
- * force-inherited.
- */
- if (!stream_encroot && is_encroot &&
- strcmp(top_zfs, fsname) != 0) {
- err = lzc_change_key(fsname, DCP_CMD_FORCE_INHERIT,
- NULL, NULL, 0);
- if (err != 0) {
- zfs_close(zhp);
- goto error;
- }
- }
-
- zfs_close(zhp);
- }
-
- return (0);
-
-error:
- return (err);
-}
-
-static int
-recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
- recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
- nvlist_t *renamed)
-{
- nvlist_t *local_nv, *deleted = NULL;
- avl_tree_t *local_avl;
- nvpair_t *fselem, *nextfselem;
- const char *fromsnap;
- char newname[ZFS_MAX_DATASET_NAME_LEN];
- char guidname[32];
- int error;
- boolean_t needagain, progress, recursive;
- const char *s1, *s2;
-
- if (flags->dryrun)
- return (0);
-
- fromsnap = fnvlist_lookup_string(stream_nv, "fromsnap");
-
- recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
- ENOENT);
-
-again:
- needagain = progress = B_FALSE;
-
- deleted = fnvlist_alloc();
-
- if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
- recursive, B_TRUE, B_FALSE, recursive, B_FALSE, B_FALSE, B_FALSE,
- B_FALSE, B_TRUE, &local_nv, &local_avl)) != 0)
- return (error);
-
- /*
- * Process deletes and renames
- */
- for (fselem = nvlist_next_nvpair(local_nv, NULL);
- fselem; fselem = nextfselem) {
- nvlist_t *nvfs, *snaps;
- nvlist_t *stream_nvfs = NULL;
- nvpair_t *snapelem, *nextsnapelem;
- uint64_t fromguid = 0;
- uint64_t originguid = 0;
- uint64_t stream_originguid = 0;
- uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
- const char *fsname, *stream_fsname;
-
- nextfselem = nvlist_next_nvpair(local_nv, fselem);
-
- nvfs = fnvpair_value_nvlist(fselem);
- snaps = fnvlist_lookup_nvlist(nvfs, "snaps");
- fsname = fnvlist_lookup_string(nvfs, "name");
- parent_fromsnap_guid = fnvlist_lookup_uint64(nvfs,
- "parentfromsnap");
- (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
-
- /*
- * First find the stream's fs, so we can check for
- * a different origin (due to "zfs promote")
- */
- for (snapelem = nvlist_next_nvpair(snaps, NULL);
- snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
- uint64_t thisguid;
-
- thisguid = fnvpair_value_uint64(snapelem);
- stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
-
- if (stream_nvfs != NULL)
- break;
- }
-
- /* check for promote */
- (void) nvlist_lookup_uint64(stream_nvfs, "origin",
- &stream_originguid);
- if (stream_nvfs && originguid != stream_originguid) {
- switch (created_before(hdl, local_avl,
- stream_originguid, originguid)) {
- case 1: {
- /* promote it! */
- nvlist_t *origin_nvfs;
- const char *origin_fsname;
-
- origin_nvfs = fsavl_find(local_avl, originguid,
- NULL);
- origin_fsname = fnvlist_lookup_string(
- origin_nvfs, "name");
- error = recv_promote(hdl, fsname, origin_fsname,
- flags);
- if (error == 0)
- progress = B_TRUE;
- break;
- }
- default:
- break;
- case -1:
- fsavl_destroy(local_avl);
- fnvlist_free(local_nv);
- return (-1);
- }
- /*
- * We had/have the wrong origin, therefore our
- * list of snapshots is wrong. Need to handle
- * them on the next pass.
- */
- needagain = B_TRUE;
- continue;
- }
-
- for (snapelem = nvlist_next_nvpair(snaps, NULL);
- snapelem; snapelem = nextsnapelem) {
- uint64_t thisguid;
- const char *stream_snapname;
- nvlist_t *found, *props;
-
- nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
-
- thisguid = fnvpair_value_uint64(snapelem);
- found = fsavl_find(stream_avl, thisguid,
- &stream_snapname);
-
- /* check for delete */
- if (found == NULL) {
- char name[ZFS_MAX_DATASET_NAME_LEN];
-
- if (!flags->force)
- continue;
-
- (void) snprintf(name, sizeof (name), "%s@%s",
- fsname, nvpair_name(snapelem));
-
- error = recv_destroy(hdl, name,
- strlen(fsname)+1, newname, flags);
- if (error)
- needagain = B_TRUE;
- else
- progress = B_TRUE;
- sprintf(guidname, "%llu",
- (u_longlong_t)thisguid);
- nvlist_add_boolean(deleted, guidname);
- continue;
- }
-
- stream_nvfs = found;
-
- if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
- &props) && 0 == nvlist_lookup_nvlist(props,
- stream_snapname, &props)) {
- zfs_cmd_t zc = {"\0"};
-
- zc.zc_cookie = B_TRUE; /* received */
- (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
- "%s@%s", fsname, nvpair_name(snapelem));
- zcmd_write_src_nvlist(hdl, &zc, props);
- (void) zfs_ioctl(hdl,
- ZFS_IOC_SET_PROP, &zc);
- zcmd_free_nvlists(&zc);
- }
-
- /* check for different snapname */
- if (strcmp(nvpair_name(snapelem),
- stream_snapname) != 0) {
- char name[ZFS_MAX_DATASET_NAME_LEN];
- char tryname[ZFS_MAX_DATASET_NAME_LEN];
-
- (void) snprintf(name, sizeof (name), "%s@%s",
- fsname, nvpair_name(snapelem));
- (void) snprintf(tryname, sizeof (name), "%s@%s",
- fsname, stream_snapname);
-
- error = recv_rename(hdl, name, tryname,
- strlen(fsname)+1, newname, flags);
- if (error)
- needagain = B_TRUE;
- else
- progress = B_TRUE;
- }
-
- if (strcmp(stream_snapname, fromsnap) == 0)
- fromguid = thisguid;
- }
-
- /* check for delete */
- if (stream_nvfs == NULL) {
- if (!flags->force)
- continue;
-
- error = recv_destroy(hdl, fsname, strlen(tofs)+1,
- newname, flags);
- if (error)
- needagain = B_TRUE;
- else
- progress = B_TRUE;
- sprintf(guidname, "%llu",
- (u_longlong_t)parent_fromsnap_guid);
- nvlist_add_boolean(deleted, guidname);
- continue;
- }
-
- if (fromguid == 0) {
- if (flags->verbose) {
- (void) printf("local fs %s does not have "
- "fromsnap (%s in stream); must have "
- "been deleted locally; ignoring\n",
- fsname, fromsnap);
- }
- continue;
- }
-
- stream_fsname = fnvlist_lookup_string(stream_nvfs, "name");
- stream_parent_fromsnap_guid = fnvlist_lookup_uint64(
- stream_nvfs, "parentfromsnap");
-
- s1 = strrchr(fsname, '/');
- s2 = strrchr(stream_fsname, '/');
-
- /*
- * Check if we're going to rename based on parent guid change
- * and the current parent guid was also deleted. If it was then
- * rename will fail and is likely unneeded, so avoid this and
- * force an early retry to determine the new
- * parent_fromsnap_guid.
- */
- if (stream_parent_fromsnap_guid != 0 &&
- parent_fromsnap_guid != 0 &&
- stream_parent_fromsnap_guid != parent_fromsnap_guid) {
- sprintf(guidname, "%llu",
- (u_longlong_t)parent_fromsnap_guid);
- if (nvlist_exists(deleted, guidname)) {
- progress = B_TRUE;
- needagain = B_TRUE;
- goto doagain;
- }
- }
-
- /*
- * Check for rename. If the exact receive path is specified, it
- * does not count as a rename, but we still need to check the
- * datasets beneath it.
- */
- if ((stream_parent_fromsnap_guid != 0 &&
- parent_fromsnap_guid != 0 &&
- stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
- ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
- (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
- nvlist_t *parent;
- char tryname[ZFS_MAX_DATASET_NAME_LEN];
-
- parent = fsavl_find(local_avl,
- stream_parent_fromsnap_guid, NULL);
- /*
- * NB: parent might not be found if we used the
- * tosnap for stream_parent_fromsnap_guid,
- * because the parent is a newly-created fs;
- * we'll be able to rename it after we recv the
- * new fs.
- */
- if (parent != NULL) {
- const char *pname;
-
- pname = fnvlist_lookup_string(parent, "name");
- (void) snprintf(tryname, sizeof (tryname),
- "%s%s", pname, strrchr(stream_fsname, '/'));
- } else {
- tryname[0] = '\0';
- if (flags->verbose) {
- (void) printf("local fs %s new parent "
- "not found\n", fsname);
- }
- }
-
- newname[0] = '\0';
-
- error = recv_rename(hdl, fsname, tryname,
- strlen(tofs)+1, newname, flags);
-
- if (renamed != NULL && newname[0] != '\0') {
- fnvlist_add_boolean(renamed, newname);
- }
-
- if (error)
- needagain = B_TRUE;
- else
- progress = B_TRUE;
- }
- }
-
-doagain:
- fsavl_destroy(local_avl);
- fnvlist_free(local_nv);
- fnvlist_free(deleted);
-
- if (needagain && progress) {
- /* do another pass to fix up temporary names */
- if (flags->verbose)
- (void) printf("another pass:\n");
- goto again;
- }
-
- return (needagain || error != 0);
-}
-
-static int
-zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
- recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
- char **top_zfs, nvlist_t *cmdprops)
-{
- nvlist_t *stream_nv = NULL;
- avl_tree_t *stream_avl = NULL;
- const char *fromsnap = NULL;
- const char *sendsnap = NULL;
- char *cp;
- char tofs[ZFS_MAX_DATASET_NAME_LEN];
- char sendfs[ZFS_MAX_DATASET_NAME_LEN];
- char errbuf[ERRBUFLEN];
- dmu_replay_record_t drre;
- int error;
- boolean_t anyerr = B_FALSE;
- boolean_t softerr = B_FALSE;
- boolean_t recursive, raw;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot receive"));
-
- assert(drr->drr_type == DRR_BEGIN);
- assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
- assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
- DMU_COMPOUNDSTREAM);
-
- /*
- * Read in the nvlist from the stream.
- */
- if (drr->drr_payloadlen != 0) {
- error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
- &stream_nv, flags->byteswap, zc);
- if (error) {
- error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
- }
-
- recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
- ENOENT);
- raw = (nvlist_lookup_boolean(stream_nv, "raw") == 0);
-
- if (recursive && strchr(destname, '@')) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot specify snapshot name for multi-snapshot stream"));
- error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
-
- /*
- * Read in the end record and verify checksum.
- */
- if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
- flags->byteswap, NULL)))
- goto out;
- if (flags->byteswap) {
- drre.drr_type = BSWAP_32(drre.drr_type);
- drre.drr_u.drr_end.drr_checksum.zc_word[0] =
- BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
- drre.drr_u.drr_end.drr_checksum.zc_word[1] =
- BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
- drre.drr_u.drr_end.drr_checksum.zc_word[2] =
- BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
- drre.drr_u.drr_end.drr_checksum.zc_word[3] =
- BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
- }
- if (drre.drr_type != DRR_END) {
- error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
- if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incorrect header checksum"));
- error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
-
- (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
-
- if (drr->drr_payloadlen != 0) {
- nvlist_t *stream_fss;
-
- stream_fss = fnvlist_lookup_nvlist(stream_nv, "fss");
- if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "couldn't allocate avl tree"));
- error = zfs_error(hdl, EZFS_NOMEM, errbuf);
- goto out;
- }
-
- if (fromsnap != NULL && recursive) {
- nvlist_t *renamed = NULL;
- nvpair_t *pair = NULL;
-
- (void) strlcpy(tofs, destname, sizeof (tofs));
- if (flags->isprefix) {
- struct drr_begin *drrb = &drr->drr_u.drr_begin;
- int i;
-
- if (flags->istail) {
- cp = strrchr(drrb->drr_toname, '/');
- if (cp == NULL) {
- (void) strlcat(tofs, "/",
- sizeof (tofs));
- i = 0;
- } else {
- i = (cp - drrb->drr_toname);
- }
- } else {
- i = strcspn(drrb->drr_toname, "/@");
- }
- /* zfs_receive_one() will create_parents() */
- (void) strlcat(tofs, &drrb->drr_toname[i],
- sizeof (tofs));
- *strchr(tofs, '@') = '\0';
- }
-
- if (!flags->dryrun && !flags->nomount) {
- renamed = fnvlist_alloc();
- }
-
- softerr = recv_incremental_replication(hdl, tofs, flags,
- stream_nv, stream_avl, renamed);
-
- /* Unmount renamed filesystems before receiving. */
- while ((pair = nvlist_next_nvpair(renamed,
- pair)) != NULL) {
- zfs_handle_t *zhp;
- prop_changelist_t *clp = NULL;
-
- zhp = zfs_open(hdl, nvpair_name(pair),
- ZFS_TYPE_FILESYSTEM);
- if (zhp != NULL) {
- clp = changelist_gather(zhp,
- ZFS_PROP_MOUNTPOINT, 0,
- flags->forceunmount ? MS_FORCE : 0);
- zfs_close(zhp);
- if (clp != NULL) {
- softerr |=
- changelist_prefix(clp);
- changelist_free(clp);
- }
- }
- }
-
- fnvlist_free(renamed);
- }
- }
-
- /*
- * Get the fs specified by the first path in the stream (the top level
- * specified by 'zfs send') and pass it to each invocation of
- * zfs_receive_one().
- */
- (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
- sizeof (sendfs));
- if ((cp = strchr(sendfs, '@')) != NULL) {
- *cp = '\0';
- /*
- * Find the "sendsnap", the final snapshot in a replication
- * stream. zfs_receive_one() handles certain errors
- * differently, depending on if the contained stream is the
- * last one or not.
- */
- sendsnap = (cp + 1);
- }
-
- /* Finally, receive each contained stream */
- do {
- /*
- * we should figure out if it has a recoverable
- * error, in which case do a recv_skip() and drive on.
- * Note, if we fail due to already having this guid,
- * zfs_receive_one() will take care of it (ie,
- * recv_skip() and return 0).
- */
- error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
- sendfs, stream_nv, stream_avl, top_zfs, sendsnap, cmdprops);
- if (error == ENODATA) {
- error = 0;
- break;
- }
- anyerr |= error;
- } while (error == 0);
-
- if (drr->drr_payloadlen != 0 && recursive && fromsnap != NULL) {
- /*
- * Now that we have the fs's they sent us, try the
- * renames again.
- */
- softerr = recv_incremental_replication(hdl, tofs, flags,
- stream_nv, stream_avl, NULL);
- }
-
- if (raw && *top_zfs != NULL && !flags->dryrun) {
- softerr = recv_fix_encryption_hierarchy(hdl, *top_zfs,
- stream_nv, stream_avl);
- }
-
-out:
- fsavl_destroy(stream_avl);
- fnvlist_free(stream_nv);
- if (softerr)
- error = -2;
- if (anyerr)
- error = -1;
- return (error);
-}
-
-static void
-trunc_prop_errs(int truncated)
-{
- ASSERT(truncated != 0);
-
- if (truncated == 1)
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "1 more property could not be set\n"));
- else
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
- "%d more properties could not be set\n"), truncated);
-}
-
-static int
-recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
-{
- dmu_replay_record_t *drr;
- void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
- uint64_t payload_size;
- char errbuf[ERRBUFLEN];
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot receive"));
-
- /* XXX would be great to use lseek if possible... */
- drr = buf;
-
- while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
- byteswap, NULL) == 0) {
- if (byteswap)
- drr->drr_type = BSWAP_32(drr->drr_type);
-
- switch (drr->drr_type) {
- case DRR_BEGIN:
- if (drr->drr_payloadlen != 0) {
- (void) recv_read(hdl, fd, buf,
- drr->drr_payloadlen, B_FALSE, NULL);
- }
- break;
-
- case DRR_END:
- free(buf);
- return (0);
-
- case DRR_OBJECT:
- if (byteswap) {
- drr->drr_u.drr_object.drr_bonuslen =
- BSWAP_32(drr->drr_u.drr_object.
- drr_bonuslen);
- drr->drr_u.drr_object.drr_raw_bonuslen =
- BSWAP_32(drr->drr_u.drr_object.
- drr_raw_bonuslen);
- }
-
- payload_size =
- DRR_OBJECT_PAYLOAD_SIZE(&drr->drr_u.drr_object);
- (void) recv_read(hdl, fd, buf, payload_size,
- B_FALSE, NULL);
- break;
-
- case DRR_WRITE:
- if (byteswap) {
- drr->drr_u.drr_write.drr_logical_size =
- BSWAP_64(
- drr->drr_u.drr_write.drr_logical_size);
- drr->drr_u.drr_write.drr_compressed_size =
- BSWAP_64(
- drr->drr_u.drr_write.drr_compressed_size);
- }
- payload_size =
- DRR_WRITE_PAYLOAD_SIZE(&drr->drr_u.drr_write);
- assert(payload_size <= SPA_MAXBLOCKSIZE);
- (void) recv_read(hdl, fd, buf,
- payload_size, B_FALSE, NULL);
- break;
- case DRR_SPILL:
- if (byteswap) {
- drr->drr_u.drr_spill.drr_length =
- BSWAP_64(drr->drr_u.drr_spill.drr_length);
- drr->drr_u.drr_spill.drr_compressed_size =
- BSWAP_64(drr->drr_u.drr_spill.
- drr_compressed_size);
- }
-
- payload_size =
- DRR_SPILL_PAYLOAD_SIZE(&drr->drr_u.drr_spill);
- (void) recv_read(hdl, fd, buf, payload_size,
- B_FALSE, NULL);
- break;
- case DRR_WRITE_EMBEDDED:
- if (byteswap) {
- drr->drr_u.drr_write_embedded.drr_psize =
- BSWAP_32(drr->drr_u.drr_write_embedded.
- drr_psize);
- }
- (void) recv_read(hdl, fd, buf,
- P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
- 8), B_FALSE, NULL);
- break;
- case DRR_OBJECT_RANGE:
- case DRR_WRITE_BYREF:
- case DRR_FREEOBJECTS:
- case DRR_FREE:
- break;
-
- default:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid record type"));
- free(buf);
- return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
- }
- }
-
- free(buf);
- return (-1);
-}
-
-static void
-recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
- boolean_t resumable, boolean_t checksum)
-{
- char target_fs[ZFS_MAX_DATASET_NAME_LEN];
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, (checksum ?
- "checksum mismatch" : "incomplete stream")));
-
- if (!resumable)
- return;
- (void) strlcpy(target_fs, target_snap, sizeof (target_fs));
- *strchr(target_fs, '@') = '\0';
- zfs_handle_t *zhp = zfs_open(hdl, target_fs,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL)
- return;
-
- char token_buf[ZFS_MAXPROPLEN];
- int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
- token_buf, sizeof (token_buf),
- NULL, NULL, 0, B_TRUE);
- if (error == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "checksum mismatch or incomplete stream.\n"
- "Partially received snapshot is saved.\n"
- "A resuming stream can be generated on the sending "
- "system by running:\n"
- " zfs send -t %s"),
- token_buf);
- }
- zfs_close(zhp);
-}
-
-/*
- * Prepare a new nvlist of properties that are to override (-o) or be excluded
- * (-x) from the received dataset
- * recvprops: received properties from the send stream
- * cmdprops: raw input properties from command line
- * origprops: properties, both locally-set and received, currently set on the
- * target dataset if it exists, NULL otherwise.
- * oxprops: valid output override (-o) and excluded (-x) properties
- */
-static int
-zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
- char *fsname, boolean_t zoned, boolean_t recursive, boolean_t newfs,
- boolean_t raw, boolean_t toplevel, nvlist_t *recvprops, nvlist_t *cmdprops,
- nvlist_t *origprops, nvlist_t **oxprops, uint8_t **wkeydata_out,
- uint_t *wkeylen_out, const char *errbuf)
-{
- nvpair_t *nvp;
- nvlist_t *oprops, *voprops;
- zfs_handle_t *zhp = NULL;
- zpool_handle_t *zpool_hdl = NULL;
- char *cp;
- int ret = 0;
- char namebuf[ZFS_MAX_DATASET_NAME_LEN];
-
- if (nvlist_empty(cmdprops))
- return (0); /* No properties to override or exclude */
-
- *oxprops = fnvlist_alloc();
- oprops = fnvlist_alloc();
-
- strlcpy(namebuf, fsname, ZFS_MAX_DATASET_NAME_LEN);
-
- /*
- * Get our dataset handle. The target dataset may not exist yet.
- */
- if (zfs_dataset_exists(hdl, namebuf, ZFS_TYPE_DATASET)) {
- zhp = zfs_open(hdl, namebuf, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- ret = -1;
- goto error;
- }
- }
-
- /* open the zpool handle */
- cp = strchr(namebuf, '/');
- if (cp != NULL)
- *cp = '\0';
- zpool_hdl = zpool_open(hdl, namebuf);
- if (zpool_hdl == NULL) {
- ret = -1;
- goto error;
- }
-
- /* restore namebuf to match fsname for later use */
- if (cp != NULL)
- *cp = '/';
-
- /*
- * first iteration: process excluded (-x) properties now and gather
- * added (-o) properties to be later processed by zfs_valid_proplist()
- */
- nvp = NULL;
- while ((nvp = nvlist_next_nvpair(cmdprops, nvp)) != NULL) {
- const char *name = nvpair_name(nvp);
- zfs_prop_t prop = zfs_name_to_prop(name);
-
- /*
- * It turns out, if we don't normalize "aliased" names
- * e.g. compress= against the "real" names (e.g. compression)
- * here, then setting/excluding them does not work as
- * intended.
- *
- * But since user-defined properties wouldn't have a valid
- * mapping here, we do this conditional dance.
- */
- const char *newname = name;
- if (prop >= ZFS_PROP_TYPE)
- newname = zfs_prop_to_name(prop);
-
- /* "origin" is processed separately, don't handle it here */
- if (prop == ZFS_PROP_ORIGIN)
- continue;
-
- /* raw streams can't override encryption properties */
- if ((zfs_prop_encryption_key_param(prop) ||
- prop == ZFS_PROP_ENCRYPTION) && raw) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encryption property '%s' cannot "
- "be set or excluded for raw streams."), name);
- ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- /*
- * For plain replicated send, we can ignore encryption
- * properties other than first stream
- */
- if ((zfs_prop_encryption_key_param(prop) || prop ==
- ZFS_PROP_ENCRYPTION) && !newfs && recursive && !raw) {
- continue;
- }
-
- /* incremental streams can only exclude encryption properties */
- if ((zfs_prop_encryption_key_param(prop) ||
- prop == ZFS_PROP_ENCRYPTION) && !newfs &&
- nvpair_type(nvp) != DATA_TYPE_BOOLEAN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encryption property '%s' cannot "
- "be set for incremental streams."), name);
- ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- switch (nvpair_type(nvp)) {
- case DATA_TYPE_BOOLEAN: /* -x property */
- /*
- * DATA_TYPE_BOOLEAN is the way we're asked to "exclude"
- * 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.
- */
- if (nvlist_exists(origprops, newname)) {
- nvlist_t *attrs;
- const char *source = NULL;
-
- attrs = fnvlist_lookup_nvlist(origprops,
- newname);
- if (nvlist_lookup_string(attrs,
- ZPROP_SOURCE, &source) == 0 &&
- strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0)
- continue;
- }
- /*
- * We can't force an explicit inherit on non-inheritable
- * properties: if we're asked to exclude this kind of
- * values we remove them from "recvprops" input nvlist.
- */
- if (!zfs_prop_user(name) && /* can be inherited too */
- !zfs_prop_inheritable(prop) &&
- nvlist_exists(recvprops, newname))
- fnvlist_remove(recvprops, newname);
- else
- fnvlist_add_boolean(*oxprops, newname);
- 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_string(oprops, newname,
- fnvpair_value_string(nvp));
- break;
- default:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' must be a string or boolean"), name);
- ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
- }
-
- if (toplevel) {
- /* convert override strings properties to native */
- if ((voprops = zfs_valid_proplist(hdl, ZFS_TYPE_DATASET,
- oprops, zoned, zhp, zpool_hdl, B_FALSE, errbuf)) == NULL) {
- ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
- /*
- * zfs_crypto_create() requires the parent name. Get it
- * by truncating the fsname copy stored in namebuf.
- */
- cp = strrchr(namebuf, '/');
- if (cp != NULL)
- *cp = '\0';
-
- if (!raw && !(!newfs && recursive) &&
- zfs_crypto_create(hdl, namebuf, voprops, NULL,
- B_FALSE, wkeydata_out, wkeylen_out) != 0) {
- fnvlist_free(voprops);
- ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
- goto error;
- }
-
- /* second pass: process "-o" properties */
- fnvlist_merge(*oxprops, voprops);
- fnvlist_free(voprops);
- } else {
- /* override props on child dataset are inherited */
- nvp = NULL;
- while ((nvp = nvlist_next_nvpair(oprops, nvp)) != NULL) {
- const char *name = nvpair_name(nvp);
- fnvlist_add_boolean(*oxprops, name);
- }
- }
-
-error:
- if (zhp != NULL)
- zfs_close(zhp);
- if (zpool_hdl != NULL)
- zpool_close(zpool_hdl);
- fnvlist_free(oprops);
- return (ret);
-}
-
-/*
- * Restores a backup of tosnap from the file descriptor specified by infd.
- */
-static int
-zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
- const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
- dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
- avl_tree_t *stream_avl, char **top_zfs,
- const char *finalsnap, nvlist_t *cmdprops)
-{
- struct timespec begin_time;
- int ioctl_err, ioctl_errno, err;
- char *cp;
- struct drr_begin *drrb = &drr->drr_u.drr_begin;
- char errbuf[ERRBUFLEN];
- const char *chopprefix;
- boolean_t newfs = B_FALSE;
- boolean_t stream_wantsnewfs, stream_resumingnewfs;
- boolean_t newprops = B_FALSE;
- uint64_t read_bytes = 0;
- uint64_t errflags = 0;
- uint64_t parent_snapguid = 0;
- prop_changelist_t *clp = NULL;
- nvlist_t *snapprops_nvlist = NULL;
- nvlist_t *snapholds_nvlist = NULL;
- zprop_errflags_t prop_errflags;
- nvlist_t *prop_errors = NULL;
- boolean_t recursive;
- const char *snapname = NULL;
- char destsnap[MAXPATHLEN * 2];
- char origin[MAXNAMELEN] = {0};
- char name[MAXPATHLEN];
- char tmp_keylocation[MAXNAMELEN] = {0};
- nvlist_t *rcvprops = NULL; /* props received from the send stream */
- nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
- nvlist_t *origprops = NULL; /* original props (if destination exists) */
- zfs_type_t type = ZFS_TYPE_INVALID;
- boolean_t toplevel = B_FALSE;
- boolean_t zoned = B_FALSE;
- boolean_t hastoken = B_FALSE;
- boolean_t redacted;
- uint8_t *wkeydata = NULL;
- uint_t wkeylen = 0;
-
-#ifndef CLOCK_MONOTONIC_RAW
-#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
-#endif
- clock_gettime(CLOCK_MONOTONIC_RAW, &begin_time);
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot receive"));
-
- recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
- ENOENT);
-
- /* Did the user request holds be skipped via zfs recv -k? */
- boolean_t holds = flags->holds && !flags->skipholds;
-
- if (stream_avl != NULL) {
- const char *keylocation = NULL;
- nvlist_t *lookup = NULL;
- nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
- &snapname);
-
- (void) nvlist_lookup_uint64(fs, "parentfromsnap",
- &parent_snapguid);
- err = nvlist_lookup_nvlist(fs, "props", &rcvprops);
- if (err) {
- rcvprops = fnvlist_alloc();
- newprops = B_TRUE;
- }
-
- /*
- * The keylocation property may only be set on encryption roots,
- * but this dataset might not become an encryption root until
- * recv_fix_encryption_hierarchy() is called. That function
- * will fixup the keylocation anyway, so we temporarily unset
- * the keylocation for now to avoid any errors from the receive
- * ioctl.
- */
- err = nvlist_lookup_string(rcvprops,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);
- if (err == 0) {
- strlcpy(tmp_keylocation, keylocation, MAXNAMELEN);
- (void) nvlist_remove_all(rcvprops,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION));
- }
-
- if (flags->canmountoff) {
- fnvlist_add_uint64(rcvprops,
- zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0);
- } else if (newprops) { /* nothing in rcvprops, eliminate it */
- fnvlist_free(rcvprops);
- rcvprops = NULL;
- newprops = B_FALSE;
- }
- if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
- snapprops_nvlist = fnvlist_lookup_nvlist(lookup,
- snapname);
- }
- if (holds) {
- if (0 == nvlist_lookup_nvlist(fs, "snapholds",
- &lookup)) {
- snapholds_nvlist = fnvlist_lookup_nvlist(
- lookup, snapname);
- }
- }
- }
-
- cp = NULL;
-
- /*
- * Determine how much of the snapshot name stored in the stream
- * we are going to tack on to the name they specified on the
- * command line, and how much we are going to chop off.
- *
- * If they specified a snapshot, chop the entire name stored in
- * the stream.
- */
- if (flags->istail) {
- /*
- * A filesystem was specified with -e. We want to tack on only
- * the tail of the sent snapshot path.
- */
- if (strchr(tosnap, '@')) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
- "argument - snapshot not allowed with -e"));
- err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto out;
- }
-
- chopprefix = strrchr(sendfs, '/');
-
- if (chopprefix == NULL) {
- /*
- * The tail is the poolname, so we need to
- * prepend a path separator.
- */
- int len = strlen(drrb->drr_toname);
- cp = umem_alloc(len + 2, UMEM_NOFAIL);
- cp[0] = '/';
- (void) strcpy(&cp[1], drrb->drr_toname);
- chopprefix = cp;
- } else {
- chopprefix = drrb->drr_toname + (chopprefix - sendfs);
- }
- } else if (flags->isprefix) {
- /*
- * A filesystem was specified with -d. We want to tack on
- * everything but the first element of the sent snapshot path
- * (all but the pool name).
- */
- if (strchr(tosnap, '@')) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
- "argument - snapshot not allowed with -d"));
- err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto out;
- }
-
- chopprefix = strchr(drrb->drr_toname, '/');
- if (chopprefix == NULL)
- chopprefix = strchr(drrb->drr_toname, '@');
- } else if (strchr(tosnap, '@') == NULL) {
- /*
- * If a filesystem was specified without -d or -e, we want to
- * tack on everything after the fs specified by 'zfs send'.
- */
- chopprefix = drrb->drr_toname + strlen(sendfs);
- } else {
- /* A snapshot was specified as an exact path (no -d or -e). */
- if (recursive) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot specify snapshot name for multi-snapshot "
- "stream"));
- err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
- chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
- }
-
- ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
- ASSERT(chopprefix > drrb->drr_toname || strchr(sendfs, '/') == NULL);
- ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname) ||
- strchr(sendfs, '/') == NULL);
- ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
- chopprefix[0] == '\0');
-
- /*
- * Determine name of destination snapshot.
- */
- (void) strlcpy(destsnap, tosnap, sizeof (destsnap));
- (void) strlcat(destsnap, chopprefix, sizeof (destsnap));
- if (cp != NULL)
- umem_free(cp, strlen(cp) + 1);
- if (!zfs_name_valid(destsnap, ZFS_TYPE_SNAPSHOT)) {
- err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto out;
- }
-
- /*
- * Determine the name of the origin snapshot.
- */
- if (originsnap) {
- (void) strlcpy(origin, originsnap, sizeof (origin));
- if (flags->verbose)
- (void) printf("using provided clone origin %s\n",
- origin);
- } else if (drrb->drr_flags & DRR_FLAG_CLONE) {
- if (guid_to_name(hdl, destsnap,
- drrb->drr_fromguid, B_FALSE, origin) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "local origin for clone %s does not exist"),
- destsnap);
- err = zfs_error(hdl, EZFS_NOENT, errbuf);
- goto out;
- }
- if (flags->verbose)
- (void) printf("found clone origin %s\n", origin);
- }
-
- if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
- DMU_BACKUP_FEATURE_DEDUP)) {
- (void) fprintf(stderr,
- gettext("ERROR: \"zfs receive\" no longer supports "
- "deduplicated send streams. Use\n"
- "the \"zstream redup\" command to convert this stream "
- "to a regular,\n"
- "non-deduplicated stream.\n"));
- err = zfs_error(hdl, EZFS_NOTSUP, errbuf);
- goto out;
- }
-
- boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
- DMU_BACKUP_FEATURE_RESUMING;
- boolean_t raw = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
- DMU_BACKUP_FEATURE_RAW;
- boolean_t embedded = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
- DMU_BACKUP_FEATURE_EMBED_DATA;
- stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
- (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;
- stream_resumingnewfs = (drrb->drr_fromguid == 0 ||
- (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && resuming;
-
- if (stream_wantsnewfs) {
- /*
- * if the parent fs does not exist, look for it based on
- * the parent snap GUID
- */
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot receive new filesystem stream"));
-
- (void) strlcpy(name, destsnap, sizeof (name));
- cp = strrchr(name, '/');
- if (cp)
- *cp = '\0';
- if (cp &&
- !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
- char suffix[ZFS_MAX_DATASET_NAME_LEN];
- (void) strlcpy(suffix, strrchr(destsnap, '/'),
- sizeof (suffix));
- if (guid_to_name(hdl, name, parent_snapguid,
- B_FALSE, destsnap) == 0) {
- *strchr(destsnap, '@') = '\0';
- (void) strlcat(destsnap, suffix,
- sizeof (destsnap));
- }
- }
- } else {
- /*
- * If the fs does not exist, look for it based on the
- * fromsnap GUID.
- */
- if (resuming) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot receive resume stream"));
- } else {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN,
- "cannot receive incremental stream"));
- }
-
- (void) strlcpy(name, destsnap, sizeof (name));
- *strchr(name, '@') = '\0';
-
- /*
- * If the exact receive path was specified and this is the
- * topmost path in the stream, then if the fs does not exist we
- * should look no further.
- */
- if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
- strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
- !zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
- char snap[ZFS_MAX_DATASET_NAME_LEN];
- (void) strlcpy(snap, strchr(destsnap, '@'),
- sizeof (snap));
- if (guid_to_name(hdl, name, drrb->drr_fromguid,
- B_FALSE, destsnap) == 0) {
- *strchr(destsnap, '@') = '\0';
- (void) strlcat(destsnap, snap,
- sizeof (destsnap));
- }
- }
- }
-
- (void) strlcpy(name, destsnap, sizeof (name));
- *strchr(name, '@') = '\0';
-
- redacted = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
- DMU_BACKUP_FEATURE_REDACTED;
-
- if (flags->heal) {
- if (flags->isprefix || flags->istail || flags->force ||
- flags->canmountoff || flags->resumable || flags->nomount ||
- flags->skipholds) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "corrective recv can not be used when combined with"
- " this flag"));
- err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto out;
- }
- uint64_t guid =
- get_snap_guid(hdl, name, strchr(destsnap, '@') + 1);
- if (guid == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "corrective recv must specify an existing snapshot"
- " to heal"));
- err = zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
- goto out;
- } else if (guid != drrb->drr_toguid) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "local snapshot doesn't match the snapshot"
- " in the provided stream"));
- err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
- goto out;
- }
- } else if (zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
- zfs_cmd_t zc = {"\0"};
- zfs_handle_t *zhp = NULL;
- boolean_t encrypted;
-
- (void) strcpy(zc.zc_name, name);
-
- /*
- * Destination fs exists. It must be one of these cases:
- * - an incremental send stream
- * - the stream specifies a new fs (full stream or clone)
- * and they want us to blow away the existing fs (and
- * have therefore specified -F and removed any snapshots)
- * - we are resuming a failed receive.
- */
- if (stream_wantsnewfs) {
- boolean_t is_volume = drrb->drr_type == DMU_OST_ZVOL;
- if (!flags->force) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination '%s' exists\n"
- "must specify -F to overwrite it"), name);
- err = zfs_error(hdl, EZFS_EXISTS, errbuf);
- goto out;
- }
- if (zfs_ioctl(hdl, ZFS_IOC_SNAPSHOT_LIST_NEXT,
- &zc) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination has snapshots (eg. %s)\n"
- "must destroy them to overwrite it"),
- zc.zc_name);
- err = zfs_error(hdl, EZFS_EXISTS, errbuf);
- goto out;
- }
- if (is_volume && strrchr(name, '/') == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination %s is the root dataset\n"
- "cannot overwrite with a ZVOL"),
- name);
- err = zfs_error(hdl, EZFS_EXISTS, errbuf);
- goto out;
- }
- if (is_volume &&
- zfs_ioctl(hdl, ZFS_IOC_DATASET_LIST_NEXT,
- &zc) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination has children (eg. %s)\n"
- "cannot overwrite with a ZVOL"),
- zc.zc_name);
- err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
- goto out;
- }
- }
-
- if ((zhp = zfs_open(hdl, name,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
- err = -1;
- goto out;
- }
-
- /*
- * When receiving full/newfs on existing dataset, then it
- * should be done with "-F" flag. Its enforced for initial
- * receive in previous checks in this function.
- * Similarly, on resuming full/newfs recv on existing dataset,
- * it should be done with "-F" flag.
- *
- * When dataset doesn't exist, then full/newfs recv is done on
- * newly created dataset and it's marked INCONSISTENT. But
- * When receiving on existing dataset, recv is first done on
- * %recv and its marked INCONSISTENT. Existing dataset is not
- * marked INCONSISTENT.
- * Resume of full/newfs receive with dataset not INCONSISTENT
- * indicates that its resuming newfs on existing dataset. So,
- * enforce "-F" flag in this case.
- */
- if (stream_resumingnewfs &&
- !zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) &&
- !flags->force) {
- zfs_close(zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Resuming recv on existing destination '%s'\n"
- "must specify -F to overwrite it"), name);
- err = zfs_error(hdl, EZFS_RESUME_EXISTS, errbuf);
- goto out;
- }
-
- if (stream_wantsnewfs &&
- zhp->zfs_dmustats.dds_origin[0]) {
- zfs_close(zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination '%s' is a clone\n"
- "must destroy it to overwrite it"), name);
- err = zfs_error(hdl, EZFS_EXISTS, errbuf);
- goto out;
- }
-
- /*
- * Raw sends can not be performed as an incremental on top
- * of existing unencrypted datasets. zfs recv -F can't be
- * used to blow away an existing encrypted filesystem. This
- * is because it would require the dsl dir to point to the
- * new key (or lack of a key) and the old key at the same
- * time. The -F flag may still be used for deleting
- * intermediate snapshots that would otherwise prevent the
- * receive from working.
- */
- encrypted = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) !=
- ZIO_CRYPT_OFF;
- if (!stream_wantsnewfs && !encrypted && raw) {
- zfs_close(zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot perform raw receive on top of "
- "existing unencrypted dataset"));
- err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- goto out;
- }
-
- if (stream_wantsnewfs && flags->force &&
- ((raw && !encrypted) || encrypted)) {
- zfs_close(zhp);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "zfs receive -F cannot be used to destroy an "
- "encrypted filesystem or overwrite an "
- "unencrypted one with an encrypted one"));
- err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- goto out;
- }
-
- if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
- (stream_wantsnewfs || stream_resumingnewfs)) {
- /* We can't do online recv in this case */
- clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
- flags->forceunmount ? MS_FORCE : 0);
- if (clp == NULL) {
- zfs_close(zhp);
- err = -1;
- goto out;
- }
- if (changelist_prefix(clp) != 0) {
- changelist_free(clp);
- zfs_close(zhp);
- err = -1;
- goto out;
- }
- }
-
- /*
- * If we are resuming a newfs, set newfs here so that we will
- * mount it if the recv succeeds this time. We can tell
- * that it was a newfs on the first recv because the fs
- * itself will be inconsistent (if the fs existed when we
- * did the first recv, we would have received it into
- * .../%recv).
- */
- if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
- newfs = B_TRUE;
-
- /* we want to know if we're zoned when validating -o|-x props */
- zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
-
- /* may need this info later, get it now we have zhp around */
- if (zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN, NULL, 0,
- NULL, NULL, 0, B_TRUE) == 0)
- hastoken = B_TRUE;
-
- /* gather existing properties on destination */
- origprops = fnvlist_alloc();
- fnvlist_merge(origprops, zhp->zfs_props);
- fnvlist_merge(origprops, zhp->zfs_user_props);
-
- zfs_close(zhp);
- } else {
- zfs_handle_t *zhp;
-
- /*
- * Destination filesystem does not exist. Therefore we better
- * be creating a new filesystem (either from a full backup, or
- * a clone). It would therefore be invalid if the user
- * specified only the pool name (i.e. if the destination name
- * contained no slash character).
- */
- cp = strrchr(name, '/');
-
- if (!stream_wantsnewfs || cp == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination '%s' does not exist"), name);
- err = zfs_error(hdl, EZFS_NOENT, errbuf);
- goto out;
- }
-
- /*
- * Trim off the final dataset component so we perform the
- * recvbackup ioctl to the filesystems's parent.
- */
- *cp = '\0';
-
- if (flags->isprefix && !flags->istail && !flags->dryrun &&
- create_parents(hdl, destsnap, strlen(tosnap)) != 0) {
- err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- goto out;
- }
-
- /* validate parent */
- zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- err = zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- goto out;
- }
- if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "parent '%s' is not a filesystem"), name);
- err = zfs_error(hdl, EZFS_WRONG_PARENT, errbuf);
- zfs_close(zhp);
- goto out;
- }
-
- zfs_close(zhp);
-
- newfs = B_TRUE;
- *cp = '/';
- }
-
- if (flags->verbose) {
- (void) printf("%s %s%s stream of %s into %s\n",
- flags->dryrun ? "would receive" : "receiving",
- flags->heal ? "corrective " : "",
- drrb->drr_fromguid ? "incremental" : "full",
- drrb->drr_toname, destsnap);
- (void) fflush(stdout);
- }
-
- /*
- * If this is the top-level dataset, record it so we can use it
- * for recursive operations later.
- */
- if (top_zfs != NULL &&
- (*top_zfs == NULL || strcmp(*top_zfs, name) == 0)) {
- toplevel = B_TRUE;
- if (*top_zfs == NULL)
- *top_zfs = zfs_strdup(hdl, name);
- }
-
- if (drrb->drr_type == DMU_OST_ZVOL) {
- type = ZFS_TYPE_VOLUME;
- } else if (drrb->drr_type == DMU_OST_ZFS) {
- type = ZFS_TYPE_FILESYSTEM;
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid record type: 0x%d"), drrb->drr_type);
- err = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- goto out;
- }
- if ((err = zfs_setup_cmdline_props(hdl, type, name, zoned, recursive,
- stream_wantsnewfs, raw, toplevel, rcvprops, cmdprops, origprops,
- &oxprops, &wkeydata, &wkeylen, errbuf)) != 0)
- goto out;
-
- /*
- * When sending with properties (zfs send -p), the encryption property
- * is not included because it is a SETONCE property and therefore
- * treated as read only. However, we are always able to determine its
- * value because raw sends will include it in the DRR_BDEGIN payload
- * and non-raw sends with properties are not allowed for encrypted
- * datasets. Therefore, if this is a non-raw properties stream, we can
- * infer that the value should be ZIO_CRYPT_OFF and manually add that
- * to the received properties.
- */
- if (stream_wantsnewfs && !raw && rcvprops != NULL &&
- !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
- if (oxprops == NULL)
- oxprops = fnvlist_alloc();
- fnvlist_add_uint64(oxprops,
- 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;
- }
-
- if (flags->heal) {
- err = ioctl_err = lzc_receive_with_heal(destsnap, rcvprops,
- oxprops, wkeydata, wkeylen, origin, flags->force,
- flags->heal, flags->resumable, raw, infd, drr_noswap, -1,
- &read_bytes, &errflags, NULL, &prop_errors);
- } else {
- 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, NULL, &prop_errors);
- }
- ioctl_errno = ioctl_err;
- prop_errflags = errflags;
-
- if (err == 0) {
- nvpair_t *prop_err = NULL;
-
- while ((prop_err = nvlist_next_nvpair(prop_errors,
- prop_err)) != NULL) {
- char tbuf[1024];
- zfs_prop_t prop;
- int intval;
-
- prop = zfs_name_to_prop(nvpair_name(prop_err));
- (void) nvpair_value_int32(prop_err, &intval);
- if (strcmp(nvpair_name(prop_err),
- ZPROP_N_MORE_ERRORS) == 0) {
- trunc_prop_errs(intval);
- break;
- } else if (snapname == NULL || finalsnap == NULL ||
- strcmp(finalsnap, snapname) == 0 ||
- strcmp(nvpair_name(prop_err),
- zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
- /*
- * Skip the special case of, for example,
- * "refquota", errors on intermediate
- * snapshots leading up to a final one.
- * That's why we have all of the checks above.
- *
- * See zfs_ioctl.c's extract_delay_props() for
- * a list of props which can fail on
- * intermediate snapshots, but shouldn't
- * affect the overall receive.
- */
- (void) snprintf(tbuf, sizeof (tbuf),
- dgettext(TEXT_DOMAIN,
- "cannot receive %s property on %s"),
- nvpair_name(prop_err), name);
- zfs_setprop_error(hdl, prop, intval, tbuf);
- }
- }
- }
-
- if (err == 0 && snapprops_nvlist) {
- zfs_cmd_t zc = {"\0"};
-
- (void) strlcpy(zc.zc_name, destsnap, sizeof (zc.zc_name));
- zc.zc_cookie = B_TRUE; /* received */
- zcmd_write_src_nvlist(hdl, &zc, snapprops_nvlist);
- (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
- zcmd_free_nvlists(&zc);
- }
- if (err == 0 && snapholds_nvlist) {
- nvpair_t *pair;
- nvlist_t *holds, *errors = NULL;
- int cleanup_fd = -1;
-
- VERIFY0(nvlist_alloc(&holds, 0, KM_SLEEP));
- for (pair = nvlist_next_nvpair(snapholds_nvlist, NULL);
- pair != NULL;
- pair = nvlist_next_nvpair(snapholds_nvlist, pair)) {
- fnvlist_add_string(holds, destsnap, nvpair_name(pair));
- }
- (void) lzc_hold(holds, cleanup_fd, &errors);
- fnvlist_free(snapholds_nvlist);
- fnvlist_free(holds);
- }
-
- if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
- /*
- * It may be that this snapshot already exists,
- * in which case we want to consume & ignore it
- * rather than failing.
- */
- avl_tree_t *local_avl;
- nvlist_t *local_nv, *fs;
- cp = strchr(destsnap, '@');
-
- /*
- * XXX Do this faster by just iterating over snaps in
- * this fs. Also if zc_value does not exist, we will
- * get a strange "does not exist" error message.
- */
- *cp = '\0';
- if (gather_nvlist(hdl, destsnap, NULL, NULL, B_FALSE, B_TRUE,
- 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);
- fnvlist_free(local_nv);
-
- if (fs != NULL) {
- if (flags->verbose) {
- (void) printf("snap %s already exists; "
- "ignoring\n", destsnap);
- }
- err = ioctl_err = recv_skip(hdl, infd,
- flags->byteswap);
- }
- }
- *cp = '@';
- }
-
- if (ioctl_err != 0) {
- switch (ioctl_errno) {
- case ENODEV:
- cp = strchr(destsnap, '@');
- *cp = '\0';
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "most recent snapshot of %s does not\n"
- "match incremental source"), destsnap);
- (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- *cp = '@';
- break;
- case ETXTBSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination %s has been modified\n"
- "since most recent snapshot"), name);
- (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
- break;
- case EACCES:
- if (flags->heal) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "key must be loaded to do a non-raw "
- "corrective recv on an encrypted "
- "dataset."));
- } else if (raw && stream_wantsnewfs) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "failed to create encryption key"));
- } else if (raw && !stream_wantsnewfs) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "encryption key does not match "
- "existing key"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "inherited key must be loaded"));
- }
- (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
- break;
- case EEXIST:
- cp = strchr(destsnap, '@');
- if (newfs) {
- /* it's the containing fs that exists */
- *cp = '\0';
- }
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination already exists"));
- (void) zfs_error_fmt(hdl, EZFS_EXISTS,
- dgettext(TEXT_DOMAIN, "cannot restore to %s"),
- destsnap);
- *cp = '@';
- break;
- case EINVAL:
- if (embedded && !raw) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incompatible embedded data stream "
- "feature with encrypted receive."));
- } else if (flags->resumable) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "kernel modules must be upgraded to "
- "receive this stream."));
- }
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ECKSUM:
- case ZFS_ERR_STREAM_TRUNCATED:
- if (flags->heal)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "corrective receive was not able to "
- "reconstruct the data needed for "
- "healing."));
- else
- recv_ecksum_set_aux(hdl, destsnap,
- flags->resumable, ioctl_err == ECKSUM);
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ZFS_ERR_STREAM_LARGE_BLOCK_MISMATCH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "incremental send stream requires -L "
- "(--large-block), to match previous receive."));
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ENOTSUP:
- if (flags->heal)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "stream is not compatible with the "
- "data in the pool."));
- else
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool must be upgraded to receive this "
- "stream."));
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
- case ZFS_ERR_CRYPTO_NOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "stream uses crypto parameters not compatible with "
- "this pool"));
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case EDQUOT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination %s space quota exceeded."), name);
- (void) zfs_error(hdl, EZFS_NOSPC, errbuf);
- break;
- case ZFS_ERR_FROM_IVSET_GUID_MISSING:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "IV set guid missing. See errata %u at "
- "https://openzfs.github.io/openzfs-docs/msg/"
- "ZFS-8000-ER."),
- ZPOOL_ERRATA_ZOL_8308_ENCRYPTION);
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ZFS_ERR_FROM_IVSET_GUID_MISMATCH:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "IV set guid mismatch. See the 'zfs receive' "
- "man page section\n discussing the limitations "
- "of raw encrypted send streams."));
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ZFS_ERR_SPILL_BLOCK_FLAG_MISSING:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Spill block flag missing for raw send.\n"
- "The zfs software on the sending system must "
- "be updated."));
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case ZFS_ERR_RESUME_EXISTS:
- cp = strchr(destsnap, '@');
- if (newfs) {
- /* it's the containing fs that exists */
- *cp = '\0';
- }
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Resuming recv on existing dataset without force"));
- (void) zfs_error_fmt(hdl, EZFS_RESUME_EXISTS,
- dgettext(TEXT_DOMAIN, "cannot resume recv %s"),
- destsnap);
- *cp = '@';
- break;
- case E2BIG:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "zfs receive required kernel memory allocation "
- "larger than the system can support. Please file "
- "an issue at the OpenZFS issue tracker:\n"
- "https://github.com/openzfs/zfs/issues/new"));
- (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
- break;
- case EBUSY:
- if (hastoken) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "destination %s contains "
- "partially-complete state from "
- "\"zfs receive -s\"."), name);
- (void) zfs_error(hdl, EZFS_BUSY, errbuf);
- break;
- }
- zfs_fallthrough;
- default:
- (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
- }
- }
-
- /*
- * Mount the target filesystem (if created). Also mount any
- * children of the target filesystem if we did a replication
- * receive (indicated by stream_avl being non-NULL).
- */
- if (clp) {
- if (!flags->nomount)
- err |= changelist_postfix(clp);
- changelist_free(clp);
- }
-
- if ((newfs || stream_avl) && type == ZFS_TYPE_FILESYSTEM && !redacted)
- flags->domount = B_TRUE;
-
- if (prop_errflags & ZPROP_ERR_NOCLEAR) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
- "failed to clear unreceived properties on %s"), name);
- (void) fprintf(stderr, "\n");
- }
- if (prop_errflags & ZPROP_ERR_NORESTORE) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
- "failed to restore original properties on %s"), name);
- (void) fprintf(stderr, "\n");
- }
-
- if (err || ioctl_err) {
- err = -1;
- goto out;
- }
-
- if (flags->verbose) {
- char buf1[64];
- char buf2[64];
- uint64_t bytes = read_bytes;
- struct timespec delta;
- clock_gettime(CLOCK_MONOTONIC_RAW, &delta);
- if (begin_time.tv_nsec > delta.tv_nsec) {
- delta.tv_nsec =
- 1000000000 + delta.tv_nsec - begin_time.tv_nsec;
- delta.tv_sec -= 1;
- } else
- delta.tv_nsec -= begin_time.tv_nsec;
- delta.tv_sec -= begin_time.tv_sec;
- if (delta.tv_sec == 0 && delta.tv_nsec == 0)
- delta.tv_nsec = 1;
- double delta_f = delta.tv_sec + (delta.tv_nsec / 1e9);
- zfs_nicebytes(bytes, buf1, sizeof (buf1));
- zfs_nicebytes(bytes / delta_f, buf2, sizeof (buf2));
-
- (void) printf("received %s stream in %.2f seconds (%s/sec)\n",
- buf1, delta_f, buf2);
- }
-
- err = 0;
-out:
- if (prop_errors != NULL)
- fnvlist_free(prop_errors);
-
- if (tmp_keylocation[0] != '\0') {
- fnvlist_add_string(rcvprops,
- zfs_prop_to_name(ZFS_PROP_KEYLOCATION), tmp_keylocation);
- }
-
- if (newprops)
- fnvlist_free(rcvprops);
-
- fnvlist_free(oxprops);
- fnvlist_free(origprops);
-
- return (err);
-}
-
-/*
- * Check properties we were asked to override (both -o|-x)
- */
-static boolean_t
-zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
- const char *errbuf)
-{
- nvpair_t *nvp = NULL;
- zfs_prop_t prop;
- const char *name;
-
- while ((nvp = nvlist_next_nvpair(props, nvp)) != NULL) {
- name = nvpair_name(nvp);
- prop = zfs_name_to_prop(name);
-
- if (prop == ZPROP_USERPROP) {
- if (!zfs_prop_user(name)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "%s: invalid property '%s'"), errbuf, name);
- return (B_FALSE);
- }
- continue;
- }
- /*
- * "origin" is readonly but is used to receive datasets as
- * clones so we don't raise an error here
- */
- if (prop == ZFS_PROP_ORIGIN)
- continue;
-
- /* encryption params have their own verification later */
- if (prop == ZFS_PROP_ENCRYPTION ||
- zfs_prop_encryption_key_param(prop))
- continue;
-
- /*
- * cannot override readonly, set-once and other specific
- * settable properties
- */
- if (zfs_prop_readonly(prop) || prop == ZFS_PROP_VERSION ||
- prop == ZFS_PROP_VOLSIZE) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "%s: invalid property '%s'"), errbuf, name);
- return (B_FALSE);
- }
- }
-
- return (B_TRUE);
-}
-
-static int
-zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
- const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
- nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs,
- const char *finalsnap, nvlist_t *cmdprops)
-{
- int err;
- dmu_replay_record_t drr, drr_noswap;
- struct drr_begin *drrb = &drr.drr_u.drr_begin;
- char errbuf[ERRBUFLEN];
- zio_cksum_t zcksum = { { 0 } };
- uint64_t featureflags;
- int hdrtype;
-
- (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
- "cannot receive"));
-
- /* check cmdline props, raise an error if they cannot be received */
- if (!zfs_receive_checkprops(hdl, cmdprops, errbuf))
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
-
- if (flags->isprefix &&
- !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
- "(%s) does not exist"), tosnap);
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
- }
- if (originsnap &&
- !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
- "(%s) does not exist"), originsnap);
- return (zfs_error(hdl, EZFS_NOENT, errbuf));
- }
-
- /* read in the BEGIN record */
- if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
- &zcksum)))
- return (err);
-
- if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
- /* It's the double end record at the end of a package */
- return (ENODATA);
- }
-
- /* the kernel needs the non-byteswapped begin record */
- drr_noswap = drr;
-
- flags->byteswap = B_FALSE;
- if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
- /*
- * We computed the checksum in the wrong byteorder in
- * recv_read() above; do it again correctly.
- */
- memset(&zcksum, 0, sizeof (zio_cksum_t));
- fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
- flags->byteswap = B_TRUE;
-
- drr.drr_type = BSWAP_32(drr.drr_type);
- drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
- drrb->drr_magic = BSWAP_64(drrb->drr_magic);
- drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
- drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
- drrb->drr_type = BSWAP_32(drrb->drr_type);
- drrb->drr_flags = BSWAP_32(drrb->drr_flags);
- drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
- drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
- }
-
- if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
- "stream (bad magic number)"));
- return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
- }
-
- featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
- hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
-
- if (!DMU_STREAM_SUPPORTED(featureflags) ||
- (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
- /*
- * Let's be explicit about this one, since rather than
- * being a new feature we can't know, it's an old
- * feature we dropped.
- */
- if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "stream has deprecated feature: dedup, try "
- "'zstream redup [send in a file] | zfs recv "
- "[...]'"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "stream has unsupported feature, feature flags = "
- "%llx (unknown flags = %llx)"),
- (u_longlong_t)featureflags,
- (u_longlong_t)((featureflags) &
- ~DMU_BACKUP_FEATURE_MASK));
- }
- return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
- }
-
- /* Holds feature is set once in the compound stream header. */
- if (featureflags & DMU_BACKUP_FEATURE_HOLDS)
- flags->holds = B_TRUE;
-
- if (strchr(drrb->drr_toname, '@') == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
- "stream (bad snapshot name)"));
- return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
- }
-
- if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
- char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
- if (sendfs == NULL) {
- /*
- * We were not called from zfs_receive_package(). Get
- * the fs specified by 'zfs send'.
- */
- char *cp;
- (void) strlcpy(nonpackage_sendfs,
- drr.drr_u.drr_begin.drr_toname,
- sizeof (nonpackage_sendfs));
- if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
- *cp = '\0';
- sendfs = nonpackage_sendfs;
- VERIFY0P(finalsnap);
- }
- return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
- &drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
- finalsnap, cmdprops));
- } else {
- assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
- DMU_COMPOUNDSTREAM);
- return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
- &zcksum, top_zfs, cmdprops));
- }
-}
-
-/*
- * Restores a backup of tosnap from the file descriptor specified by infd.
- * Return 0 on total success, -2 if some things couldn't be
- * destroyed/renamed/promoted, -1 if some things couldn't be received.
- * (-1 will override -2, if -1 and the resumable flag was specified the
- * transfer can be resumed if the sending side supports it).
- */
-int
-zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
- recvflags_t *flags, int infd, avl_tree_t *stream_avl)
-{
- char *top_zfs = NULL;
- int err;
- struct stat sb;
- const char *originsnap = NULL;
-
- /*
- * The only way fstat can fail is if we do not have a valid file
- * descriptor.
- */
- if (fstat(infd, &sb) == -1) {
- perror("fstat");
- return (-2);
- }
-
- if (props) {
- err = nvlist_lookup_string(props, "origin", &originsnap);
- if (err && err != ENOENT)
- return (err);
- }
-
- err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
- stream_avl, &top_zfs, NULL, props);
-
- if (err == 0 && !flags->nomount && flags->domount && top_zfs) {
- zfs_handle_t *zhp = NULL;
- prop_changelist_t *clp = NULL;
-
- zhp = zfs_open(hdl, top_zfs,
- ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL) {
- err = -1;
- goto out;
- } else {
- if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
- zfs_close(zhp);
- goto out;
- }
-
- clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
- CL_GATHER_MOUNT_ALWAYS,
- flags->forceunmount ? MS_FORCE : 0);
- zfs_close(zhp);
- if (clp == NULL) {
- err = -1;
- goto out;
- }
-
- /* mount and share received datasets */
- err = changelist_postfix(clp);
- changelist_free(clp);
- if (err != 0)
- err = -1;
- }
- }
-
-out:
- if (top_zfs)
- free(top_zfs);
-
- return (err);
-}
diff --git a/lib/libzfs/libzfs_status.c b/lib/libzfs/libzfs_status.c
deleted file mode 100644
index bdddefb92165..000000000000
--- a/lib/libzfs/libzfs_status.c
+++ /dev/null
@@ -1,537 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
- * Copyright (c) 2013 Steven Hartland. All rights reserved.
- * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
- */
-
-/*
- * This file contains the functions which analyze the status of a pool. This
- * include both the status of an active pool, as well as the status exported
- * pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
- * the pool. This status is independent (to a certain degree) from the state of
- * the pool. A pool's state describes only whether or not it is capable of
- * providing the necessary fault tolerance for data. The status describes the
- * overall status of devices. A pool that is online can still have a device
- * that is experiencing errors.
- *
- * Only a subset of the possible faults can be detected using 'zpool status',
- * and not all possible errors correspond to a FMA message ID. The explanation
- * is left up to the caller, depending on whether it is a live pool or an
- * import.
- */
-
-#include <libzfs.h>
-#include <libzutil.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/systeminfo.h>
-#include "libzfs_impl.h"
-#include "zfeature_common.h"
-
-/*
- * Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
- * in include/libzfs.h. Note that there are some status results which go past
- * the end of this table, and hence have no associated message ID.
- */
-static const char *const zfs_msgid_table[] = {
- "ZFS-8000-14", /* ZPOOL_STATUS_CORRUPT_CACHE */
- "ZFS-8000-2Q", /* ZPOOL_STATUS_MISSING_DEV_R */
- "ZFS-8000-3C", /* ZPOOL_STATUS_MISSING_DEV_NR */
- "ZFS-8000-4J", /* ZPOOL_STATUS_CORRUPT_LABEL_R */
- "ZFS-8000-5E", /* ZPOOL_STATUS_CORRUPT_LABEL_NR */
- "ZFS-8000-6X", /* ZPOOL_STATUS_BAD_GUID_SUM */
- "ZFS-8000-72", /* ZPOOL_STATUS_CORRUPT_POOL */
- "ZFS-8000-8A", /* ZPOOL_STATUS_CORRUPT_DATA */
- "ZFS-8000-9P", /* ZPOOL_STATUS_FAILING_DEV */
- "ZFS-8000-A5", /* ZPOOL_STATUS_VERSION_NEWER */
- "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_MISMATCH */
- "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_ACTIVE */
- "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_REQUIRED */
- "ZFS-8000-HC", /* ZPOOL_STATUS_IO_FAILURE_WAIT */
- "ZFS-8000-JQ", /* ZPOOL_STATUS_IO_FAILURE_CONTINUE */
- "ZFS-8000-MM", /* ZPOOL_STATUS_IO_FAILURE_MMP */
- "ZFS-8000-K4", /* ZPOOL_STATUS_BAD_LOG */
- "ZFS-8000-ER", /* ZPOOL_STATUS_ERRATA */
- /*
- * The following results have no message ID.
- * ZPOOL_STATUS_UNSUP_FEAT_READ
- * ZPOOL_STATUS_UNSUP_FEAT_WRITE
- * ZPOOL_STATUS_FAULTED_DEV_R
- * ZPOOL_STATUS_FAULTED_DEV_NR
- * ZPOOL_STATUS_VERSION_OLDER
- * ZPOOL_STATUS_FEAT_DISABLED
- * ZPOOL_STATUS_RESILVERING
- * ZPOOL_STATUS_OFFLINE_DEV
- * ZPOOL_STATUS_REMOVED_DEV
- * ZPOOL_STATUS_REBUILDING
- * ZPOOL_STATUS_REBUILD_SCRUB
- * ZPOOL_STATUS_COMPATIBILITY_ERR
- * ZPOOL_STATUS_INCOMPATIBLE_FEAT
- * ZPOOL_STATUS_OK
- */
-};
-
-#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
-
-static int
-vdev_missing(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_OPEN_FAILED);
-}
-
-static int
-vdev_faulted(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_FAULTED);
-}
-
-static int
-vdev_errors(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_DEGRADED ||
- vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||
- vs->vs_checksum_errors != 0);
-}
-
-static int
-vdev_broken(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_CANT_OPEN);
-}
-
-static int
-vdev_offlined(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_OFFLINE);
-}
-
-static int
-vdev_removed(vdev_stat_t *vs, uint_t vsc)
-{
- (void) vsc;
- return (vs->vs_state == VDEV_STATE_REMOVED);
-}
-
-static int
-vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
-{
- if (getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") != NULL)
- return (0);
-
- return (VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
- vs->vs_configured_ashift < vs->vs_physical_ashift);
-}
-
-/*
- * Detect if any leaf devices that have seen errors or could not be opened.
- */
-static boolean_t
-find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
- boolean_t ignore_replacing)
-{
- nvlist_t **child;
- uint_t c, children;
-
- /*
- * Ignore problems within a 'replacing' vdev, since we're presumably in
- * the process of repairing any such errors, and don't want to call them
- * out again. We'll pick up the fact that a resilver is happening
- * later.
- */
- if (ignore_replacing == B_TRUE) {
- const char *type = fnvlist_lookup_string(vdev,
- ZPOOL_CONFIG_TYPE);
- if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
- return (B_FALSE);
- }
-
- if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
- &children) == 0) {
- for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func, ignore_replacing))
- return (B_TRUE);
- } else {
- uint_t vsc;
- vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
- vdev, ZPOOL_CONFIG_VDEV_STATS, &vsc);
- if (func(vs, vsc) != 0)
- return (B_TRUE);
- }
-
- /*
- * Check any L2 cache devs
- */
- if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
- &children) == 0) {
- for (c = 0; c < children; c++)
- if (find_vdev_problem(child[c], func, ignore_replacing))
- return (B_TRUE);
- }
-
- return (B_FALSE);
-}
-
-/*
- * Active pool health status.
- *
- * To determine the status for a pool, we make several passes over the config,
- * picking the most egregious error we find. In order of importance, we do the
- * following:
- *
- * - Check for a complete and valid configuration
- * - Look for any faulted or missing devices in a non-replicated config
- * - Check for any data errors
- * - Check for any faulted or missing devices in a replicated config
- * - Look for any devices showing errors
- * - Check for any resilvering or rebuilding devices
- *
- * There can obviously be multiple errors within a single pool, so this routine
- * only picks the most damaging of all the current errors to report.
- */
-static zpool_status_t
-check_status(nvlist_t *config, boolean_t isimport,
- zpool_errata_t *erratap, const char *compat)
-{
- pool_scan_stat_t *ps = NULL;
- uint_t vsc, psc;
- uint64_t suspended;
- uint64_t hostid = 0;
- uint64_t errata = 0;
- unsigned long system_hostid = get_system_hostid();
-
- uint64_t version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
- nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_VDEV_TREE);
- vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(nvroot,
- ZPOOL_CONFIG_VDEV_STATS, &vsc);
- uint64_t stateval = fnvlist_lookup_uint64(config,
- ZPOOL_CONFIG_POOL_STATE);
-
- /*
- * Currently resilvering a vdev
- */
- (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
- (uint64_t **)&ps, &psc);
- if (ps != NULL && ps->pss_func == POOL_SCAN_RESILVER &&
- ps->pss_state == DSS_SCANNING)
- return (ZPOOL_STATUS_RESILVERING);
-
- /*
- * Currently rebuilding a vdev, check top-level vdevs.
- */
- vdev_rebuild_stat_t *vrs = NULL;
- nvlist_t **child;
- uint_t c, i, children;
- uint64_t rebuild_end_time = 0;
- if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
- &child, &children) == 0) {
- for (c = 0; c < children; c++) {
- if ((nvlist_lookup_uint64_array(child[c],
- ZPOOL_CONFIG_REBUILD_STATS,
- (uint64_t **)&vrs, &i) == 0) && (vrs != NULL)) {
- uint64_t state = vrs->vrs_state;
-
- if (state == VDEV_REBUILD_ACTIVE) {
- return (ZPOOL_STATUS_REBUILDING);
- } else if (state == VDEV_REBUILD_COMPLETE &&
- vrs->vrs_end_time > rebuild_end_time) {
- rebuild_end_time = vrs->vrs_end_time;
- }
- }
- }
-
- /*
- * If we can determine when the last scrub was run, and it
- * was before the last rebuild completed, then recommend
- * that the pool be scrubbed to verify all checksums. When
- * ps is NULL we can infer the pool has never been scrubbed.
- */
- if (rebuild_end_time > 0) {
- if (ps != NULL) {
- if ((ps->pss_state == DSS_FINISHED &&
- ps->pss_func == POOL_SCAN_SCRUB &&
- rebuild_end_time > ps->pss_end_time) ||
- ps->pss_state == DSS_NONE)
- return (ZPOOL_STATUS_REBUILD_SCRUB);
- } else {
- return (ZPOOL_STATUS_REBUILD_SCRUB);
- }
- }
- }
-
- /*
- * The multihost property is set and the pool may be active.
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_ACTIVE) {
- mmp_state_t mmp_state;
- nvlist_t *nvinfo;
-
- nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
- mmp_state = fnvlist_lookup_uint64(nvinfo,
- ZPOOL_CONFIG_MMP_STATE);
-
- if (mmp_state == MMP_STATE_ACTIVE)
- return (ZPOOL_STATUS_HOSTID_ACTIVE);
- else if (mmp_state == MMP_STATE_NO_HOSTID)
- return (ZPOOL_STATUS_HOSTID_REQUIRED);
- else
- return (ZPOOL_STATUS_HOSTID_MISMATCH);
- }
-
- /*
- * Pool last accessed by another system.
- */
- (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
- if (hostid != 0 && (unsigned long)hostid != system_hostid &&
- stateval == POOL_STATE_ACTIVE)
- return (ZPOOL_STATUS_HOSTID_MISMATCH);
-
- /*
- * Newer on-disk version.
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_VERSION_NEWER)
- return (ZPOOL_STATUS_VERSION_NEWER);
-
- /*
- * Unsupported feature(s).
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_UNSUP_FEAT) {
- nvlist_t *nvinfo = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_LOAD_INFO);
- if (nvlist_exists(nvinfo, ZPOOL_CONFIG_CAN_RDONLY))
- return (ZPOOL_STATUS_UNSUP_FEAT_WRITE);
- return (ZPOOL_STATUS_UNSUP_FEAT_READ);
- }
-
- /*
- * Check that the config is complete.
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_BAD_GUID_SUM)
- return (ZPOOL_STATUS_BAD_GUID_SUM);
-
- /*
- * Check whether the pool has suspended.
- */
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
- &suspended) == 0) {
- uint64_t reason;
-
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED_REASON,
- &reason) == 0 && reason == ZIO_SUSPEND_MMP)
- return (ZPOOL_STATUS_IO_FAILURE_MMP);
-
- if (suspended == ZIO_FAILURE_MODE_CONTINUE)
- return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
- return (ZPOOL_STATUS_IO_FAILURE_WAIT);
- }
-
- /*
- * Could not read a log.
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_BAD_LOG) {
- return (ZPOOL_STATUS_BAD_LOG);
- }
-
- /*
- * Bad devices in non-replicated config.
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
- return (ZPOOL_STATUS_FAULTED_DEV_NR);
-
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_missing, B_TRUE))
- return (ZPOOL_STATUS_MISSING_DEV_NR);
-
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- find_vdev_problem(nvroot, vdev_broken, B_TRUE))
- return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
-
- /*
- * Corrupted pool metadata
- */
- if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
- vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
- return (ZPOOL_STATUS_CORRUPT_POOL);
-
- /*
- * Persistent data errors.
- */
- if (!isimport) {
- uint64_t nerr;
- if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
- &nerr) == 0 && nerr != 0)
- return (ZPOOL_STATUS_CORRUPT_DATA);
- }
-
- /*
- * Missing devices in a replicated config.
- */
- if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
- return (ZPOOL_STATUS_FAULTED_DEV_R);
- if (find_vdev_problem(nvroot, vdev_missing, B_TRUE))
- return (ZPOOL_STATUS_MISSING_DEV_R);
- if (find_vdev_problem(nvroot, vdev_broken, B_TRUE))
- return (ZPOOL_STATUS_CORRUPT_LABEL_R);
-
- /*
- * Devices with errors
- */
- if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE))
- return (ZPOOL_STATUS_FAILING_DEV);
-
- /*
- * Offlined devices
- */
- if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE))
- return (ZPOOL_STATUS_OFFLINE_DEV);
-
- /*
- * Removed device
- */
- if (find_vdev_problem(nvroot, vdev_removed, B_TRUE))
- return (ZPOOL_STATUS_REMOVED_DEV);
-
- /*
- * Suboptimal, but usable, ashift configuration.
- */
- if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE))
- return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);
-
- /*
- * Informational errata available.
- */
- (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRATA, &errata);
- if (errata) {
- *erratap = errata;
- return (ZPOOL_STATUS_ERRATA);
- }
-
- /*
- * Outdated, but usable, version
- */
- 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 or superfluous features
- * (superfluous = beyond what's requested by 'compatibility')
- */
- if (version >= SPA_VERSION_FEATURES) {
- int i;
- nvlist_t *feat;
-
- if (isimport) {
- feat = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_LOAD_INFO);
- if (nvlist_exists(feat, ZPOOL_CONFIG_ENABLED_FEAT))
- feat = fnvlist_lookup_nvlist(feat,
- ZPOOL_CONFIG_ENABLED_FEAT);
- } else {
- feat = fnvlist_lookup_nvlist(config,
- ZPOOL_CONFIG_FEATURE_STATS);
- }
-
- /* check against all features, or limited set? */
- boolean_t c_features[SPA_FEATURES];
-
- 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 ||
- (fi->fi_flags & ZFEATURE_FLAG_NO_UPGRADE))
- continue;
- 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);
- }
- }
-
- return (ZPOOL_STATUS_OK);
-}
-
-zpool_status_t
-zpool_get_status(zpool_handle_t *zhp, const char **msgid,
- zpool_errata_t *errata)
-{
- /*
- * pass in the desired feature set, as
- * it affects check for disabled features
- */
- char compatibility[ZFS_MAXPROPLEN];
- if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compatibility,
- ZFS_MAXPROPLEN, NULL, B_FALSE) != 0)
- compatibility[0] = '\0';
-
- zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata,
- compatibility);
-
- if (msgid != NULL) {
- if (ret >= NMSGID)
- *msgid = NULL;
- else
- *msgid = zfs_msgid_table[ret];
- }
- return (ret);
-}
-
-zpool_status_t
-zpool_import_status(nvlist_t *config, const char **msgid,
- zpool_errata_t *errata)
-{
- zpool_status_t ret = check_status(config, B_TRUE, errata, NULL);
-
- if (ret >= NMSGID)
- *msgid = NULL;
- else
- *msgid = zfs_msgid_table[ret];
-
- return (ret);
-}
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
deleted file mode 100644
index 26f5135dff62..000000000000
--- a/lib/libzfs/libzfs_util.c
+++ /dev/null
@@ -1,2462 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2020 Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2024 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright (c) 2017 Datto Inc.
- * Copyright (c) 2020 The FreeBSD Foundation
- *
- * Portions of this software were developed by Allan Jude
- * under sponsorship from the FreeBSD Foundation.
- */
-
-/*
- * Internal utility routines for the ZFS library.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <unistd.h>
-#include <math.h>
-#if LIBFETCH_DYNAMIC
-#include <dlfcn.h>
-#endif
-#include <sys/stat.h>
-#include <sys/mnttab.h>
-#include <sys/mntent.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <libzfs.h>
-#include <libzfs_core.h>
-
-#include "libzfs_impl.h"
-#include "zfs_prop.h"
-#include "zfeature_common.h"
-#include <zfs_fletcher.h>
-#include <libzutil.h>
-
-/*
- * We only care about the scheme in order to match the scheme
- * with the handler. Each handler should validate the full URI
- * as necessary.
- */
-#define URI_REGEX "^\\([A-Za-z][A-Za-z0-9+.\\-]*\\):"
-#define STR_NUMS "0123456789"
-
-int
-libzfs_errno(libzfs_handle_t *hdl)
-{
- return (hdl->libzfs_error);
-}
-
-const char *
-libzfs_error_action(libzfs_handle_t *hdl)
-{
- return (hdl->libzfs_action);
-}
-
-const char *
-libzfs_error_description(libzfs_handle_t *hdl)
-{
- if (hdl->libzfs_desc[0] != '\0')
- return (hdl->libzfs_desc);
-
- switch (hdl->libzfs_error) {
- case EZFS_NOMEM:
- return (dgettext(TEXT_DOMAIN, "out of memory"));
- case EZFS_BADPROP:
- return (dgettext(TEXT_DOMAIN, "invalid property value"));
- case EZFS_PROPREADONLY:
- return (dgettext(TEXT_DOMAIN, "read-only property"));
- case EZFS_PROPTYPE:
- return (dgettext(TEXT_DOMAIN, "property doesn't apply to "
- "datasets of this type"));
- case EZFS_PROPNONINHERIT:
- return (dgettext(TEXT_DOMAIN, "property cannot be inherited"));
- case EZFS_PROPSPACE:
- return (dgettext(TEXT_DOMAIN, "invalid quota or reservation"));
- case EZFS_BADTYPE:
- return (dgettext(TEXT_DOMAIN, "operation not applicable to "
- "datasets of this type"));
- case EZFS_BUSY:
- return (dgettext(TEXT_DOMAIN, "pool or dataset is busy"));
- case EZFS_EXISTS:
- return (dgettext(TEXT_DOMAIN, "pool or dataset exists"));
- case EZFS_NOENT:
- return (dgettext(TEXT_DOMAIN, "no such pool or dataset"));
- case EZFS_BADSTREAM:
- return (dgettext(TEXT_DOMAIN, "invalid backup stream"));
- case EZFS_DSREADONLY:
- return (dgettext(TEXT_DOMAIN, "dataset is read-only"));
- case EZFS_VOLTOOBIG:
- return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for "
- "this system"));
- case EZFS_INVALIDNAME:
- return (dgettext(TEXT_DOMAIN, "invalid name"));
- case EZFS_BADRESTORE:
- return (dgettext(TEXT_DOMAIN, "unable to restore to "
- "destination"));
- case EZFS_BADBACKUP:
- return (dgettext(TEXT_DOMAIN, "backup failed"));
- case EZFS_BADTARGET:
- return (dgettext(TEXT_DOMAIN, "invalid target vdev"));
- case EZFS_NODEVICE:
- return (dgettext(TEXT_DOMAIN, "no such device in pool"));
- case EZFS_BADDEV:
- return (dgettext(TEXT_DOMAIN, "invalid device"));
- case EZFS_NOREPLICAS:
- return (dgettext(TEXT_DOMAIN, "no valid replicas"));
- case EZFS_RESILVERING:
- return (dgettext(TEXT_DOMAIN, "currently resilvering"));
- case EZFS_BADVERSION:
- return (dgettext(TEXT_DOMAIN, "unsupported version or "
- "feature"));
- case EZFS_POOLUNAVAIL:
- return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
- case EZFS_DEVOVERFLOW:
- return (dgettext(TEXT_DOMAIN, "too many devices in one vdev"));
- case EZFS_BADPATH:
- return (dgettext(TEXT_DOMAIN, "must be an absolute path"));
- case EZFS_CROSSTARGET:
- return (dgettext(TEXT_DOMAIN, "operation crosses datasets or "
- "pools"));
- case EZFS_ZONED:
- return (dgettext(TEXT_DOMAIN, "dataset in use by local zone"));
- case EZFS_MOUNTFAILED:
- return (dgettext(TEXT_DOMAIN, "mount failed"));
- case EZFS_UMOUNTFAILED:
- return (dgettext(TEXT_DOMAIN, "unmount failed"));
- case EZFS_UNSHARENFSFAILED:
- return (dgettext(TEXT_DOMAIN, "NFS share removal failed"));
- case EZFS_SHARENFSFAILED:
- return (dgettext(TEXT_DOMAIN, "NFS share creation failed"));
- case EZFS_UNSHARESMBFAILED:
- return (dgettext(TEXT_DOMAIN, "SMB share removal failed"));
- case EZFS_SHARESMBFAILED:
- return (dgettext(TEXT_DOMAIN, "SMB share creation failed"));
- case EZFS_PERM:
- return (dgettext(TEXT_DOMAIN, "permission denied"));
- case EZFS_NOSPC:
- return (dgettext(TEXT_DOMAIN, "out of space"));
- case EZFS_FAULT:
- return (dgettext(TEXT_DOMAIN, "bad address"));
- case EZFS_IO:
- return (dgettext(TEXT_DOMAIN, "I/O error"));
- case EZFS_INTR:
- return (dgettext(TEXT_DOMAIN, "signal received"));
- case EZFS_CKSUM:
- return (dgettext(TEXT_DOMAIN, "insufficient replicas"));
- case EZFS_ISSPARE:
- return (dgettext(TEXT_DOMAIN, "device is reserved as a hot "
- "spare"));
- case EZFS_INVALCONFIG:
- return (dgettext(TEXT_DOMAIN, "invalid vdev configuration"));
- case EZFS_RECURSIVE:
- return (dgettext(TEXT_DOMAIN, "recursive dataset dependency"));
- case EZFS_NOHISTORY:
- return (dgettext(TEXT_DOMAIN, "no history available"));
- case EZFS_POOLPROPS:
- return (dgettext(TEXT_DOMAIN, "failed to retrieve "
- "pool properties"));
- case EZFS_POOL_NOTSUP:
- return (dgettext(TEXT_DOMAIN, "operation not supported "
- "on this type of pool"));
- case EZFS_POOL_INVALARG:
- return (dgettext(TEXT_DOMAIN, "invalid argument for "
- "this pool operation"));
- case EZFS_NAMETOOLONG:
- return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
- case EZFS_OPENFAILED:
- return (dgettext(TEXT_DOMAIN, "open failed"));
- case EZFS_NOCAP:
- return (dgettext(TEXT_DOMAIN,
- "disk capacity information could not be retrieved"));
- case EZFS_LABELFAILED:
- return (dgettext(TEXT_DOMAIN, "write of label failed"));
- case EZFS_BADWHO:
- return (dgettext(TEXT_DOMAIN, "invalid user/group"));
- case EZFS_BADPERM:
- return (dgettext(TEXT_DOMAIN, "invalid permission"));
- case EZFS_BADPERMSET:
- return (dgettext(TEXT_DOMAIN, "invalid permission set name"));
- case EZFS_NODELEGATION:
- return (dgettext(TEXT_DOMAIN, "delegated administration is "
- "disabled on pool"));
- case EZFS_BADCACHE:
- return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
- case EZFS_ISL2CACHE:
- return (dgettext(TEXT_DOMAIN, "device is in use as a cache"));
- case EZFS_VDEVNOTSUP:
- return (dgettext(TEXT_DOMAIN, "vdev specification is not "
- "supported"));
- case EZFS_NOTSUP:
- return (dgettext(TEXT_DOMAIN, "operation not supported "
- "on this dataset"));
- case EZFS_IOC_NOTSUPPORTED:
- return (dgettext(TEXT_DOMAIN, "operation not supported by "
- "zfs kernel module"));
- case EZFS_ACTIVE_SPARE:
- return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
- "device"));
- case EZFS_UNPLAYED_LOGS:
- return (dgettext(TEXT_DOMAIN, "log device has unplayed intent "
- "logs"));
- case EZFS_REFTAG_RELE:
- return (dgettext(TEXT_DOMAIN, "no such tag on this dataset"));
- case EZFS_REFTAG_HOLD:
- return (dgettext(TEXT_DOMAIN, "tag already exists on this "
- "dataset"));
- case EZFS_TAGTOOLONG:
- return (dgettext(TEXT_DOMAIN, "tag too long"));
- case EZFS_PIPEFAILED:
- return (dgettext(TEXT_DOMAIN, "pipe create failed"));
- case EZFS_THREADCREATEFAILED:
- return (dgettext(TEXT_DOMAIN, "thread create failed"));
- case EZFS_POSTSPLIT_ONLINE:
- return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
- "into a new one"));
- case EZFS_SCRUB_PAUSED:
- return (dgettext(TEXT_DOMAIN, "scrub is paused; "
- "use 'zpool scrub' to resume scrub"));
- case EZFS_SCRUB_PAUSED_TO_CANCEL:
- return (dgettext(TEXT_DOMAIN, "scrub is paused; "
- "use 'zpool scrub' to resume or 'zpool scrub -s' to "
- "cancel scrub"));
- case EZFS_SCRUBBING:
- return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
- "use 'zpool scrub -s' to cancel scrub"));
- case EZFS_ERRORSCRUBBING:
- return (dgettext(TEXT_DOMAIN, "currently error scrubbing; "
- "use 'zpool scrub -s' to cancel error scrub"));
- case EZFS_ERRORSCRUB_PAUSED:
- return (dgettext(TEXT_DOMAIN, "error scrub is paused; "
- "use 'zpool scrub -e' to resume error scrub"));
- case EZFS_NO_SCRUB:
- return (dgettext(TEXT_DOMAIN, "there is no active scrub"));
- case EZFS_DIFF:
- return (dgettext(TEXT_DOMAIN, "unable to generate diffs"));
- case EZFS_DIFFDATA:
- return (dgettext(TEXT_DOMAIN, "invalid diff data"));
- case EZFS_POOLREADONLY:
- return (dgettext(TEXT_DOMAIN, "pool is read-only"));
- case EZFS_NO_PENDING:
- return (dgettext(TEXT_DOMAIN, "operation is not "
- "in progress"));
- case EZFS_CHECKPOINT_EXISTS:
- return (dgettext(TEXT_DOMAIN, "checkpoint exists"));
- case EZFS_DISCARDING_CHECKPOINT:
- return (dgettext(TEXT_DOMAIN, "currently discarding "
- "checkpoint"));
- case EZFS_NO_CHECKPOINT:
- return (dgettext(TEXT_DOMAIN, "checkpoint does not exist"));
- case EZFS_DEVRM_IN_PROGRESS:
- return (dgettext(TEXT_DOMAIN, "device removal in progress"));
- case EZFS_VDEV_TOO_BIG:
- return (dgettext(TEXT_DOMAIN, "device exceeds supported size"));
- case EZFS_ACTIVE_POOL:
- return (dgettext(TEXT_DOMAIN, "pool is imported on a "
- "different host"));
- case EZFS_CRYPTOFAILED:
- return (dgettext(TEXT_DOMAIN, "encryption failure"));
- case EZFS_TOOMANY:
- return (dgettext(TEXT_DOMAIN, "argument list too long"));
- case EZFS_INITIALIZING:
- return (dgettext(TEXT_DOMAIN, "currently initializing"));
- case EZFS_NO_INITIALIZE:
- return (dgettext(TEXT_DOMAIN, "there is no active "
- "initialization"));
- case EZFS_WRONG_PARENT:
- return (dgettext(TEXT_DOMAIN, "invalid parent dataset"));
- case EZFS_TRIMMING:
- return (dgettext(TEXT_DOMAIN, "currently trimming"));
- case EZFS_NO_TRIM:
- return (dgettext(TEXT_DOMAIN, "there is no active trim"));
- case EZFS_TRIM_NOTSUP:
- return (dgettext(TEXT_DOMAIN, "trim operations are not "
- "supported by this device"));
- case EZFS_NO_RESILVER_DEFER:
- return (dgettext(TEXT_DOMAIN, "this action requires the "
- "resilver_defer feature"));
- case EZFS_EXPORT_IN_PROGRESS:
- return (dgettext(TEXT_DOMAIN, "pool export in progress"));
- case EZFS_REBUILDING:
- return (dgettext(TEXT_DOMAIN, "currently sequentially "
- "resilvering"));
- case EZFS_VDEV_NOTSUP:
- return (dgettext(TEXT_DOMAIN, "operation not supported "
- "on this type of vdev"));
- case EZFS_NOT_USER_NAMESPACE:
- return (dgettext(TEXT_DOMAIN, "the provided file "
- "was not a user namespace file"));
- case EZFS_RESUME_EXISTS:
- return (dgettext(TEXT_DOMAIN, "Resuming recv on existing "
- "dataset without force"));
- case EZFS_RAIDZ_EXPAND_IN_PROGRESS:
- return (dgettext(TEXT_DOMAIN, "raidz expansion in progress"));
- case EZFS_ASHIFT_MISMATCH:
- return (dgettext(TEXT_DOMAIN, "adding devices with "
- "different physical sector sizes is not allowed"));
- case EZFS_UNKNOWN:
- return (dgettext(TEXT_DOMAIN, "unknown error"));
- default:
- assert(hdl->libzfs_error == 0);
- return (dgettext(TEXT_DOMAIN, "no error"));
- }
-}
-
-void
-zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc),
- fmt, ap);
- hdl->libzfs_desc_active = 1;
-
- va_end(ap);
-}
-
-static void
-zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap)
-{
- (void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action),
- fmt, ap);
- hdl->libzfs_error = error;
-
- if (hdl->libzfs_desc_active)
- hdl->libzfs_desc_active = 0;
- else
- hdl->libzfs_desc[0] = '\0';
-
- if (hdl->libzfs_printerr) {
- if (error == EZFS_UNKNOWN) {
- (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal "
- "error: %s: %s\n"), hdl->libzfs_action,
- libzfs_error_description(hdl));
- abort();
- }
-
- (void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action,
- libzfs_error_description(hdl));
- if (error == EZFS_NOMEM)
- exit(1);
- }
-}
-
-int
-zfs_error(libzfs_handle_t *hdl, int error, const char *msg)
-{
- return (zfs_error_fmt(hdl, error, "%s", msg));
-}
-
-int
-zfs_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- zfs_verror(hdl, error, fmt, ap);
-
- va_end(ap);
-
- return (-1);
-}
-
-static int
-zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
- va_list ap)
-{
- switch (error) {
- case EPERM:
- case EACCES:
- zfs_verror(hdl, EZFS_PERM, fmt, ap);
- return (-1);
-
- case ECANCELED:
- zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap);
- return (-1);
-
- case EIO:
- zfs_verror(hdl, EZFS_IO, fmt, ap);
- return (-1);
-
- case EFAULT:
- zfs_verror(hdl, EZFS_FAULT, fmt, ap);
- return (-1);
-
- case EINTR:
- zfs_verror(hdl, EZFS_INTR, fmt, ap);
- return (-1);
-
- case ECKSUM:
- zfs_verror(hdl, EZFS_CKSUM, fmt, ap);
- return (-1);
- }
-
- return (0);
-}
-
-int
-zfs_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
-{
- return (zfs_standard_error_fmt(hdl, error, "%s", msg));
-}
-
-int
-zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- if (zfs_common_error(hdl, error, fmt, ap) != 0) {
- va_end(ap);
- return (-1);
- }
-
- switch (error) {
- case ENXIO:
- case ENODEV:
- case EPIPE:
- zfs_verror(hdl, EZFS_IO, fmt, ap);
- break;
-
- case ENOENT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset does not exist"));
- zfs_verror(hdl, EZFS_NOENT, fmt, ap);
- break;
-
- case ENOSPC:
- case EDQUOT:
- zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
- break;
-
- case EEXIST:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset already exists"));
- zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
- break;
-
- case EBUSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "dataset is busy"));
- zfs_verror(hdl, EZFS_BUSY, fmt, ap);
- break;
- case EROFS:
- zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
- break;
- case ENAMETOOLONG:
- zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
- break;
- case ENOTSUP:
- zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
- break;
- case EAGAIN:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool I/O is currently suspended"));
- zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
- break;
- case EREMOTEIO:
- zfs_verror(hdl, EZFS_ACTIVE_POOL, fmt, ap);
- break;
- case ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE:
- case ZFS_ERR_IOC_CMD_UNAVAIL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
- "module does not support this operation. A reboot may "
- "be required to enable this operation."));
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_IOC_ARG_UNAVAIL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
- "module does not support an option for this operation. "
- "A reboot may be required to enable this option."));
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_IOC_ARG_REQUIRED:
- case ZFS_ERR_IOC_ARG_BADTYPE:
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_WRONG_PARENT:
- zfs_verror(hdl, EZFS_WRONG_PARENT, fmt, ap);
- break;
- case ZFS_ERR_BADPROP:
- zfs_verror(hdl, EZFS_BADPROP, fmt, ap);
- break;
- case ZFS_ERR_NOT_USER_NAMESPACE:
- zfs_verror(hdl, EZFS_NOT_USER_NAMESPACE, fmt, ap);
- break;
- default:
- zfs_error_aux(hdl, "%s", zfs_strerror(error));
- zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
- break;
- }
-
- va_end(ap);
- return (-1);
-}
-
-void
-zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
- char *errbuf)
-{
- switch (err) {
-
- case ENOSPC:
- /*
- * For quotas and reservations, ENOSPC indicates
- * something different; setting a quota or reservation
- * doesn't use any disk space.
- */
- switch (prop) {
- case ZFS_PROP_QUOTA:
- case ZFS_PROP_REFQUOTA:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "size is less than current used or "
- "reserved space"));
- (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
- break;
-
- case ZFS_PROP_RESERVATION:
- case ZFS_PROP_REFRESERVATION:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "size is greater than available space"));
- (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
- break;
-
- default:
- (void) zfs_standard_error(hdl, err, errbuf);
- break;
- }
- break;
-
- case EBUSY:
- (void) zfs_standard_error(hdl, EBUSY, errbuf);
- break;
-
- case EROFS:
- (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
- break;
-
- case E2BIG:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property value too long"));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- break;
-
- case ENOTSUP:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool and or dataset must be upgraded to set this "
- "property or value"));
- (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
- break;
-
- case ERANGE:
- if (prop == ZFS_PROP_COMPRESSION ||
- prop == ZFS_PROP_DNODESIZE ||
- prop == ZFS_PROP_RECORDSIZE) {
- (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property setting is not allowed on "
- "bootable datasets"));
- (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
- } else if (prop == ZFS_PROP_CHECKSUM ||
- prop == ZFS_PROP_DEDUP) {
- (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property setting is not allowed on "
- "root pools"));
- (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
- } else {
- (void) zfs_standard_error(hdl, err, errbuf);
- }
- break;
-
- case EINVAL:
- if (prop == ZPROP_INVAL) {
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- } else {
- (void) zfs_standard_error(hdl, err, errbuf);
- }
- break;
-
- case ZFS_ERR_BADPROP:
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- break;
-
- case EACCES:
- if (prop == ZFS_PROP_KEYLOCATION) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "keylocation may only be set on encryption roots"));
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- } else {
- (void) zfs_standard_error(hdl, err, errbuf);
- }
- break;
-
- case EOVERFLOW:
- /*
- * This platform can't address a volume this big.
- */
-#ifdef _ILP32
- if (prop == ZFS_PROP_VOLSIZE) {
- (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
- break;
- }
- zfs_fallthrough;
-#endif
- default:
- (void) zfs_standard_error(hdl, err, errbuf);
- }
-}
-
-int
-zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg)
-{
- return (zpool_standard_error_fmt(hdl, error, "%s", msg));
-}
-
-int
-zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- if (zfs_common_error(hdl, error, fmt, ap) != 0) {
- va_end(ap);
- return (-1);
- }
-
- switch (error) {
- case ENODEV:
- zfs_verror(hdl, EZFS_NODEVICE, fmt, ap);
- break;
-
- case ENOENT:
- zfs_error_aux(hdl,
- dgettext(TEXT_DOMAIN, "no such pool or dataset"));
- zfs_verror(hdl, EZFS_NOENT, fmt, ap);
- break;
-
- case EEXIST:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool already exists"));
- zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
- break;
-
- case EBUSY:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
- zfs_verror(hdl, EZFS_BUSY, fmt, ap);
- break;
-
- /* There is no pending operation to cancel */
- case ENOTACTIVE:
- zfs_verror(hdl, EZFS_NO_PENDING, fmt, ap);
- break;
-
- case ENXIO:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "one or more devices is currently unavailable"));
- zfs_verror(hdl, EZFS_BADDEV, fmt, ap);
- break;
-
- case ENAMETOOLONG:
- zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap);
- break;
-
- case ENOTSUP:
- zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap);
- break;
-
- case EINVAL:
- zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
- break;
-
- case ENOSPC:
- case EDQUOT:
- zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
- break;
-
- case EAGAIN:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pool I/O is currently suspended"));
- zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap);
- break;
-
- case EROFS:
- zfs_verror(hdl, EZFS_POOLREADONLY, fmt, ap);
- break;
- case EDOM:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "block size out of range or does not match"));
- zfs_verror(hdl, EZFS_BADPROP, fmt, ap);
- break;
- case EREMOTEIO:
- zfs_verror(hdl, EZFS_ACTIVE_POOL, fmt, ap);
- break;
- case ZFS_ERR_CHECKPOINT_EXISTS:
- zfs_verror(hdl, EZFS_CHECKPOINT_EXISTS, fmt, ap);
- break;
- case ZFS_ERR_DISCARDING_CHECKPOINT:
- zfs_verror(hdl, EZFS_DISCARDING_CHECKPOINT, fmt, ap);
- break;
- case ZFS_ERR_NO_CHECKPOINT:
- zfs_verror(hdl, EZFS_NO_CHECKPOINT, fmt, ap);
- break;
- case ZFS_ERR_DEVRM_IN_PROGRESS:
- zfs_verror(hdl, EZFS_DEVRM_IN_PROGRESS, fmt, ap);
- break;
- case ZFS_ERR_VDEV_TOO_BIG:
- zfs_verror(hdl, EZFS_VDEV_TOO_BIG, fmt, ap);
- break;
- case ZFS_ERR_EXPORT_IN_PROGRESS:
- zfs_verror(hdl, EZFS_EXPORT_IN_PROGRESS, fmt, ap);
- break;
- case ZFS_ERR_RESILVER_IN_PROGRESS:
- zfs_verror(hdl, EZFS_RESILVERING, fmt, ap);
- break;
- case ZFS_ERR_REBUILD_IN_PROGRESS:
- zfs_verror(hdl, EZFS_REBUILDING, fmt, ap);
- break;
- case ZFS_ERR_BADPROP:
- zfs_verror(hdl, EZFS_BADPROP, fmt, ap);
- break;
- case ZFS_ERR_VDEV_NOTSUP:
- zfs_verror(hdl, EZFS_VDEV_NOTSUP, fmt, ap);
- break;
- case ZFS_ERR_IOC_CMD_UNAVAIL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
- "module does not support this operation. A reboot may "
- "be required to enable this operation."));
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_IOC_ARG_UNAVAIL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
- "module does not support an option for this operation. "
- "A reboot may be required to enable this option."));
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_IOC_ARG_REQUIRED:
- case ZFS_ERR_IOC_ARG_BADTYPE:
- zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
- break;
- case ZFS_ERR_RAIDZ_EXPAND_IN_PROGRESS:
- zfs_verror(hdl, EZFS_RAIDZ_EXPAND_IN_PROGRESS, fmt, ap);
- break;
- case ZFS_ERR_ASHIFT_MISMATCH:
- zfs_verror(hdl, EZFS_ASHIFT_MISMATCH, fmt, ap);
- break;
- case ZFS_ERR_TOO_MANY_SITOUTS:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "too many disks "
- "already sitting out"));
- zfs_verror(hdl, EZFS_BUSY, fmt, ap);
- break;
- default:
- zfs_error_aux(hdl, "%s", zfs_strerror(error));
- zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
- }
-
- va_end(ap);
- return (-1);
-}
-
-int
-zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
-{
- return (lzc_ioctl_fd(hdl->libzfs_fd, request, zc));
-}
-
-/*
- * Display an out of memory error message and abort the current program.
- */
-int
-no_memory(libzfs_handle_t *hdl)
-{
- return (zfs_error(hdl, EZFS_NOMEM, "internal error"));
-}
-
-/*
- * A safe form of malloc() which will die if the allocation fails.
- */
-void *
-zfs_alloc(libzfs_handle_t *hdl, size_t size)
-{
- void *data;
-
- if ((data = calloc(1, size)) == NULL)
- (void) no_memory(hdl);
-
- return (data);
-}
-
-/*
- * A safe form of asprintf() which will die if the allocation fails.
- */
-char *
-zfs_asprintf(libzfs_handle_t *hdl, const char *fmt, ...)
-{
- va_list ap;
- char *ret;
- int err;
-
- va_start(ap, fmt);
-
- err = vasprintf(&ret, fmt, ap);
-
- va_end(ap);
-
- if (err < 0) {
- (void) no_memory(hdl);
- ret = NULL;
- }
-
- return (ret);
-}
-
-/*
- * A safe form of realloc(), which also zeroes newly allocated space.
- */
-void *
-zfs_realloc(libzfs_handle_t *hdl, void *ptr, size_t oldsize, size_t newsize)
-{
- void *ret;
-
- if ((ret = realloc(ptr, newsize)) == NULL) {
- (void) no_memory(hdl);
- return (NULL);
- }
-
- memset((char *)ret + oldsize, 0, newsize - oldsize);
- return (ret);
-}
-
-/*
- * A safe form of strdup() which will die if the allocation fails.
- */
-char *
-zfs_strdup(libzfs_handle_t *hdl, const char *str)
-{
- char *ret;
-
- if ((ret = strdup(str)) == NULL)
- (void) no_memory(hdl);
-
- return (ret);
-}
-
-void
-libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr)
-{
- hdl->libzfs_printerr = printerr;
-}
-
-/*
- * Read lines from an open file descriptor and store them in an array of
- * strings until EOF. lines[] will be allocated and populated with all the
- * lines read. All newlines are replaced with NULL terminators for
- * convenience. lines[] must be freed after use with libzfs_free_str_array().
- *
- * Returns the number of lines read.
- */
-static int
-libzfs_read_stdout_from_fd(int fd, char **lines[])
-{
-
- FILE *fp;
- int lines_cnt = 0;
- size_t len = 0;
- char *line = NULL;
- char **tmp_lines = NULL, **tmp;
-
- fp = fdopen(fd, "r");
- if (fp == NULL) {
- close(fd);
- return (0);
- }
- 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 */
- break;
- }
- tmp_lines = tmp;
-
- /* 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);
-}
-
-static int
-libzfs_run_process_impl(const char *path, char *argv[], char *env[], int flags,
- char **lines[], int *lines_cnt)
-{
- pid_t pid;
- int error, devnull_fd;
- int link[2];
-
- /*
- * Setup a pipe between our child and parent process if we're
- * reading stdout.
- */
- if (lines != NULL && pipe2(link, O_NONBLOCK | O_CLOEXEC) == -1)
- return (-EPIPE);
-
- pid = fork();
- if (pid == 0) {
- /* Child process */
- setpgid(0, 0);
- devnull_fd = open("/dev/null", O_WRONLY | O_CLOEXEC);
-
- if (devnull_fd < 0)
- _exit(-1);
-
- if (!(flags & STDOUT_VERBOSE) && (lines == NULL))
- (void) dup2(devnull_fd, STDOUT_FILENO);
- else if (lines != NULL) {
- /* Save the output to lines[] */
- dup2(link[1], STDOUT_FILENO);
- }
-
- if (!(flags & STDERR_VERBOSE))
- (void) dup2(devnull_fd, STDERR_FILENO);
-
- if (flags & NO_DEFAULT_PATH) {
- if (env == NULL)
- execv(path, argv);
- else
- execve(path, argv, env);
- } else {
- if (env == NULL)
- execvp(path, argv);
- else
- execvpe(path, argv, env);
- }
-
- _exit(-1);
- } else if (pid > 0) {
- /* Parent process */
- int status;
-
- while ((error = waitpid(pid, &status, 0)) == -1 &&
- errno == EINTR)
- ;
- if (error < 0 || !WIFEXITED(status))
- return (-1);
-
- if (lines != NULL) {
- close(link[1]);
- *lines_cnt = libzfs_read_stdout_from_fd(link[0], lines);
- }
- return (WEXITSTATUS(status));
- }
-
- return (-1);
-}
-
-int
-libzfs_run_process(const char *path, char *argv[], int flags)
-{
- return (libzfs_run_process_impl(path, argv, NULL, flags, NULL, NULL));
-}
-
-/*
- * Run a command and store its stdout lines in an array of strings (lines[]).
- * lines[] is allocated and populated for you, and the number of lines is set in
- * lines_cnt. lines[] must be freed after use with libzfs_free_str_array().
- * All newlines (\n) in lines[] are terminated for convenience.
- */
-int
-libzfs_run_process_get_stdout(const char *path, char *argv[], char *env[],
- char **lines[], int *lines_cnt)
-{
- return (libzfs_run_process_impl(path, argv, env, 0, lines, lines_cnt));
-}
-
-/*
- * Same as libzfs_run_process_get_stdout(), but run without $PATH set. This
- * means that *path needs to be the full path to the executable.
- */
-int
-libzfs_run_process_get_stdout_nopath(const char *path, char *argv[],
- char *env[], char **lines[], int *lines_cnt)
-{
- return (libzfs_run_process_impl(path, argv, env, NO_DEFAULT_PATH,
- lines, lines_cnt));
-}
-
-/*
- * Free an array of strings. Free both the strings contained in the array and
- * the array itself.
- */
-void
-libzfs_free_str_array(char **strs, int count)
-{
- while (--count >= 0)
- free(strs[count]);
-
- free(strs);
-}
-
-/*
- * Returns 1 if environment variable is set to "YES", "yes", "ON", "on", or
- * a non-zero number.
- *
- * Returns 0 otherwise.
- */
-boolean_t
-libzfs_envvar_is_set(const char *envvar)
-{
- char *env = getenv(envvar);
- return (env && (strtoul(env, NULL, 0) > 0 ||
- (!strncasecmp(env, "YES", 3) && strnlen(env, 4) == 3) ||
- (!strncasecmp(env, "ON", 2) && strnlen(env, 3) == 2)));
-}
-
-libzfs_handle_t *
-libzfs_init(void)
-{
- libzfs_handle_t *hdl;
- int error;
- char *env;
-
- if ((error = libzfs_load_module()) != 0) {
- errno = error;
- return (NULL);
- }
-
- if ((hdl = calloc(1, sizeof (libzfs_handle_t))) == NULL) {
- return (NULL);
- }
-
- if (regcomp(&hdl->libzfs_urire, URI_REGEX, 0) != 0) {
- free(hdl);
- return (NULL);
- }
-
- 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);
- free(hdl);
- return (NULL);
- }
-
- zfs_prop_init();
- zpool_prop_init();
- zpool_feature_init();
- vdev_prop_init();
- libzfs_mnttab_init(hdl);
- fletcher_4_init();
-
- if (getenv("ZFS_PROP_DEBUG") != NULL) {
- hdl->libzfs_prop_debug = B_TRUE;
- }
- if ((env = getenv("ZFS_SENDRECV_MAX_NVLIST")) != NULL) {
- if ((error = zfs_nicestrtonum(hdl, env,
- &hdl->libzfs_max_nvlist))) {
- errno = error;
- (void) close(hdl->libzfs_fd);
- free(hdl);
- return (NULL);
- }
- } else {
- hdl->libzfs_max_nvlist = (SPA_MAXBLOCKSIZE * 4);
- }
-
- /*
- * For testing, remove some settable properties and features
- */
- if (libzfs_envvar_is_set("ZFS_SYSFS_PROP_SUPPORT_TEST")) {
- zprop_desc_t *proptbl;
-
- proptbl = zpool_prop_get_table();
- proptbl[ZPOOL_PROP_COMMENT].pd_zfs_mod_supported = B_FALSE;
-
- proptbl = zfs_prop_get_table();
- proptbl[ZFS_PROP_DNODESIZE].pd_zfs_mod_supported = B_FALSE;
-
- zfeature_info_t *ftbl = spa_feature_table;
- ftbl[SPA_FEATURE_LARGE_BLOCKS].fi_zfs_mod_supported = B_FALSE;
- }
-
- return (hdl);
-}
-
-void
-libzfs_fini(libzfs_handle_t *hdl)
-{
- (void) close(hdl->libzfs_fd);
- 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);
-}
-
-libzfs_handle_t *
-zpool_get_handle(zpool_handle_t *zhp)
-{
- return (zhp->zpool_hdl);
-}
-
-libzfs_handle_t *
-zfs_get_handle(zfs_handle_t *zhp)
-{
- return (zhp->zfs_hdl);
-}
-
-zpool_handle_t *
-zfs_get_pool_handle(const zfs_handle_t *zhp)
-{
- return (zhp->zpool_hdl);
-}
-
-/*
- * Given a name, determine whether or not it's a valid path
- * (starts with '/' or "./"). If so, walk the mnttab trying
- * to match the device number. If not, treat the path as an
- * fs/vol/snap/bkmark name.
- */
-zfs_handle_t *
-zfs_path_to_zhandle(libzfs_handle_t *hdl, const char *path, zfs_type_t argtype)
-{
- struct stat64 statbuf;
- struct extmnttab entry;
-
- if (path[0] != '/' && strncmp(path, "./", strlen("./")) != 0) {
- /*
- * It's not a valid path, assume it's a name of type 'argtype'.
- */
- return (zfs_open(hdl, path, argtype));
- }
-
- if (getextmntent(path, &entry, &statbuf) != 0)
- return (NULL);
-
- if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) {
- (void) fprintf(stderr, gettext("'%s': not a ZFS filesystem\n"),
- path);
- return (NULL);
- }
-
- return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM));
-}
-
-/*
- * Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from
- * an ioctl().
- */
-void
-zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len)
-{
- if (len == 0)
- len = 256 * 1024;
- zc->zc_nvlist_dst_size = len;
- zc->zc_nvlist_dst =
- (uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
-}
-
-/*
- * Called when an ioctl() which returns an nvlist fails with ENOMEM. This will
- * expand the nvlist to the size specified in 'zc_nvlist_dst_size', which was
- * filled in by the kernel to indicate the actual required size.
- */
-void
-zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
-{
- free((void *)(uintptr_t)zc->zc_nvlist_dst);
- zc->zc_nvlist_dst =
- (uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
-}
-
-/*
- * Called to free the src and dst nvlists stored in the command structure.
- */
-void
-zcmd_free_nvlists(zfs_cmd_t *zc)
-{
- free((void *)(uintptr_t)zc->zc_nvlist_conf);
- free((void *)(uintptr_t)zc->zc_nvlist_src);
- free((void *)(uintptr_t)zc->zc_nvlist_dst);
- zc->zc_nvlist_conf = 0;
- zc->zc_nvlist_src = 0;
- zc->zc_nvlist_dst = 0;
-}
-
-static void
-zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
- nvlist_t *nvl)
-{
- char *packed;
-
- size_t len = fnvlist_size(nvl);
- packed = zfs_alloc(hdl, len);
-
- verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
-
- *outnv = (uint64_t)(uintptr_t)packed;
- *outlen = len;
-}
-
-void
-zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
-{
- zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf,
- &zc->zc_nvlist_conf_size, nvl);
-}
-
-void
-zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
-{
- zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
- &zc->zc_nvlist_src_size, nvl);
-}
-
-/*
- * Unpacks an nvlist from the ZFS ioctl command structure.
- */
-int
-zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
-{
- if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst,
- zc->zc_nvlist_dst_size, nvlp, 0) != 0)
- return (no_memory(hdl));
-
- return (0);
-}
-
-/*
- * ================================================================
- * API shared by zfs and zpool property management
- * ================================================================
- */
-
-void
-zcmd_print_json(nvlist_t *nvl)
-{
- nvlist_print_json(stdout, nvl);
- (void) putchar('\n');
- nvlist_free(nvl);
-}
-
-static void
-zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
-{
- zprop_list_t *pl;
- int i;
- char *title;
- size_t len;
-
- cbp->cb_first = B_FALSE;
- if (cbp->cb_scripted)
- return;
-
- /*
- * Start with the length of the column headers.
- */
- cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN, "NAME"));
- cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN,
- "PROPERTY"));
- cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN,
- "VALUE"));
- cbp->cb_colwidths[GET_COL_RECVD] = strlen(dgettext(TEXT_DOMAIN,
- "RECEIVED"));
- cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN,
- "SOURCE"));
-
- /* first property is always NAME */
- assert(cbp->cb_proplist->pl_prop ==
- ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
- ((type == ZFS_TYPE_VDEV) ? VDEV_PROP_NAME : ZFS_PROP_NAME)));
-
- /*
- * Go through and calculate the widths for each column. For the
- * 'source' column, we kludge it up by taking the worst-case scenario of
- * inheriting from the longest name. This is acceptable because in the
- * majority of cases 'SOURCE' is the last column displayed, and we don't
- * use the width anyway. Note that the 'VALUE' column can be oversized,
- * if the name of the property is much longer than any values we find.
- */
- for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
- /*
- * 'PROPERTY' column
- */
- if (pl->pl_prop != ZPROP_USERPROP) {
- const char *propname = (type == ZFS_TYPE_POOL) ?
- zpool_prop_to_name(pl->pl_prop) :
- ((type == ZFS_TYPE_VDEV) ?
- vdev_prop_to_name(pl->pl_prop) :
- zfs_prop_to_name(pl->pl_prop));
-
- assert(propname != NULL);
- len = strlen(propname);
- if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
- cbp->cb_colwidths[GET_COL_PROPERTY] = len;
- } else {
- assert(pl->pl_user_prop != NULL);
- len = strlen(pl->pl_user_prop);
- if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
- cbp->cb_colwidths[GET_COL_PROPERTY] = len;
- }
-
- /*
- * 'VALUE' column. The first property is always the 'name'
- * property that was tacked on either by /sbin/zfs's
- * zfs_do_get() or when calling zprop_expand_list(), so we
- * ignore its width. If the user specified the name property
- * to display, then it will be later in the list in any case.
- */
- if (pl != cbp->cb_proplist &&
- pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE])
- cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width;
-
- /* 'RECEIVED' column. */
- if (pl != cbp->cb_proplist &&
- pl->pl_recvd_width > cbp->cb_colwidths[GET_COL_RECVD])
- cbp->cb_colwidths[GET_COL_RECVD] = pl->pl_recvd_width;
-
- /*
- * 'NAME' and 'SOURCE' columns
- */
- if (pl->pl_prop == ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
- ((type == ZFS_TYPE_VDEV) ? VDEV_PROP_NAME :
- ZFS_PROP_NAME)) && pl->pl_width >
- cbp->cb_colwidths[GET_COL_NAME]) {
- cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
- cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
- strlen(dgettext(TEXT_DOMAIN, "inherited from"));
- }
- }
-
- /*
- * Now go through and print the headers.
- */
- for (i = 0; i < ZFS_GET_NCOLS; i++) {
- switch (cbp->cb_columns[i]) {
- case GET_COL_NAME:
- title = dgettext(TEXT_DOMAIN, "NAME");
- break;
- case GET_COL_PROPERTY:
- title = dgettext(TEXT_DOMAIN, "PROPERTY");
- break;
- case GET_COL_VALUE:
- title = dgettext(TEXT_DOMAIN, "VALUE");
- break;
- case GET_COL_RECVD:
- title = dgettext(TEXT_DOMAIN, "RECEIVED");
- break;
- case GET_COL_SOURCE:
- title = dgettext(TEXT_DOMAIN, "SOURCE");
- break;
- default:
- title = NULL;
- }
-
- if (title != NULL) {
- if (i == (ZFS_GET_NCOLS - 1) ||
- cbp->cb_columns[i + 1] == GET_COL_NONE)
- (void) printf("%s", title);
- else
- (void) printf("%-*s ",
- cbp->cb_colwidths[cbp->cb_columns[i]],
- title);
- }
- }
- (void) printf("\n");
-}
-
-/*
- * Add property value and source to provided nvlist, according to
- * settings in cb structure. Later to be printed in JSON format.
- */
-int
-zprop_nvlist_one_property(const char *propname,
- const char *value, zprop_source_t sourcetype, const char *source,
- const char *recvd_value, nvlist_t *nvl, boolean_t as_int)
-{
- int ret = 0;
- nvlist_t *src_nv, *prop;
- boolean_t all_numeric = strspn(value, STR_NUMS) == strlen(value);
- src_nv = prop = NULL;
-
- if ((nvlist_alloc(&prop, NV_UNIQUE_NAME, 0) != 0) ||
- (nvlist_alloc(&src_nv, NV_UNIQUE_NAME, 0) != 0)) {
- ret = -1;
- goto err;
- }
-
- if (as_int && all_numeric) {
- uint64_t val;
- sscanf(value, "%lld", (u_longlong_t *)&val);
- if (nvlist_add_uint64(prop, "value", val) != 0) {
- ret = -1;
- goto err;
- }
- } else {
- if (nvlist_add_string(prop, "value", value) != 0) {
- ret = -1;
- goto err;
- }
- }
-
- switch (sourcetype) {
- case ZPROP_SRC_NONE:
- if (nvlist_add_string(src_nv, "type", "NONE") != 0 ||
- (nvlist_add_string(src_nv, "data", "-") != 0)) {
- ret = -1;
- goto err;
- }
- break;
- case ZPROP_SRC_DEFAULT:
- if (nvlist_add_string(src_nv, "type", "DEFAULT") != 0 ||
- (nvlist_add_string(src_nv, "data", "-") != 0)) {
- ret = -1;
- goto err;
- }
- break;
- case ZPROP_SRC_LOCAL:
- if (nvlist_add_string(src_nv, "type", "LOCAL") != 0 ||
- (nvlist_add_string(src_nv, "data", "-") != 0)) {
- ret = -1;
- goto err;
- }
- break;
- case ZPROP_SRC_TEMPORARY:
- if (nvlist_add_string(src_nv, "type", "TEMPORARY") != 0 ||
- (nvlist_add_string(src_nv, "data", "-") != 0)) {
- ret = -1;
- goto err;
- }
- break;
- case ZPROP_SRC_INHERITED:
- if (nvlist_add_string(src_nv, "type", "INHERITED") != 0 ||
- (nvlist_add_string(src_nv, "data", source) != 0)) {
- ret = -1;
- goto err;
- }
- break;
- case ZPROP_SRC_RECEIVED:
- if (nvlist_add_string(src_nv, "type", "RECEIVED") != 0 ||
- (nvlist_add_string(src_nv, "data",
- (recvd_value == NULL ? "-" : recvd_value)) != 0)) {
- ret = -1;
- goto err;
- }
- break;
- default:
- assert(!"unhandled zprop_source_t");
- if (nvlist_add_string(src_nv, "type",
- "unhandled zprop_source_t") != 0) {
- ret = -1;
- goto err;
- }
- }
- if ((nvlist_add_nvlist(prop, "source", src_nv) != 0) ||
- (nvlist_add_nvlist(nvl, propname, prop)) != 0) {
- ret = -1;
- goto err;
- }
-err:
- nvlist_free(src_nv);
- nvlist_free(prop);
- return (ret);
-}
-
-/*
- * Display a single line of output, according to the settings in the callback
- * structure.
- */
-void
-zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
- const char *propname, const char *value, zprop_source_t sourcetype,
- const char *source, const char *recvd_value)
-{
- int i;
- const char *str = NULL;
- char buf[128];
-
- /*
- * Ignore those source types that the user has chosen to ignore.
- */
- if ((sourcetype & cbp->cb_sources) == 0)
- return;
-
- if (cbp->cb_first)
- zprop_print_headers(cbp, cbp->cb_type);
-
- for (i = 0; i < ZFS_GET_NCOLS; i++) {
- switch (cbp->cb_columns[i]) {
- case GET_COL_NAME:
- str = name;
- break;
-
- case GET_COL_PROPERTY:
- str = propname;
- break;
-
- case GET_COL_VALUE:
- str = value;
- break;
-
- case GET_COL_SOURCE:
- switch (sourcetype) {
- case ZPROP_SRC_NONE:
- str = "-";
- break;
-
- case ZPROP_SRC_DEFAULT:
- str = "default";
- break;
-
- case ZPROP_SRC_LOCAL:
- str = "local";
- break;
-
- case ZPROP_SRC_TEMPORARY:
- str = "temporary";
- break;
-
- case ZPROP_SRC_INHERITED:
- (void) snprintf(buf, sizeof (buf),
- "inherited from %s", source);
- str = buf;
- break;
- case ZPROP_SRC_RECEIVED:
- str = "received";
- break;
-
- default:
- str = NULL;
- assert(!"unhandled zprop_source_t");
- }
- break;
-
- case GET_COL_RECVD:
- str = (recvd_value == NULL ? "-" : recvd_value);
- break;
-
- default:
- continue;
- }
-
- if (i == (ZFS_GET_NCOLS - 1) ||
- cbp->cb_columns[i + 1] == GET_COL_NONE)
- (void) printf("%s", str);
- else if (cbp->cb_scripted)
- (void) printf("%s\t", str);
- else
- (void) printf("%-*s ",
- cbp->cb_colwidths[cbp->cb_columns[i]],
- str);
- }
-
- (void) printf("\n");
-}
-
-int
-zprop_collect_property(const char *name, zprop_get_cbdata_t *cbp,
- const char *propname, const char *value, zprop_source_t sourcetype,
- const char *source, const char *recvd_value, nvlist_t *nvl)
-{
- if (cbp->cb_json) {
- if ((sourcetype & cbp->cb_sources) == 0)
- return (0);
- else {
- return (zprop_nvlist_one_property(propname, value,
- sourcetype, source, recvd_value, nvl,
- cbp->cb_json_as_int));
- }
- } else {
- zprop_print_one_property(name, cbp,
- propname, value, sourcetype, source, recvd_value);
- return (0);
- }
-}
-
-/*
- * Given a numeric suffix, convert the value into a number of bits that the
- * resulting value must be shifted.
- */
-static int
-str2shift(libzfs_handle_t *hdl, const char *buf)
-{
- const char *ends = "BKMGTPEZ";
- int i, len;
-
- if (buf[0] == '\0')
- return (0);
-
- len = strlen(ends);
- for (i = 0; i < len; i++) {
- if (toupper(buf[0]) == ends[i])
- break;
- }
- if (i == len) {
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid numeric suffix '%s'"), buf);
- return (-1);
- }
-
- /*
- * Allow 'G' = 'GB' = 'GiB', case-insensitively.
- * However, 'BB' and 'BiB' are disallowed.
- */
- if (buf[1] == '\0' ||
- (toupper(buf[0]) != 'B' &&
- ((toupper(buf[1]) == 'B' && buf[2] == '\0') ||
- (toupper(buf[1]) == 'I' && toupper(buf[2]) == 'B' &&
- buf[3] == '\0'))))
- return (10 * i);
-
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid numeric suffix '%s'"), buf);
- return (-1);
-}
-
-/*
- * Convert a string of the form '100G' into a real number. Used when setting
- * properties or creating a volume. 'buf' is used to place an extended error
- * message for the caller to use.
- */
-int
-zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
-{
- char *end;
- int shift;
-
- *num = 0;
-
- /* Check to see if this looks like a number. */
- if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "bad numeric value '%s'"), value);
- return (-1);
- }
-
- /* Rely on strtoull() to process the numeric portion. */
- errno = 0;
- *num = strtoull(value, &end, 10);
-
- /*
- * Check for ERANGE, which indicates that the value is too large to fit
- * in a 64-bit value.
- */
- if (errno == ERANGE) {
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "numeric value is too large"));
- return (-1);
- }
-
- /*
- * If we have a decimal value, then do the computation with floating
- * point arithmetic. Otherwise, use standard arithmetic.
- */
- if (*end == '.') {
- double fval = strtod(value, &end);
-
- if ((shift = str2shift(hdl, end)) == -1)
- return (-1);
-
- fval *= pow(2, shift);
-
- /*
- * UINT64_MAX is not exactly representable as a double.
- * The closest representation is UINT64_MAX + 1, so we
- * use a >= comparison instead of > for the bounds check.
- */
- if (fval >= (double)UINT64_MAX) {
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "numeric value is too large"));
- return (-1);
- }
-
- *num = (uint64_t)fval;
- } else {
- if ((shift = str2shift(hdl, end)) == -1)
- return (-1);
-
- /* Check for overflow */
- if (shift >= 64 || (*num << shift) >> shift != *num) {
- if (hdl)
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "numeric value is too large"));
- return (-1);
- }
-
- *num <<= shift;
- }
-
- return (0);
-}
-
-/*
- * Given a propname=value nvpair to set, parse any numeric properties
- * (index, boolean, etc) if they are specified as strings and add the
- * resulting nvpair to the returned nvlist.
- *
- * At the DSL layer, all properties are either 64-bit numbers or strings.
- * We want the user to be able to ignore this fact and specify properties
- * as native values (numbers, for example) or as strings (to simplify
- * command line utilities). This also handles converting index types
- * (compression, checksum, etc) from strings to their on-disk index.
- */
-int
-zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
- zfs_type_t type, nvlist_t *ret, const char **svalp, uint64_t *ivalp,
- const char *errbuf)
-{
- data_type_t datatype = nvpair_type(elem);
- zprop_type_t proptype;
- const char *propname;
- const char *value;
- boolean_t isnone = B_FALSE;
- boolean_t isauto = B_FALSE;
- int err = 0;
-
- if (type == ZFS_TYPE_POOL) {
- proptype = zpool_prop_get_type(prop);
- propname = zpool_prop_to_name(prop);
- } else if (type == ZFS_TYPE_VDEV) {
- proptype = vdev_prop_get_type(prop);
- propname = vdev_prop_to_name(prop);
- } else {
- proptype = zfs_prop_get_type(prop);
- propname = zfs_prop_to_name(prop);
- }
-
- /*
- * Convert any properties to the internal DSL value types.
- */
- *svalp = NULL;
- *ivalp = 0;
-
- switch (proptype) {
- case PROP_TYPE_STRING:
- if (datatype != DATA_TYPE_STRING) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a string"), nvpair_name(elem));
- goto error;
- }
- err = nvpair_value_string(elem, svalp);
- if (err != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is invalid"), nvpair_name(elem));
- goto error;
- }
- if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' is too long"), nvpair_name(elem));
- goto error;
- }
- break;
-
- case PROP_TYPE_NUMBER:
- if (datatype == DATA_TYPE_STRING) {
- (void) nvpair_value_string(elem, &value);
- if (strcmp(value, "none") == 0) {
- isnone = B_TRUE;
- } else if (strcmp(value, "auto") == 0) {
- isauto = B_TRUE;
- } else if (zfs_nicestrtonum(hdl, value, ivalp) != 0) {
- goto error;
- }
- } else if (datatype == DATA_TYPE_UINT64) {
- (void) nvpair_value_uint64(elem, ivalp);
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a number"), nvpair_name(elem));
- goto error;
- }
-
- /*
- * Quota special: force 'none' and don't allow 0.
- */
- if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
- (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "use 'none' to disable quota/refquota"));
- goto error;
- }
- /*
- * Pool dedup table quota; force use of 'none' instead of 0
- */
- if ((type & ZFS_TYPE_POOL) && *ivalp == 0 &&
- (!isnone && !isauto) &&
- prop == ZPOOL_PROP_DEDUP_TABLE_QUOTA) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "use 'none' to disable ddt table quota"));
- goto error;
- }
-
- /*
- * Special handling for "*_limit=none". In this case it's not
- * 0 but UINT64_MAX.
- */
- if ((type & ZFS_TYPE_DATASET) && isnone &&
- (prop == ZFS_PROP_FILESYSTEM_LIMIT ||
- prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
- *ivalp = UINT64_MAX;
- }
-
- /*
- * Special handling for "checksum_*=none". In this case it's not
- * 0 but UINT64_MAX.
- */
- if ((type & ZFS_TYPE_VDEV) && isnone &&
- (prop == VDEV_PROP_CHECKSUM_N ||
- prop == VDEV_PROP_CHECKSUM_T ||
- prop == VDEV_PROP_IO_N ||
- prop == VDEV_PROP_IO_T ||
- prop == VDEV_PROP_SLOW_IO_N ||
- prop == VDEV_PROP_SLOW_IO_T)) {
- *ivalp = UINT64_MAX;
- }
-
- /*
- * Special handling for setting 'refreservation' to 'auto'. Use
- * UINT64_MAX to tell the caller to use zfs_fix_auto_resv().
- * 'auto' is only allowed on volumes.
- */
- if (isauto) {
- switch (prop) {
- case ZFS_PROP_REFRESERVATION:
- if ((type & ZFS_TYPE_VOLUME) == 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s=auto' only allowed on "
- "volumes"), nvpair_name(elem));
- goto error;
- }
- *ivalp = UINT64_MAX;
- break;
- case ZPOOL_PROP_DEDUP_TABLE_QUOTA:
- ASSERT(type & ZFS_TYPE_POOL);
- *ivalp = UINT64_MAX;
- break;
- default:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'auto' is invalid value for '%s'"),
- nvpair_name(elem));
- goto error;
- }
- }
-
- break;
-
- case PROP_TYPE_INDEX:
- if (datatype != DATA_TYPE_STRING) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be a string"), nvpair_name(elem));
- goto error;
- }
-
- (void) nvpair_value_string(elem, &value);
-
- if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "'%s' must be one of '%s'"), propname,
- zprop_values(prop, type));
- goto error;
- }
- break;
-
- default:
- abort();
- }
-
- /*
- * Add the result to our return set of properties.
- */
- if (*svalp != NULL) {
- if (nvlist_add_string(ret, propname, *svalp) != 0) {
- (void) no_memory(hdl);
- return (-1);
- }
- } else {
- if (nvlist_add_uint64(ret, propname, *ivalp) != 0) {
- (void) no_memory(hdl);
- return (-1);
- }
- }
-
- return (0);
-error:
- (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
- return (-1);
-}
-
-static int
-addlist(libzfs_handle_t *hdl, const char *propname, zprop_list_t **listp,
- zfs_type_t type)
-{
- int prop = zprop_name_to_prop(propname, type);
- if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type, B_FALSE))
- prop = ZPROP_INVAL;
-
- /*
- * Return failure if no property table entry was found and this isn't
- * a user-defined property.
- */
- if (prop == ZPROP_USERPROP && ((type == ZFS_TYPE_POOL &&
- !zfs_prop_user(propname) &&
- !zpool_prop_feature(propname) &&
- !zpool_prop_unsupported(propname)) ||
- ((type == ZFS_TYPE_DATASET) && !zfs_prop_user(propname) &&
- !zfs_prop_userquota(propname) && !zfs_prop_written(propname)) ||
- ((type == ZFS_TYPE_VDEV) && !vdev_prop_user(propname)))) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid property '%s'"), propname);
- return (zfs_error(hdl, EZFS_BADPROP,
- dgettext(TEXT_DOMAIN, "bad property list")));
- }
-
- zprop_list_t *entry = zfs_alloc(hdl, sizeof (*entry));
-
- entry->pl_prop = prop;
- if (prop == ZPROP_USERPROP) {
- entry->pl_user_prop = zfs_strdup(hdl, propname);
- entry->pl_width = strlen(propname);
- } else {
- entry->pl_width = zprop_width(prop, &entry->pl_fixed,
- type);
- }
-
- *listp = entry;
-
- return (0);
-}
-
-/*
- * Given a comma-separated list of properties, construct a property list
- * containing both user-defined and native properties. This function will
- * return a NULL list if 'all' is specified, which can later be expanded
- * by zprop_expand_list().
- */
-int
-zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp,
- zfs_type_t type)
-{
- *listp = NULL;
-
- /*
- * If 'all' is specified, return a NULL list.
- */
- if (strcmp(props, "all") == 0)
- return (0);
-
- /*
- * If no props were specified, return an error.
- */
- if (props[0] == '\0') {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "no properties specified"));
- return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
- "bad property list")));
- }
-
- for (char *p; (p = strsep(&props, ",")); )
- if (strcmp(p, "space") == 0) {
- static const char *const spaceprops[] = {
- "name", "avail", "used", "usedbysnapshots",
- "usedbydataset", "usedbyrefreservation",
- "usedbychildren"
- };
-
- for (int i = 0; i < ARRAY_SIZE(spaceprops); i++) {
- if (addlist(hdl, spaceprops[i], listp, type))
- return (-1);
- listp = &(*listp)->pl_next;
- }
- } else {
- if (addlist(hdl, p, listp, type))
- return (-1);
- listp = &(*listp)->pl_next;
- }
-
- return (0);
-}
-
-void
-zprop_free_list(zprop_list_t *pl)
-{
- zprop_list_t *next;
-
- while (pl != NULL) {
- next = pl->pl_next;
- free(pl->pl_user_prop);
- free(pl);
- pl = next;
- }
-}
-
-typedef struct expand_data {
- zprop_list_t **last;
- libzfs_handle_t *hdl;
- zfs_type_t type;
-} expand_data_t;
-
-static int
-zprop_expand_list_cb(int prop, void *cb)
-{
- zprop_list_t *entry;
- expand_data_t *edp = cb;
-
- entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t));
-
- entry->pl_prop = prop;
- entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type);
- entry->pl_all = B_TRUE;
-
- *(edp->last) = entry;
- edp->last = &entry->pl_next;
-
- return (ZPROP_CONT);
-}
-
-int
-zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type)
-{
- zprop_list_t *entry;
- zprop_list_t **last;
- expand_data_t exp;
-
- if (*plp == NULL) {
- /*
- * If this is the very first time we've been called for an 'all'
- * specification, expand the list to include all native
- * properties.
- */
- last = plp;
-
- exp.last = last;
- exp.hdl = hdl;
- exp.type = type;
-
- if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE,
- B_FALSE, type) == ZPROP_INVAL)
- return (-1);
-
- /*
- * Add 'name' to the beginning of the list, which is handled
- * specially.
- */
- entry = zfs_alloc(hdl, sizeof (zprop_list_t));
- entry->pl_prop = ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
- ((type == ZFS_TYPE_VDEV) ? VDEV_PROP_NAME : ZFS_PROP_NAME));
- entry->pl_width = zprop_width(entry->pl_prop,
- &entry->pl_fixed, type);
- entry->pl_all = B_TRUE;
- entry->pl_next = *plp;
- *plp = entry;
- }
- return (0);
-}
-
-int
-zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
- zfs_type_t type)
-{
- return (zprop_iter_common(func, cb, show_all, ordered, type));
-}
-
-const char *
-zfs_version_userland(void)
-{
- return (ZFS_META_ALIAS);
-}
-
-/*
- * Prints both zfs userland and kernel versions
- * Returns 0 on success, and -1 on error
- */
-int
-zfs_version_print(void)
-{
- (void) puts(ZFS_META_ALIAS);
-
- char *kver = zfs_version_kernel();
- if (kver == NULL) {
- fprintf(stderr, "zfs_version_kernel() failed: %s\n",
- zfs_strerror(errno));
- return (-1);
- }
-
- (void) printf("zfs-kmod-%s\n", kver);
- free(kver);
- return (0);
-}
-
-/*
- * Returns an nvlist with both zfs userland and kernel versions.
- * Returns NULL on error.
- */
-nvlist_t *
-zfs_version_nvlist(void)
-{
- nvlist_t *nvl;
- char kmod_ver[64];
- if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
- return (NULL);
- if (nvlist_add_string(nvl, "userland", ZFS_META_ALIAS) != 0)
- goto err;
- char *kver = zfs_version_kernel();
- if (kver == NULL) {
- fprintf(stderr, "zfs_version_kernel() failed: %s\n",
- zfs_strerror(errno));
- goto err;
- }
- (void) snprintf(kmod_ver, 64, "zfs-kmod-%s", kver);
- if (nvlist_add_string(nvl, "kernel", kmod_ver) != 0)
- goto err;
- return (nvl);
-err:
- nvlist_free(nvl);
- return (NULL);
-}
-
-/*
- * Return 1 if the user requested ANSI color output, and our terminal supports
- * it. Return 0 for no color.
- */
-int
-use_color(void)
-{
- static int use_color = -1;
- char *term;
-
- /*
- * Optimization:
- *
- * For each zpool invocation, we do a single check to see if we should
- * be using color or not, and cache that value for the lifetime of the
- * the zpool command. That makes it cheap to call use_color() when
- * we're printing with color. We assume that the settings are not going
- * to change during the invocation of a zpool command (the user isn't
- * going to change the ZFS_COLOR value while zpool is running, for
- * example).
- */
- if (use_color != -1) {
- /*
- * We've already figured out if we should be using color or
- * not. Return the cached value.
- */
- return (use_color);
- }
-
- term = getenv("TERM");
- /*
- * The user sets the ZFS_COLOR env var set to enable zpool ANSI color
- * output. However if NO_COLOR is set (https://no-color.org/) then
- * don't use it. Also, don't use color if terminal doesn't support
- * it.
- */
- if (libzfs_envvar_is_set("ZFS_COLOR") &&
- !libzfs_envvar_is_set("NO_COLOR") &&
- isatty(STDOUT_FILENO) && term && strcmp("dumb", term) != 0 &&
- strcmp("unknown", term) != 0) {
- /* Color supported */
- use_color = 1;
- } else {
- use_color = 0;
- }
-
- return (use_color);
-}
-
-/*
- * The functions color_start() and color_end() are used for when you want
- * to colorize a block of text.
- *
- * For example:
- * color_start(ANSI_RED)
- * printf("hello");
- * printf("world");
- * color_end();
- */
-void
-color_start(const char *color)
-{
- if (color && use_color()) {
- fputs(color, stdout);
- fflush(stdout);
- }
-}
-
-void
-color_end(void)
-{
- if (use_color()) {
- fputs(ANSI_RESET, stdout);
- fflush(stdout);
- }
-
-}
-
-/*
- * printf() with a color. If color is NULL, then do a normal printf.
- */
-int
-printf_color(const char *color, const char *format, ...)
-{
- va_list aptr;
- int rc;
-
- if (color)
- color_start(color);
-
- va_start(aptr, format);
- rc = vprintf(format, aptr);
- va_end(aptr);
-
- if (color)
- color_end();
-
- return (rc);
-}
-
-/* PATH + 5 env vars + a NULL entry = 7 */
-#define ZPOOL_VDEV_SCRIPT_ENV_COUNT 7
-
-/*
- * There's a few places where ZFS will call external scripts (like the script
- * in zpool.d/ and `zfs_prepare_disk`). These scripts are called with a
- * reduced $PATH, and some vdev specific environment vars set. This function
- * will allocate an populate the environment variable array that is passed to
- * these scripts. The user must free the arrays with zpool_vdev_free_env() when
- * they are done.
- *
- * The following env vars will be set (but value could be blank):
- *
- * POOL_NAME
- * VDEV_PATH
- * VDEV_UPATH
- * VDEV_ENC_SYSFS_PATH
- *
- * In addition, you can set an optional environment variable named 'opt_key'
- * to 'opt_val' if you want.
- *
- * Returns allocated env[] array on success, NULL otherwise.
- */
-char **
-zpool_vdev_script_alloc_env(const char *pool_name,
- const char *vdev_path, const char *vdev_upath,
- const char *vdev_enc_sysfs_path, const char *opt_key, const char *opt_val)
-{
- char **env = NULL;
- int rc;
-
- env = calloc(ZPOOL_VDEV_SCRIPT_ENV_COUNT, sizeof (*env));
- if (!env)
- return (NULL);
-
- env[0] = strdup("PATH=/bin:/sbin:/usr/bin:/usr/sbin");
- if (!env[0])
- goto error;
-
- /* Setup our custom environment variables */
- rc = asprintf(&env[1], "POOL_NAME=%s", pool_name ? pool_name : "");
- if (rc == -1) {
- env[1] = NULL;
- goto error;
- }
-
- rc = asprintf(&env[2], "VDEV_PATH=%s", vdev_path ? vdev_path : "");
- if (rc == -1) {
- env[2] = NULL;
- goto error;
- }
-
- rc = asprintf(&env[3], "VDEV_UPATH=%s", vdev_upath ? vdev_upath : "");
- if (rc == -1) {
- env[3] = NULL;
- goto error;
- }
-
- rc = asprintf(&env[4], "VDEV_ENC_SYSFS_PATH=%s",
- vdev_enc_sysfs_path ? vdev_enc_sysfs_path : "");
- if (rc == -1) {
- env[4] = NULL;
- goto error;
- }
-
- if (opt_key != NULL) {
- rc = asprintf(&env[5], "%s=%s", opt_key,
- opt_val ? opt_val : "");
- if (rc == -1) {
- env[5] = NULL;
- goto error;
- }
- }
-
- return (env);
-
-error:
- for (int i = 0; i < ZPOOL_VDEV_SCRIPT_ENV_COUNT; i++)
- free(env[i]);
-
- free(env);
-
- return (NULL);
-}
-
-/*
- * Free the env[] array that was allocated by zpool_vdev_script_alloc_env().
- */
-void
-zpool_vdev_script_free_env(char **env)
-{
- for (int i = 0; i < ZPOOL_VDEV_SCRIPT_ENV_COUNT; i++)
- free(env[i]);
-
- free(env);
-}
-
-/*
- * Prepare a disk by (optionally) running a program before labeling the disk.
- * This can be useful for installing disk firmware or doing some pre-flight
- * checks on the disk before it becomes part of the pool. The program run is
- * located at ZFSEXECDIR/zfs_prepare_disk
- * (E.x: /usr/local/libexec/zfs/zfs_prepare_disk).
- *
- * Return 0 on success, non-zero on failure.
- */
-int
-zpool_prepare_disk(zpool_handle_t *zhp, nvlist_t *vdev_nv,
- const char *prepare_str, char **lines[], int *lines_cnt)
-{
- const char *script_path = ZFSEXECDIR "/zfs_prepare_disk";
- const char *pool_name;
- int rc = 0;
-
- /* Path to script and a NULL entry */
- char *argv[2] = {(char *)script_path};
- char **env = NULL;
- const char *path = NULL, *enc_sysfs_path = NULL;
- char *upath;
- *lines_cnt = 0;
-
- if (access(script_path, X_OK) != 0) {
- /* No script, nothing to do */
- return (0);
- }
-
- (void) nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_PATH, &path);
- (void) nvlist_lookup_string(vdev_nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH,
- &enc_sysfs_path);
-
- upath = zfs_get_underlying_path(path);
- pool_name = zhp ? zpool_get_name(zhp) : NULL;
-
- env = zpool_vdev_script_alloc_env(pool_name, path, upath,
- enc_sysfs_path, "VDEV_PREPARE", prepare_str);
-
- free(upath);
-
- if (env == NULL) {
- return (ENOMEM);
- }
-
- rc = libzfs_run_process_get_stdout(script_path, argv, env, lines,
- lines_cnt);
-
- zpool_vdev_script_free_env(env);
-
- return (rc);
-}
-
-/*
- * Optionally run a script and then label a disk. The script can be used to
- * prepare a disk for inclusion into the pool. For example, it might update
- * the disk's firmware or check its health.
- *
- * The 'name' provided is the short name, stripped of any leading
- * /dev path, and is passed to zpool_label_disk. vdev_nv is the nvlist for
- * the vdev. prepare_str is a string that gets passed as the VDEV_PREPARE
- * env variable to the script.
- *
- * The following env vars are passed to the script:
- *
- * POOL_NAME: The pool name (blank during zpool create)
- * VDEV_PREPARE: Reason why the disk is being prepared for inclusion:
- * "create", "add", "replace", or "autoreplace"
- * VDEV_PATH: Path to the disk
- * VDEV_UPATH: One of the 'underlying paths' to the disk. This is
- * useful for DM devices.
- * VDEV_ENC_SYSFS_PATH: Path to the disk's enclosure sysfs path, if available.
- *
- * Note, some of these values can be blank.
- *
- * Return 0 on success, non-zero otherwise.
- */
-int
-zpool_prepare_and_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp,
- const char *name, nvlist_t *vdev_nv, const char *prepare_str,
- char **lines[], int *lines_cnt)
-{
- int rc;
- char vdev_path[MAXPATHLEN];
- (void) snprintf(vdev_path, sizeof (vdev_path), "%s/%s", DISK_ROOT,
- name);
-
- /* zhp will be NULL when creating a pool */
- rc = zpool_prepare_disk(zhp, vdev_nv, prepare_str, lines, lines_cnt);
- if (rc != 0)
- return (rc);
-
- rc = zpool_label_disk(hdl, zhp, name);
- return (rc);
-}
diff --git a/lib/libzfs/os/freebsd/libzfs_compat.c b/lib/libzfs/os/freebsd/libzfs_compat.c
deleted file mode 100644
index e772e3e12262..000000000000
--- a/lib/libzfs/os/freebsd/libzfs_compat.c
+++ /dev/null
@@ -1,369 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
- */
-#include "../../libzfs_impl.h"
-#include <libzfs.h>
-#include <libzutil.h>
-#include <sys/sysctl.h>
-#include <libintl.h>
-#include <sys/linker.h>
-#include <sys/module.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-
-#ifdef IN_BASE
-#define ZFS_KMOD "zfs"
-#else
-#define ZFS_KMOD "openzfs"
-#endif
-
-#ifndef HAVE_EXECVPE
-/* FreeBSD prior to 15 lacks execvpe */
-static int
-execvPe(const char *name, const char *path, char * const *argv,
- char * const *envp)
-{
- const char **memp;
- size_t cnt, lp, ln;
- int eacces, save_errno;
- char buf[MAXPATHLEN];
- const char *bp, *np, *op, *p;
- struct stat sb;
-
- eacces = 0;
-
- /* If it's an absolute or relative path name, it's easy. */
- if (strchr(name, '/')) {
- bp = name;
- op = NULL;
- goto retry;
- }
- bp = buf;
-
- /* If it's an empty path name, fail in the usual POSIX way. */
- if (*name == '\0') {
- errno = ENOENT;
- return (-1);
- }
-
- 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 (np == op) {
- /* Empty component. */
- p = ".";
- lp = 1;
- } 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
- * security issue; given a way to make the path too long
- * the user may execute the wrong program.
- */
- if (lp + ln + 2 > sizeof (buf)) {
- (void) write(STDERR_FILENO, "execvP: ", 8);
- (void) write(STDERR_FILENO, p, lp);
- (void) write(STDERR_FILENO, ": path too long\n",
- 16);
- continue;
- }
- memcpy(buf, p, lp);
- buf[lp] = '/';
- memcpy(buf + lp + 1, name, ln);
- buf[lp + ln + 1] = '\0';
-
-retry: (void) execve(bp, argv, envp);
- switch (errno) {
- case E2BIG:
- goto done;
- case ELOOP:
- case ENAMETOOLONG:
- case ENOENT:
- break;
- case ENOEXEC:
- for (cnt = 0; argv[cnt]; ++cnt)
- ;
-
- /*
- * 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;
- }
- if (cnt > 0) {
- memp[0] = argv[0];
- memp[1] = bp;
- memcpy(memp + 2, argv + 1,
- 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;
- case ENOTDIR:
- break;
- case ETXTBSY:
- /*
- * We used to retry here, but sh(1) doesn't.
- */
- goto done;
- default:
- /*
- * EACCES may be for an inaccessible directory or
- * a non-executable file. Call stat() to decide
- * which. This also handles ambiguities for EFAULT
- * and EIO, and undocumented errors like ESTALE.
- * We hope that the race for a stat() is unimportant.
- */
- save_errno = errno;
- if (stat(bp, &sb) != 0)
- break;
- if (save_errno == EACCES) {
- eacces = 1;
- continue;
- }
- errno = save_errno;
- goto done;
- }
- }
- if (eacces)
- errno = EACCES;
- else
- errno = ENOENT;
-done:
- return (-1);
-}
-
-int
-execvpe(const char *name, char * const argv[], char * const envp[])
-{
- const char *path;
-
- /* Get the path we're searching. */
- if ((path = getenv("PATH")) == NULL)
- path = _PATH_DEFPATH;
-
- return (execvPe(name, path, argv, envp));
-}
-#endif /* !HAVE_EXECVPE */
-
-static __thread char errbuf[ERRBUFLEN];
-
-const char *
-libzfs_error_init(int error)
-{
- char *msg = errbuf;
- size_t msglen = sizeof (errbuf);
-
- if (modfind("zfs") < 0) {
- size_t len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
- "Failed to load %s module: "), ZFS_KMOD);
- if (len >= msglen)
- len = msglen - 1;
- msg += len;
- msglen -= len;
- }
-
- (void) snprintf(msg, msglen, "%s", zfs_strerror(error));
-
- return (errbuf);
-}
-
-/*
- * Verify the required ZFS_DEV device is available and optionally attempt
- * to load the ZFS modules. Under normal circumstances the modules
- * should already have been loaded by some external mechanism.
- */
-int
-libzfs_load_module(void)
-{
- /*
- * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain
- * modfind("zfs") so out-of-base openzfs userland works with the
- * in-base module.
- */
- if (modfind("zfs") < 0) {
- /* Not present in kernel, try loading it. */
- if (kldload(ZFS_KMOD) < 0 && errno != EEXIST) {
- return (errno);
- }
- }
- return (0);
-}
-
-int
-zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
-{
- (void) hdl, (void) path, (void) msg;
- return (0);
-}
-
-int
-zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
-{
- (void) hdl, (void) zhp, (void) name;
- return (0);
-}
-
-int
-find_shares_object(differ_info_t *di)
-{
- (void) di;
- return (0);
-}
-
-int
-zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
-{
- (void) hdl, (void) snaps;
- return (0);
-}
-
-/*
- * Attach/detach the given filesystem to/from the given jail.
- */
-int
-zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- zfs_cmd_t zc = {"\0"};
- unsigned long cmd;
- int ret;
-
- if (attach) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
- } else {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name);
- }
-
- switch (zhp->zfs_type) {
- case ZFS_TYPE_VOLUME:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "volumes can not be jailed"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_SNAPSHOT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots can not be jailed"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_BOOKMARK:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "bookmarks can not be jailed"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_VDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "vdevs can not be jailed"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_INVALID:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid zfs_type_t: ZFS_TYPE_INVALID"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_POOL:
- case ZFS_TYPE_FILESYSTEM:
- /* OK */
- ;
- }
- assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- zc.zc_objset_type = DMU_OST_ZFS;
- zc.zc_zoneid = jailid;
-
- cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
- if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0)
- zfs_standard_error(hdl, errno, errbuf);
-
- return (ret);
-}
-
-/*
- * Set loader options for next boot.
- */
-int
-zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
- const char *command)
-{
- zfs_cmd_t zc = {"\0"};
- nvlist_t *args;
-
- args = fnvlist_alloc();
- fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid);
- fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid);
- fnvlist_add_string(args, "command", command);
- zcmd_write_src_nvlist(hdl, &zc, args);
- int error = zfs_ioctl(hdl, ZFS_IOC_NEXTBOOT, &zc);
- zcmd_free_nvlists(&zc);
- nvlist_free(args);
- return (error);
-}
-
-/*
- * Return allocated loaded module version, or NULL on error (with errno set)
- */
-char *
-zfs_version_kernel(void)
-{
- size_t l;
- if (sysctlbyname("vfs.zfs.version.module",
- NULL, &l, NULL, 0) == -1)
- return (NULL);
- char *version = malloc(l);
- if (version == NULL)
- return (NULL);
- if (sysctlbyname("vfs.zfs.version.module",
- version, &l, NULL, 0) == -1) {
- free(version);
- return (NULL);
- }
- return (version);
-}
diff --git a/lib/libzfs/os/freebsd/libzfs_zmount.c b/lib/libzfs/os/freebsd/libzfs_zmount.c
deleted file mode 100644
index bc7d68b17eb1..000000000000
--- a/lib/libzfs/os/freebsd/libzfs_zmount.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: BSD-2-Clause
-/*
- * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
- * 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.
- */
-
-/*
- * This file implements Solaris compatible zmount() function.
- */
-
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/uio.h>
-#include <sys/mntent.h>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mnttab.h>
-#include <sys/errno.h>
-#include <libzfs.h>
-
-#include "../../libzfs_impl.h"
-
-static void
-build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
- size_t len)
-{
- int i;
-
- if (*iovlen < 0)
- return;
- i = *iovlen;
- *iov = realloc(*iov, sizeof (**iov) * (i + 2));
- if (*iov == NULL) {
- *iovlen = -1;
- return;
- }
- (*iov)[i].iov_base = strdup(name);
- (*iov)[i].iov_len = strlen(name) + 1;
- i++;
- (*iov)[i].iov_base = val;
- if (len == (size_t)-1) {
- if (val != NULL)
- len = strlen(val) + 1;
- else
- len = 0;
- }
- (*iov)[i].iov_len = (int)len;
- *iovlen = ++i;
-}
-
-int
-do_mount(zfs_handle_t *zhp, const char *mntpt, const char *opts, int flags)
-{
- struct iovec *iov;
- char *optstr, *p, *tofree;
- int iovlen, rv;
- const char *spec = zfs_get_name(zhp);
-
- assert(spec != NULL);
- assert(mntpt != NULL);
- assert(opts != NULL);
-
- tofree = optstr = strdup(opts);
- assert(optstr != NULL);
-
- iov = NULL;
- iovlen = 0;
- if (strstr(optstr, MNTOPT_REMOUNT) != NULL)
- build_iovec(&iov, &iovlen, "update", NULL, 0);
- if (flags & MS_RDONLY)
- build_iovec(&iov, &iovlen, "ro", NULL, 0);
- build_iovec(&iov, &iovlen, "fstype", __DECONST(char *, MNTTYPE_ZFS),
- (size_t)-1);
- build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, mntpt),
- (size_t)-1);
- build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1);
- while ((p = strsep(&optstr, ",/")) != NULL)
- build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
- rv = nmount(iov, iovlen, 0);
- free(tofree);
- if (rv < 0)
- return (errno);
- return (rv);
-
-}
-
-int
-do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
-{
- (void) zhp;
- if (unmount(mntpt, flags) < 0)
- return (errno);
- return (0);
-}
-
-int
-zfs_mount_delegation_check(void)
-{
- return (0);
-}
-
-/* Called from the tail end of zpool_disable_datasets() */
-void
-zpool_disable_datasets_os(zpool_handle_t *zhp, boolean_t force)
-{
- (void) zhp, (void) force;
-}
-
-/* Called from the tail end of zfs_unmount() */
-void
-zpool_disable_volume_os(const char *name)
-{
- (void) name;
-}
diff --git a/lib/libzfs/os/linux/libzfs_mount_os.c b/lib/libzfs/os/linux/libzfs_mount_os.c
deleted file mode 100644
index 585d22d9e5b3..000000000000
--- a/lib/libzfs/os/linux/libzfs_mount_os.c
+++ /dev/null
@@ -1,431 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2021 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright 2017 RackTop Systems.
- * Copyright (c) 2018 Datto Inc.
- * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
- */
-
-#include <dirent.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <zone.h>
-#include <sys/mntent.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/vfs.h>
-#include <sys/dsl_crypt.h>
-#include <libzfs.h>
-
-#include "../../libzfs_impl.h"
-#include <thread_pool.h>
-
-#define ZS_COMMENT 0x00000000 /* comment */
-#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
-
-typedef struct option_map {
- const char *name;
- unsigned long mntmask;
- unsigned long zfsmask;
-} option_map_t;
-
-static const option_map_t option_map[] = {
- /* Canonicalized filesystem independent options from mount(8) */
- { MNTOPT_NOAUTO, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_DEFAULTS, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_NODEVICES, MS_NODEV, ZS_COMMENT },
- { MNTOPT_DEVICES, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_DIRSYNC, MS_DIRSYNC, ZS_COMMENT },
- { MNTOPT_NOEXEC, MS_NOEXEC, ZS_COMMENT },
- { MNTOPT_EXEC, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_GROUP, MS_GROUP, ZS_COMMENT },
- { MNTOPT_NETDEV, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_NOFAIL, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_NOSUID, MS_NOSUID, ZS_COMMENT },
- { MNTOPT_SUID, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_OWNER, MS_OWNER, ZS_COMMENT },
- { MNTOPT_REMOUNT, MS_REMOUNT, ZS_COMMENT },
- { MNTOPT_RO, MS_RDONLY, ZS_COMMENT },
- { MNTOPT_RW, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_SYNC, MS_SYNCHRONOUS, ZS_COMMENT },
- { MNTOPT_USER, MS_USERS, ZS_COMMENT },
- { MNTOPT_USERS, MS_USERS, ZS_COMMENT },
- /* acl flags passed with util-linux-2.24 mount command */
- { MNTOPT_ACL, MS_POSIXACL, ZS_COMMENT },
- { MNTOPT_NOACL, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_POSIXACL, MS_POSIXACL, ZS_COMMENT },
- /*
- * Case sensitive options are just listed here to silently
- * ignore the error if passed with zfs mount command.
- */
- { MNTOPT_CASESENSITIVE, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_CASEINSENSITIVE, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_CASEMIXED, MS_COMMENT, ZS_COMMENT },
-#ifdef MS_NOATIME
- { MNTOPT_NOATIME, MS_NOATIME, ZS_COMMENT },
- { MNTOPT_ATIME, MS_COMMENT, ZS_COMMENT },
-#endif
-#ifdef MS_NODIRATIME
- { MNTOPT_NODIRATIME, MS_NODIRATIME, ZS_COMMENT },
- { MNTOPT_DIRATIME, MS_COMMENT, ZS_COMMENT },
-#endif
-#ifdef MS_RELATIME
- { MNTOPT_RELATIME, MS_RELATIME, ZS_COMMENT },
- { MNTOPT_NORELATIME, MS_COMMENT, ZS_COMMENT },
-#endif
-#ifdef MS_STRICTATIME
- { MNTOPT_STRICTATIME, MS_STRICTATIME, ZS_COMMENT },
- { MNTOPT_NOSTRICTATIME, MS_COMMENT, ZS_COMMENT },
-#endif
-#ifdef MS_LAZYTIME
- { MNTOPT_LAZYTIME, MS_LAZYTIME, ZS_COMMENT },
-#endif
- { MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_DEFCONTEXT, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_ROOTCONTEXT, MS_COMMENT, ZS_COMMENT },
-#ifdef MS_I_VERSION
- { MNTOPT_IVERSION, MS_I_VERSION, ZS_COMMENT },
-#endif
-#ifdef MS_MANDLOCK
- { MNTOPT_NBMAND, MS_MANDLOCK, ZS_COMMENT },
- { MNTOPT_NONBMAND, MS_COMMENT, ZS_COMMENT },
-#endif
- /* Valid options not found in mount(8) */
- { MNTOPT_BIND, MS_BIND, ZS_COMMENT },
-#ifdef MS_REC
- { MNTOPT_RBIND, MS_BIND|MS_REC, ZS_COMMENT },
-#endif
- { MNTOPT_COMMENT, MS_COMMENT, ZS_COMMENT },
-#ifdef MS_NOSUB
- { MNTOPT_NOSUB, MS_NOSUB, ZS_COMMENT },
-#endif
-#ifdef MS_SILENT
- { MNTOPT_QUIET, MS_SILENT, ZS_COMMENT },
-#endif
- /* Custom zfs options */
- { MNTOPT_XATTR, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_NOXATTR, MS_COMMENT, ZS_COMMENT },
- { MNTOPT_ZFSUTIL, MS_COMMENT, ZS_ZFSUTIL },
- { NULL, 0, 0 } };
-
-/*
- * Break the mount option in to a name/value pair. The name is
- * validated against the option map and mount flags set accordingly.
- */
-static int
-parse_option(char *mntopt, unsigned long *mntflags,
- unsigned long *zfsflags, int sloppy)
-{
- const option_map_t *opt;
- char *ptr, *name, *value = NULL;
- int error = 0;
-
- name = strdup(mntopt);
- if (name == NULL)
- return (ENOMEM);
-
- for (ptr = name; ptr && *ptr; ptr++) {
- if (*ptr == '=') {
- *ptr = '\0';
- value = ptr+1;
- VERIFY3P(value, !=, NULL);
- break;
- }
- }
-
- for (opt = option_map; opt->name != NULL; opt++) {
- if (strncmp(name, opt->name, strlen(name)) == 0) {
- *mntflags |= opt->mntmask;
- *zfsflags |= opt->zfsmask;
- error = 0;
- goto out;
- }
- }
-
- if (!sloppy)
- error = ENOENT;
-out:
- /* If required further process on the value may be done here */
- free(name);
- return (error);
-}
-
-/*
- * Translate the mount option string in to MS_* mount flags for the
- * kernel vfs. When sloppy is non-zero unknown options will be ignored
- * otherwise they are considered fatal are copied in to badopt.
- */
-int
-zfs_parse_mount_options(const char *mntopts, unsigned long *mntflags,
- unsigned long *zfsflags, int sloppy, char *badopt, char *mtabopt)
-{
- int error = 0, quote = 0, flag = 0, count = 0;
- char *ptr, *opt, *opts;
-
- opts = strdup(mntopts);
- if (opts == NULL)
- return (ENOMEM);
-
- *mntflags = 0;
- opt = NULL;
-
- /*
- * Scan through all mount options which must be comma delimited.
- * We must be careful to notice regions which are double quoted
- * and skip commas in these regions. Each option is then checked
- * to determine if it is a known option.
- */
- for (ptr = opts; ptr && !flag; ptr++) {
- if (opt == NULL)
- opt = ptr;
-
- if (*ptr == '"')
- quote = !quote;
-
- if (quote)
- continue;
-
- if (*ptr == '\0')
- flag = 1;
-
- if ((*ptr == ',') || (*ptr == '\0')) {
- *ptr = '\0';
-
- error = parse_option(opt, mntflags, zfsflags, sloppy);
- if (error) {
- strcpy(badopt, opt);
- goto out;
-
- }
-
- if (!(*mntflags & MS_REMOUNT) &&
- !(*zfsflags & ZS_ZFSUTIL) &&
- mtabopt != NULL) {
- if (count > 0)
- strlcat(mtabopt, ",", MNT_LINE_MAX);
-
- strlcat(mtabopt, opt, MNT_LINE_MAX);
- count++;
- }
-
- opt = NULL;
- }
- }
-
-out:
- free(opts);
- return (error);
-}
-
-static void
-append_mntopt(const char *name, const char *val, char *mntopts,
- char *mtabopt, boolean_t quote)
-{
- char tmp[MNT_LINE_MAX];
-
- snprintf(tmp, MNT_LINE_MAX, quote ? ",%s=\"%s\"" : ",%s=%s", name, val);
-
- if (mntopts)
- strlcat(mntopts, tmp, MNT_LINE_MAX);
-
- if (mtabopt)
- strlcat(mtabopt, tmp, MNT_LINE_MAX);
-}
-
-static void
-zfs_selinux_setcontext(zfs_handle_t *zhp, zfs_prop_t zpt, const char *name,
- char *mntopts, char *mtabopt)
-{
- char context[ZFS_MAXPROPLEN];
-
- if (zfs_prop_get(zhp, zpt, context, sizeof (context),
- NULL, NULL, 0, B_FALSE) == 0) {
- if (strcmp(context, "none") != 0)
- append_mntopt(name, context, mntopts, mtabopt, B_TRUE);
- }
-}
-
-void
-zfs_adjust_mount_options(zfs_handle_t *zhp, const char *mntpoint,
- char *mntopts, char *mtabopt)
-{
- char prop[ZFS_MAXPROPLEN];
-
- /*
- * Checks to see if the ZFS_PROP_SELINUX_CONTEXT exists
- * if it does, create a tmp variable in case it's needed
- * checks to see if the selinux context is set to the default
- * if it is, allow the setting of the other context properties
- * this is needed because the 'context' property overrides others
- * if it is not the default, set the 'context' property
- */
- if (zfs_prop_get(zhp, ZFS_PROP_SELINUX_CONTEXT, prop, sizeof (prop),
- NULL, NULL, 0, B_FALSE) == 0) {
- if (strcmp(prop, "none") == 0) {
- zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT,
- MNTOPT_FSCONTEXT, mntopts, mtabopt);
- zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_DEFCONTEXT,
- MNTOPT_DEFCONTEXT, mntopts, mtabopt);
- zfs_selinux_setcontext(zhp,
- ZFS_PROP_SELINUX_ROOTCONTEXT, MNTOPT_ROOTCONTEXT,
- mntopts, mtabopt);
- } else {
- append_mntopt(MNTOPT_CONTEXT, prop,
- mntopts, mtabopt, B_TRUE);
- }
- }
-
- /* A hint used to determine an auto-mounted snapshot mount point */
- append_mntopt(MNTOPT_MNTPOINT, mntpoint, mntopts, NULL, B_FALSE);
-}
-
-/*
- * By default the filesystem by preparing the mount options (i.e. parsing
- * some flags from the "opts" parameter into the "flags" parameter) and then
- * directly calling the system call mount(2). We don't need the mount utility
- * or update /etc/mtab, because this is a symlink on all modern systems.
- *
- * If the environment variable ZFS_MOUNT_HELPER is set, we fall back to the
- * previous behavior:
- * The filesystem is mounted by invoking the system mount utility rather
- * than by the system call mount(2). This ensures that the /etc/mtab
- * file is correctly locked for the update. Performing our own locking
- * and /etc/mtab update requires making an unsafe assumption about how
- * the mount utility performs its locking. Unfortunately, this also means
- * in the case of a mount failure we do not have the exact errno. We must
- * make due with return value from the mount process.
- */
-int
-do_mount(zfs_handle_t *zhp, const char *mntpt, const char *opts, int flags)
-{
- const char *src = zfs_get_name(zhp);
- int error = 0;
-
- if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
- char badopt[MNT_LINE_MAX] = {0};
- unsigned long mntflags = flags, zfsflags = 0;
- char myopts[MNT_LINE_MAX] = {0};
-
- if (zfs_parse_mount_options(opts, &mntflags,
- &zfsflags, 0, badopt, NULL)) {
- return (EINVAL);
- }
- strlcat(myopts, opts, MNT_LINE_MAX);
- zfs_adjust_mount_options(zhp, mntpt, myopts, NULL);
- if (mount(src, mntpt, MNTTYPE_ZFS, mntflags, myopts)) {
- return (errno);
- }
- } else {
- char *argv[9] = {
- (char *)"/bin/mount",
- (char *)"--no-canonicalize",
- (char *)"-t", (char *)MNTTYPE_ZFS,
- (char *)"-o", (char *)opts,
- (char *)src,
- (char *)mntpt,
- (char *)NULL };
-
- /* Return only the most critical mount error */
- error = libzfs_run_process(argv[0], argv,
- STDOUT_VERBOSE|STDERR_VERBOSE);
- if (error) {
- if (error & MOUNT_FILEIO) {
- error = EIO;
- } else if (error & MOUNT_USER) {
- error = EINTR;
- } else if (error & MOUNT_SOFTWARE) {
- error = EPIPE;
- } else if (error & MOUNT_BUSY) {
- error = EBUSY;
- } else if (error & MOUNT_SYSERR) {
- error = EAGAIN;
- } else if (error & MOUNT_USAGE) {
- error = EINVAL;
- } else
- error = ENXIO; /* Generic error */
- }
- }
-
- return (error);
-}
-
-int
-do_unmount(zfs_handle_t *zhp, const char *mntpt, int flags)
-{
- (void) zhp;
-
- if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
- int rv = umount2(mntpt, flags);
-
- return (rv < 0 ? errno : 0);
- }
-
- char *argv[7] = {
- (char *)"/bin/umount",
- (char *)"-t", (char *)MNTTYPE_ZFS,
- NULL, NULL, NULL, NULL };
- int rc, count = 3;
-
- if (flags & MS_FORCE)
- argv[count++] = (char *)"-f";
-
- if (flags & MS_DETACH)
- argv[count++] = (char *)"-l";
-
- argv[count] = (char *)mntpt;
- rc = libzfs_run_process(argv[0], argv, STDOUT_VERBOSE|STDERR_VERBOSE);
-
- return (rc ? EINVAL : 0);
-}
-
-int
-zfs_mount_delegation_check(void)
-{
- return ((geteuid() != 0) ? EACCES : 0);
-}
-
-/* Called from the tail end of zpool_disable_datasets() */
-void
-zpool_disable_datasets_os(zpool_handle_t *zhp, boolean_t force)
-{
- (void) zhp, (void) force;
-}
-
-/* Called from the tail end of zfs_unmount() */
-void
-zpool_disable_volume_os(const char *name)
-{
- (void) name;
-}
diff --git a/lib/libzfs/os/linux/libzfs_pool_os.c b/lib/libzfs/os/linux/libzfs_pool_os.c
deleted file mode 100644
index aef169a3f880..000000000000
--- a/lib/libzfs/os/linux/libzfs_pool_os.c
+++ /dev/null
@@ -1,352 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 2015 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
- * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
- * Copyright (c) 2018 Datto Inc.
- * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
- * Copyright (c) 2017, Intel Corporation.
- * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
- */
-
-#include <errno.h>
-#include <libintl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <zone.h>
-#include <sys/stat.h>
-#include <sys/efi_partition.h>
-#include <sys/systeminfo.h>
-#include <sys/zfs_ioctl.h>
-#include <sys/vdev_disk.h>
-#include <dlfcn.h>
-#include <libzutil.h>
-
-#include "zfs_namecheck.h"
-#include "zfs_prop.h"
-#include "../../libzfs_impl.h"
-#include "zfs_comutil.h"
-#include "zfeature_common.h"
-
-/*
- * If the device has being dynamically expanded then we need to relabel
- * the disk to use the new unallocated space.
- */
-int
-zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
-{
- int fd, error;
-
- 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));
- }
-
- /*
- * It's possible that we might encounter an error if the device
- * does not have any unallocated space left. If so, we simply
- * ignore that error and continue on.
- */
- error = efi_use_whole_disk(fd);
-
- /* Flush the buffers to disk and invalidate the page cache. */
- (void) fsync(fd);
- (void) ioctl(fd, BLKFLSBUF);
-
- (void) close(fd);
- if (error && error != VT_ENOSPC) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
- "relabel '%s': unable to read disk capacity"), path);
- return (zfs_error(hdl, EZFS_NOCAP, msg));
- }
- return (0);
-}
-
-/*
- * Read the EFI label from the config, if a label does not exist then
- * pass back the error to the caller. If the caller has passed a non-NULL
- * diskaddr argument then we set it to the starting address of the EFI
- * partition.
- */
-static int
-read_efi_label(nvlist_t *config, diskaddr_t *sb)
-{
- const char *path;
- int fd;
- char diskname[MAXPATHLEN];
- int err = -1;
-
- if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
- return (err);
-
- (void) snprintf(diskname, sizeof (diskname), "%s%s", DISK_ROOT,
- strrchr(path, '/'));
- if ((fd = open(diskname, O_RDONLY|O_DIRECT|O_CLOEXEC)) >= 0) {
- struct dk_gpt *vtoc;
-
- if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
- if (sb != NULL)
- *sb = vtoc->efi_parts[0].p_start;
- efi_free(vtoc);
- }
- (void) close(fd);
- }
- return (err);
-}
-
-/*
- * determine where a partition starts on a disk in the current
- * configuration
- */
-static diskaddr_t
-find_start_block(nvlist_t *config)
-{
- nvlist_t **child;
- uint_t c, children;
- diskaddr_t sb = MAXOFFSET_T;
- uint64_t wholedisk;
-
- if (nvlist_lookup_nvlist_array(config,
- ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
- if (nvlist_lookup_uint64(config,
- ZPOOL_CONFIG_WHOLE_DISK,
- &wholedisk) != 0 || !wholedisk) {
- return (MAXOFFSET_T);
- }
- if (read_efi_label(config, &sb) < 0)
- sb = MAXOFFSET_T;
- return (sb);
- }
-
- for (c = 0; c < children; c++) {
- sb = find_start_block(child[c]);
- if (sb != MAXOFFSET_T) {
- return (sb);
- }
- }
- return (MAXOFFSET_T);
-}
-
-static int
-zpool_label_disk_check(char *path)
-{
- struct dk_gpt *vtoc;
- int fd, err;
-
- if ((fd = open(path, O_RDONLY|O_DIRECT|O_CLOEXEC)) < 0)
- return (errno);
-
- if ((err = efi_alloc_and_read(fd, &vtoc)) != 0) {
- (void) close(fd);
- return (err);
- }
-
- if (vtoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {
- efi_free(vtoc);
- (void) close(fd);
- return (EIDRM);
- }
-
- efi_free(vtoc);
- (void) close(fd);
- return (0);
-}
-
-/*
- * Generate a unique partition name for the ZFS member. Partitions must
- * have unique names to ensure udev will be able to create symlinks under
- * /dev/disk/by-partlabel/ for all pool members. The partition names are
- * of the form <pool>-<unique-id>.
- */
-static void
-zpool_label_name(char *label_name, int label_size)
-{
- uint64_t id = 0;
- int fd;
-
- fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
- if (fd >= 0) {
- if (read(fd, &id, sizeof (id)) != sizeof (id))
- id = 0;
-
- close(fd);
- }
-
- if (id == 0)
- id = (((uint64_t)rand()) << 32) | (uint64_t)rand();
-
- snprintf(label_name, label_size, "zfs-%016llx", (u_longlong_t)id);
-}
-
-/*
- * Label an individual disk. The name provided is the short name,
- * stripped of any leading /dev path.
- */
-int
-zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
-{
- char path[MAXPATHLEN];
- struct dk_gpt *vtoc;
- int rval, fd;
- size_t resv = EFI_MIN_RESV_SIZE;
- uint64_t slice_size;
- diskaddr_t start_block;
- char errbuf[ERRBUFLEN];
-
- /* prepare an error message just in case */
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
-
- if (zhp) {
- nvlist_t *nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
- ZPOOL_CONFIG_VDEV_TREE);
-
- if (zhp->zpool_start_block == 0)
- start_block = find_start_block(nvroot);
- else
- start_block = zhp->zpool_start_block;
- zhp->zpool_start_block = start_block;
- } else {
- /* new pool */
- start_block = NEW_START_BLOCK;
- }
-
- (void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
-
- 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.
- */
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
- "label '%s': unable to open device: %d"), path, errno);
- return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
- }
-
- if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
- /*
- * The only way this can fail is if we run out of memory, or we
- * were unable to read the disk's capacity
- */
- if (errno == ENOMEM)
- (void) no_memory(hdl);
-
- (void) close(fd);
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
- "label '%s': unable to read disk capacity"), path);
-
- return (zfs_error(hdl, EZFS_NOCAP, errbuf));
- }
-
- slice_size = vtoc->efi_last_u_lba + 1;
- slice_size -= EFI_MIN_RESV_SIZE;
- if (start_block == MAXOFFSET_T)
- start_block = NEW_START_BLOCK;
- slice_size -= start_block;
- slice_size = P2ALIGN_TYPED(slice_size, PARTITION_END_ALIGNMENT,
- uint64_t);
-
- vtoc->efi_parts[0].p_start = start_block;
- vtoc->efi_parts[0].p_size = slice_size;
-
- if (vtoc->efi_parts[0].p_size * vtoc->efi_lbasize < SPA_MINDEVSIZE) {
- (void) close(fd);
- efi_free(vtoc);
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
- "label '%s': partition would be less than the minimum "
- "device size (64M)"), path);
- return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
- }
-
- /*
- * Why we use V_USR: V_BACKUP confuses users, and is considered
- * disposable by some EFI utilities (since EFI doesn't have a backup
- * slice). V_UNASSIGNED is supposed to be used only for zero size
- * partitions, and efi_write() will fail if we use it.
- * Other available types were all pretty specific.
- * V_USR is as close to reality as we
- * can get, in the absence of V_OTHER.
- */
- vtoc->efi_parts[0].p_tag = V_USR;
- zpool_label_name(vtoc->efi_parts[0].p_name, EFI_PART_NAME_LEN);
-
- vtoc->efi_parts[8].p_start = slice_size + start_block;
- vtoc->efi_parts[8].p_size = resv;
- vtoc->efi_parts[8].p_tag = V_RESERVED;
-
- rval = efi_write(fd, vtoc);
-
- /* Flush the buffers to disk and invalidate the page cache. */
- (void) fsync(fd);
- (void) ioctl(fd, BLKFLSBUF);
-
- if (rval == 0)
- rval = efi_rescan(fd);
-
- /*
- * Some block drivers (like pcata) may not support EFI GPT labels.
- * Print out a helpful error message directing the user to manually
- * label the disk and give a specific slice.
- */
- if (rval != 0) {
- (void) close(fd);
- efi_free(vtoc);
-
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "try using "
- "parted(8) and then provide a specific slice: %d"), rval);
- return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
- }
-
- (void) close(fd);
- efi_free(vtoc);
-
- (void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
- (void) zfs_append_partition(path, MAXPATHLEN);
-
- /* Wait to udev to signal use the device has settled. */
- rval = zpool_label_disk_wait(path, DISK_LABEL_WAIT);
- if (rval) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to "
- "detect device partitions on '%s': %d"), path, rval);
- return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
- }
-
- /* We can't be to paranoid. Read the label back and verify it. */
- (void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
- rval = zpool_label_disk_check(path);
- if (rval) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "freshly written "
- "EFI label on '%s' is damaged. Ensure\nthis device "
- "is not in use, and is functioning properly: %d"),
- path, rval);
- return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
- }
- return (0);
-}
diff --git a/lib/libzfs/os/linux/libzfs_util_os.c b/lib/libzfs/os/linux/libzfs_util_os.c
deleted file mode 100644
index 55dfdf3723bd..000000000000
--- a/lib/libzfs/os/linux/libzfs_util_os.c
+++ /dev/null
@@ -1,275 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.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 https://opensource.org/licenses/CDDL-1.0.
- * 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 Klara, Inc.
- */
-
-#include <alloca.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libintl.h>
-#include <math.h>
-#include <poll.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <sys/inotify.h>
-#include <sys/mntent.h>
-#include <sys/mnttab.h>
-#include <sys/stat.h>
-#include <sys/timerfd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <libzfs.h>
-#include <libzfs_core.h>
-
-#include "../../libzfs_impl.h"
-#include "zfs_prop.h"
-#include <libzutil.h>
-#include <sys/zfs_sysfs.h>
-
-#define ZDIFF_SHARESDIR "/.zfs/shares/"
-
-const char *
-libzfs_error_init(int error)
-{
- switch (error) {
- case ENXIO:
- return (dgettext(TEXT_DOMAIN, "The ZFS modules are not "
- "loaded.\nTry running 'modprobe zfs' as root "
- "to load them."));
- case ENOENT:
- return (dgettext(TEXT_DOMAIN, "/dev/zfs and /proc/self/mounts "
- "are required.\nTry running 'udevadm trigger' and 'mount "
- "-t proc proc /proc' as root."));
- case ENOEXEC:
- return (dgettext(TEXT_DOMAIN, "The ZFS modules cannot be "
- "auto-loaded.\nTry running 'modprobe zfs' as "
- "root to manually load them."));
- case EACCES:
- return (dgettext(TEXT_DOMAIN, "Permission denied the "
- "ZFS utilities must be run as root."));
- default:
- return (dgettext(TEXT_DOMAIN, "Failed to initialize the "
- "libzfs library."));
- }
-}
-
-/*
- * zfs(4) is loaded by udev if there's a fstype=zfs device present,
- * but if there isn't, load them automatically;
- * always wait for ZFS_DEV to appear via udev.
- *
- * Environment variables:
- * - ZFS_MODULE_TIMEOUT="<seconds>" - Seconds to wait for ZFS_DEV,
- * defaults to 10, max. 10 min.
- */
-int
-libzfs_load_module(void)
-{
- if (access(ZFS_DEV, F_OK) == 0)
- return (0);
-
- if (access(ZFS_SYSFS_DIR, F_OK) != 0) {
- char *argv[] = {(char *)"modprobe", (char *)"zfs", NULL};
- if (libzfs_run_process("modprobe", argv, 0))
- return (ENOEXEC);
-
- if (access(ZFS_SYSFS_DIR, F_OK) != 0)
- return (ENXIO);
- }
-
- const char *timeout_str = getenv("ZFS_MODULE_TIMEOUT");
- int seconds = 10;
- if (timeout_str)
- seconds = MIN(strtol(timeout_str, NULL, 0), 600);
- struct itimerspec timeout = {.it_value.tv_sec = MAX(seconds, 0)};
-
- int ino = inotify_init1(IN_CLOEXEC);
- if (ino == -1)
- return (ENOENT);
- inotify_add_watch(ino, ZFS_DEVDIR, IN_CREATE);
-
- if (access(ZFS_DEV, F_OK) == 0) {
- close(ino);
- return (0);
- } else if (seconds == 0) {
- close(ino);
- return (ENOENT);
- }
-
- size_t evsz = sizeof (struct inotify_event) + NAME_MAX + 1;
- struct inotify_event *ev = alloca(evsz);
-
- int tout = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
- if (tout == -1) {
- close(ino);
- return (ENOENT);
- }
- timerfd_settime(tout, 0, &timeout, NULL);
-
- int ret = ENOENT;
- struct pollfd pfds[] = {
- {.fd = ino, .events = POLLIN},
- {.fd = tout, .events = POLLIN},
- };
- while (poll(pfds, ARRAY_SIZE(pfds), -1) != -1) {
- if (pfds[0].revents & POLLIN) {
- verify(read(ino, ev, evsz) >
- sizeof (struct inotify_event));
- if (strncmp(ev->name, &ZFS_DEV[sizeof (ZFS_DEVDIR)],
- ev->len) == 0) {
- ret = 0;
- break;
- }
- }
- if (pfds[1].revents & POLLIN)
- break;
- }
- close(tout);
- close(ino);
- return (ret);
-}
-
-int
-find_shares_object(differ_info_t *di)
-{
- char fullpath[MAXPATHLEN];
- struct stat64 sb = { 0 };
-
- (void) strlcpy(fullpath, di->dsmnt, MAXPATHLEN);
- (void) strlcat(fullpath, ZDIFF_SHARESDIR, MAXPATHLEN);
-
- if (stat64(fullpath, &sb) != 0) {
- (void) snprintf(di->errbuf, sizeof (di->errbuf),
- dgettext(TEXT_DOMAIN, "Cannot stat %s"), fullpath);
- return (zfs_error(di->zhp->zfs_hdl, EZFS_DIFF, di->errbuf));
- }
-
- di->shares = (uint64_t)sb.st_ino;
- return (0);
-}
-
-int
-zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
-{
- (void) hdl, (void) snaps;
- return (0);
-}
-
-/*
- * Return allocated loaded module version, or NULL on error (with errno set)
- */
-char *
-zfs_version_kernel(void)
-{
- FILE *f = fopen(ZFS_SYSFS_DIR "/version", "re");
- if (f == NULL)
- return (NULL);
-
- char *ret = NULL;
- size_t l;
- ssize_t read;
- if ((read = getline(&ret, &l, f)) == -1) {
- int err = errno;
- fclose(f);
- errno = err;
- return (NULL);
- }
-
- fclose(f);
- if (ret[read - 1] == '\n')
- ret[read - 1] = '\0';
- return (ret);
-}
-
-/*
- * Add or delete the given filesystem to/from the given user namespace.
- */
-int
-zfs_userns(zfs_handle_t *zhp, const char *nspath, int attach)
-{
- libzfs_handle_t *hdl = zhp->zfs_hdl;
- zfs_cmd_t zc = {"\0"};
- char errbuf[1024];
- unsigned long cmd;
- int ret;
-
- if (attach) {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot add '%s' to namespace"),
- zhp->zfs_name);
- } else {
- (void) snprintf(errbuf, sizeof (errbuf),
- dgettext(TEXT_DOMAIN, "cannot remove '%s' from namespace"),
- zhp->zfs_name);
- }
-
- switch (zhp->zfs_type) {
- case ZFS_TYPE_VOLUME:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "volumes can not be namespaced"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_SNAPSHOT:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshots can not be namespaced"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_BOOKMARK:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "bookmarks can not be namespaced"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_VDEV:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "vdevs can not be namespaced"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_INVALID:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid zfs_type_t: ZFS_TYPE_INVALID"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_POOL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "pools can not be namespaced"));
- return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case ZFS_TYPE_FILESYSTEM:
- break;
- }
- assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
-
- (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
- zc.zc_objset_type = DMU_OST_ZFS;
- zc.zc_cleanup_fd = open(nspath, O_RDONLY);
- if (zc.zc_cleanup_fd < 0) {
- return (zfs_error(hdl, EZFS_NOT_USER_NAMESPACE, errbuf));
- }
-
- cmd = attach ? ZFS_IOC_USERNS_ATTACH : ZFS_IOC_USERNS_DETACH;
- if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0)
- zfs_standard_error(hdl, errno, errbuf);
-
- (void) close(zc.zc_cleanup_fd);
-
- return (ret);
-}