mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 19:28:53 +03:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f5f866266 | |||
| 8829ba19b7 | |||
| 642d86af0d | |||
| 07ca7592ad | |||
| fb0d807477 | |||
| 858ea8861c | |||
| 549841ef9a | |||
| 96f322e7e2 | |||
| d022406a14 | |||
| a1a1386965 | |||
| 43eaef6de8 | |||
| 5bc4c39d70 | |||
| 756e28be51 | |||
| 039a810491 | |||
| bfb7b9613a | |||
| 3e33897bec | |||
| 0f3b928e85 | |||
| 12fec4a147 | |||
| 7930a5ee65 | |||
| be94a3de0f | |||
| db83b3abe9 | |||
| 55fd8ceab6 | |||
| e269e1c07a | |||
| 81f981cd82 | |||
| 3790aa8176 | |||
| 4e1d1b4b92 | |||
| c32c475363 | |||
| dd487640b2 | |||
| acb39fc9a4 | |||
| 6539bf71fe |
@@ -0,0 +1,64 @@
|
||||
name: zfs-tests-functional
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
tests-functional-ubuntu:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [18.04, 20.04]
|
||||
runs-on: ubuntu-${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
|
||||
git alien fakeroot wget curl bc fio acl \
|
||||
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
|
||||
nfs-kernel-server samba rng-tools xz-utils \
|
||||
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \
|
||||
xfslibs-dev libattr1-dev libacl1-dev libudev-dev libdevmapper-dev \
|
||||
libssl-dev libffi-dev libaio-dev libelf-dev libmount-dev \
|
||||
libpam0g-dev pamtester python-dev python-setuptools python-cffi \
|
||||
python3 python3-dev python3-setuptools python3-cffi
|
||||
- name: Autogen.sh
|
||||
run: |
|
||||
sh autogen.sh
|
||||
- name: Configure
|
||||
run: |
|
||||
./configure --enable-debug --enable-debuginfo
|
||||
- name: Make
|
||||
run: |
|
||||
make --no-print-directory -s pkg-utils pkg-kmod
|
||||
- name: Install
|
||||
run: |
|
||||
sudo dpkg -i *.deb
|
||||
# Update order of directories to search for modules, otherwise
|
||||
# Ubuntu will load kernel-shipped ones.
|
||||
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
|
||||
sudo depmod
|
||||
sudo modprobe zfs
|
||||
- name: Tests
|
||||
run: |
|
||||
/usr/share/zfs/zfs-tests.sh -v -s 3G
|
||||
- name: Prepare artifacts
|
||||
if: failure()
|
||||
run: |
|
||||
RESULTS_PATH=$(readlink -f /var/tmp/test_results/current)
|
||||
sudo dmesg > $RESULTS_PATH/dmesg
|
||||
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||
sudo chmod +r $RESULTS_PATH/*
|
||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Test logs Ubuntu-${{ matrix.os }}
|
||||
path: /var/tmp/test_results/20*/
|
||||
if-no-files-found: ignore
|
||||
@@ -50,6 +50,8 @@ jobs:
|
||||
sudo dmesg > $RESULTS_PATH/dmesg
|
||||
sudo cp /var/log/syslog $RESULTS_PATH/
|
||||
sudo chmod +r $RESULTS_PATH/*
|
||||
# Replace ':' in dir names, actions/upload-artifact doesn't support it
|
||||
for f in $(find $RESULTS_PATH -name '*:*'); do mv "$f" "${f//:/__}"; done
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
@@ -1,7 +1,7 @@
|
||||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 2.0.1
|
||||
Version: 2.0.3
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
|
||||
@@ -50,6 +50,21 @@ libzfs_handle_t *g_zfs;
|
||||
static void
|
||||
parse_dataset(const char *target, char **dataset)
|
||||
{
|
||||
/*
|
||||
* Prior to util-linux 2.36.2, if a file or directory in the
|
||||
* current working directory was named 'dataset' then mount(8)
|
||||
* would prepend the current working directory to the dataset.
|
||||
* Check for it and strip the prepended path when it is added.
|
||||
*/
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, PATH_MAX) == NULL) {
|
||||
perror("getcwd");
|
||||
return;
|
||||
}
|
||||
int len = strlen(cwd);
|
||||
if (strncmp(cwd, target, len) == 0)
|
||||
target += len;
|
||||
|
||||
/* Assume pool/dataset is more likely */
|
||||
strlcpy(*dataset, target, PATH_MAX);
|
||||
|
||||
|
||||
@@ -545,6 +545,7 @@ while getopts 'c:d:eg:mp:h' OPTION; do
|
||||
done
|
||||
|
||||
if [ ! -r $CONFIG ] ; then
|
||||
echo "Error: Config file \"$CONFIG\" not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include $(top_srcdir)/config/Rules.am
|
||||
|
||||
bin_PROGRAMS = zgenhostid
|
||||
sbin_PROGRAMS = zgenhostid
|
||||
|
||||
zgenhostid_SOURCES = zgenhostid.c
|
||||
|
||||
+89
-5
@@ -669,9 +669,16 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
|
||||
}
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
uint64_t is_log = B_FALSE;
|
||||
uint64_t is_log = B_FALSE, is_hole = B_FALSE;
|
||||
char *class = "";
|
||||
|
||||
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
|
||||
&is_hole);
|
||||
|
||||
if (is_hole == B_TRUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
|
||||
&is_log);
|
||||
if (is_log)
|
||||
@@ -692,6 +699,54 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the list of l2cache devices for dry runs.
|
||||
*/
|
||||
static void
|
||||
print_cache_list(nvlist_t *nv, int indent)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||
&child, &children) == 0 && children > 0) {
|
||||
(void) printf("\t%*s%s\n", indent, "", "cache");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
for (c = 0; c < children; c++) {
|
||||
char *vname;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
|
||||
(void) printf("\t%*s%s\n", indent + 2, "", vname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the list of spares for dry runs.
|
||||
*/
|
||||
static void
|
||||
print_spare_list(nvlist_t *nv, int indent)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
|
||||
&child, &children) == 0 && children > 0) {
|
||||
(void) printf("\t%*s%s\n", indent, "", "spares");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
for (c = 0; c < children; c++) {
|
||||
char *vname;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
|
||||
(void) printf("\t%*s%s\n", indent + 2, "", vname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
prop_list_contains_feature(nvlist_t *proplist)
|
||||
{
|
||||
@@ -921,16 +976,16 @@ zpool_do_add(int argc, char **argv)
|
||||
|
||||
if (dryrun) {
|
||||
nvlist_t *poolnvroot;
|
||||
nvlist_t **l2child;
|
||||
uint_t l2children, c;
|
||||
nvlist_t **l2child, **sparechild;
|
||||
uint_t l2children, sparechildren, c;
|
||||
char *vname;
|
||||
boolean_t hadcache = B_FALSE;
|
||||
boolean_t hadcache = B_FALSE, hadspare = B_FALSE;
|
||||
|
||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
||||
&poolnvroot) == 0);
|
||||
|
||||
(void) printf(gettext("would update '%s' to the following "
|
||||
"configuration:\n"), zpool_get_name(zhp));
|
||||
"configuration:\n\n"), zpool_get_name(zhp));
|
||||
|
||||
/* print original main pool and new tree */
|
||||
print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
|
||||
@@ -991,6 +1046,29 @@ zpool_do_add(int argc, char **argv)
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
/* And finaly the spares */
|
||||
if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_SPARES,
|
||||
&sparechild, &sparechildren) == 0 && sparechildren > 0) {
|
||||
hadspare = B_TRUE;
|
||||
(void) printf(gettext("\tspares\n"));
|
||||
for (c = 0; c < sparechildren; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL,
|
||||
sparechild[c], name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||
&sparechild, &sparechildren) == 0 && sparechildren > 0) {
|
||||
if (!hadspare)
|
||||
(void) printf(gettext("\tspares\n"));
|
||||
for (c = 0; c < sparechildren; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL,
|
||||
sparechild[c], name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
@@ -1548,6 +1626,8 @@ zpool_do_create(int argc, char **argv)
|
||||
VDEV_ALLOC_BIAS_SPECIAL, 0);
|
||||
print_vdev_tree(NULL, "logs", nvroot, 0,
|
||||
VDEV_ALLOC_BIAS_LOG, 0);
|
||||
print_cache_list(nvroot, 0);
|
||||
print_spare_list(nvroot, 0);
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
@@ -6515,6 +6595,10 @@ zpool_do_split(int argc, char **argv)
|
||||
"following layout:\n\n"), newpool);
|
||||
print_vdev_tree(NULL, newpool, config, 0, "",
|
||||
flags.name_flags);
|
||||
print_vdev_tree(NULL, "dedup", config, 0,
|
||||
VDEV_ALLOC_BIAS_DEDUP, 0);
|
||||
print_vdev_tree(NULL, "special", config, 0,
|
||||
VDEV_ALLOC_BIAS_SPECIAL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ check() {
|
||||
[ "${1}" = "-d" ] && return 0
|
||||
|
||||
# Verify the zfs tool chain
|
||||
for tool in "@bindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
|
||||
for tool in "@sbindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
|
||||
test -x "$tool" || return 1
|
||||
done
|
||||
# Verify grep exists
|
||||
@@ -38,7 +38,7 @@ install() {
|
||||
inst_rules @udevruledir@/60-zvol.rules
|
||||
dracut_install hostid
|
||||
dracut_install grep
|
||||
dracut_install @bindir@/zgenhostid
|
||||
dracut_install @sbindir@/zgenhostid
|
||||
dracut_install @sbindir@/zfs
|
||||
dracut_install @sbindir@/zpool
|
||||
# Workaround for https://github.com/openzfs/zfs/issues/4749 by
|
||||
|
||||
@@ -8,7 +8,7 @@ Before=zfs-import.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh -c "/bin/systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
|
||||
ExecStart=/bin/sh -c "systemctl set-environment BOOTFS=$(@sbindir@/zpool list -H -o bootfs | grep -m1 -v '^-$')"
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs-import.target
|
||||
|
||||
@@ -59,4 +59,12 @@ echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR"/sysr
|
||||
[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires
|
||||
ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
|
||||
|
||||
|
||||
[ -d "$GENERATOR_DIR"/dracut-pre-mount.service.d ] || mkdir "$GENERATOR_DIR"/dracut-pre-mount.service.d
|
||||
|
||||
{
|
||||
echo "[Unit]"
|
||||
echo "After=zfs-import.target"
|
||||
} > "$GENERATOR_DIR"/dracut-pre-mount.service.d/zfs-enhancement.conf
|
||||
|
||||
echo "zfs-generator: finished" >> /dev/kmsg
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise
|
||||
[ -e /bin/systemctl ] || return 0
|
||||
[ -e /bin/systemctl ] || [ -e /usr/bin/systemctl ] || return 0
|
||||
|
||||
# This script only gets executed on systemd systems, see mount-zfs.sh for non-systemd systems
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ def os_open(name, mode):
|
||||
|
||||
@contextlib.contextmanager
|
||||
def dev_null():
|
||||
with os_open('/dev/null', os.O_WRONLY) as fd:
|
||||
yield fd
|
||||
with tempfile.TemporaryFile(suffix='.zstream') as fd:
|
||||
yield fd.fileno()
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
||||
@@ -8,7 +8,7 @@ After=cryptsetup.target
|
||||
After=multipathd.target
|
||||
After=systemd-remount-fs.service
|
||||
Before=zfs-import.target
|
||||
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
||||
ConditionFileNotEmpty=@sysconfdir@/zfs/zpool.cache
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -7,7 +7,7 @@ After=systemd-udev-settle.service
|
||||
After=cryptsetup.target
|
||||
After=multipathd.target
|
||||
Before=zfs-import.target
|
||||
ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
|
||||
ConditionFileNotEmpty=!@sysconfdir@/zfs/zpool.cache
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -15,6 +15,7 @@ KERNEL_H = \
|
||||
disp.h \
|
||||
dkio.h \
|
||||
extdirent.h \
|
||||
fcntl.h \
|
||||
file.h \
|
||||
freebsd_rwlock.h \
|
||||
inttypes.h \
|
||||
|
||||
@@ -166,10 +166,6 @@ extern "C" {
|
||||
#define ECHRNG ENXIO
|
||||
#define ETIME ETIMEDOUT
|
||||
|
||||
#define O_LARGEFILE 0
|
||||
#define O_RSYNC 0
|
||||
#define O_DSYNC 0
|
||||
|
||||
#ifndef LOCORE
|
||||
#ifndef HAVE_RPC_TYPES
|
||||
typedef int bool_t;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 iXsystems, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SPL_SYS_FCNTL_H_
|
||||
#define _SPL_SYS_FCNTL_H_
|
||||
|
||||
#include_next <sys/fcntl.h>
|
||||
|
||||
#define O_LARGEFILE 0
|
||||
#define O_RSYNC 0
|
||||
|
||||
#ifndef O_DSYNC
|
||||
#define O_DSYNC 0
|
||||
#endif
|
||||
|
||||
#endif /* _SPL_SYS_FCNTL_H_ */
|
||||
@@ -64,7 +64,7 @@ typedef u_int uint_t;
|
||||
typedef u_char uchar_t;
|
||||
typedef u_short ushort_t;
|
||||
typedef u_long ulong_t;
|
||||
typedef u_int minor_t;
|
||||
typedef int minor_t;
|
||||
/* END CSTYLED */
|
||||
#ifndef _OFF64_T_DECLARED
|
||||
#define _OFF64_T_DECLARED
|
||||
|
||||
@@ -127,7 +127,9 @@ vn_is_readonly(vnode_t *vp)
|
||||
#define FCREAT O_CREAT
|
||||
#define FTRUNC O_TRUNC
|
||||
#define FEXCL O_EXCL
|
||||
#ifndef FDSYNC
|
||||
#define FDSYNC FFSYNC
|
||||
#endif
|
||||
#define FRSYNC FFSYNC
|
||||
#define FSYNC FFSYNC
|
||||
#define FOFFMAX 0x00
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
SUBDIRS = sys
|
||||
|
||||
libspldir = $(includedir)/libspl
|
||||
libspl_HEADERS = \
|
||||
fcntl.h
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021 iXsystems, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_FCNTL_H_
|
||||
#define _LIBSPL_FCNTL_H_
|
||||
|
||||
#include_next <fcntl.h>
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#endif /* _LIBSPL_FCNTL_H_ */
|
||||
@@ -1,6 +1,7 @@
|
||||
libspldir = $(includedir)/libspl/sys
|
||||
libspl_HEADERS = \
|
||||
byteorder.h \
|
||||
fcntl.h \
|
||||
file.h \
|
||||
mnttab.h \
|
||||
mount.h \
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021 iXsystems, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_FCNTL_H_
|
||||
#define _LIBSPL_SYS_FCNTL_H_
|
||||
|
||||
#include_next <sys/fcntl.h>
|
||||
|
||||
#define O_LARGEFILE 0
|
||||
#define O_RSYNC 0
|
||||
|
||||
#ifndef O_DSYNC
|
||||
#define O_DSYNC 0
|
||||
#endif
|
||||
|
||||
#endif /* _LIBSPL_SYS_FCNTL_H_ */
|
||||
@@ -128,6 +128,7 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
|
||||
pp->uap_next->uap_prev = pp->uap_prev;
|
||||
pp->uap_prev->uap_next = pp->uap_next;
|
||||
(void) pthread_mutex_unlock(&uu_apool_list_lock);
|
||||
(void) pthread_mutex_destroy(&pp->uap_lock);
|
||||
pp->uap_prev = NULL;
|
||||
pp->uap_next = NULL;
|
||||
uu_free(pp);
|
||||
|
||||
@@ -3388,7 +3388,7 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
|
||||
nvlist_t *props, splitflags_t flags)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char msg[1024];
|
||||
char msg[1024], *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;
|
||||
@@ -3446,6 +3446,7 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
|
||||
|
||||
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;
|
||||
char *type;
|
||||
nvlist_t **mchild, *vdev;
|
||||
uint_t mchildren;
|
||||
@@ -3492,6 +3493,13 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
|
||||
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);
|
||||
|
||||
@@ -3509,6 +3517,20 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
|
||||
|
||||
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? */
|
||||
|
||||
+8
-3
@@ -63,12 +63,17 @@ If specified, you can list property information by the absolute pathname or the
|
||||
relative pathname.
|
||||
By default, all file systems and volumes are displayed.
|
||||
Snapshots are displayed if the
|
||||
.Sy listsnaps
|
||||
property is
|
||||
.Sy listsnapshots
|
||||
pool property is
|
||||
.Sy on
|
||||
.Po the default is
|
||||
.Sy off
|
||||
.Pc .
|
||||
.Pc ,
|
||||
or if the
|
||||
.Fl t Sy snapshot
|
||||
or
|
||||
.Fl t Sy all
|
||||
options are specified.
|
||||
The following fields are displayed:
|
||||
.Sy name Ns \&, Sy used Ns \&, Sy available Ns \&, Sy referenced Ns \&, Sy mountpoint Ns .
|
||||
.Bl -tag -width "-H"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved.
|
||||
.\" Copyright 2020 Joyent, Inc.
|
||||
.\"
|
||||
.Dd February 3, 2020
|
||||
.Dd January 26, 2021
|
||||
.Dt ZFS-PROGRAM 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -290,7 +290,7 @@ EBADF EXDEV EFBIG
|
||||
.Ss API Functions
|
||||
For detailed descriptions of the exact behavior of any zfs administrative
|
||||
operations, see the main
|
||||
.Xr zfs 1
|
||||
.Xr zfs 8
|
||||
manual page.
|
||||
.Bl -tag -width "xx"
|
||||
.It Em zfs.debug(msg)
|
||||
|
||||
+1
-1
@@ -1766,7 +1766,7 @@ where
|
||||
and
|
||||
.Sy none
|
||||
are encoded as 1, 2 and 3 respectively.
|
||||
The default values is
|
||||
The default value is
|
||||
.Sy full .
|
||||
.It Sy vscan Ns = Ns Sy on Ns | Ns Sy off
|
||||
Controls whether regular files should be scanned for viruses when a file is
|
||||
|
||||
@@ -240,9 +240,11 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
|
||||
#endif
|
||||
VI_LOCK(vp);
|
||||
vp->v_iflag &= ~VI_MOUNT;
|
||||
VI_UNLOCK(vp);
|
||||
|
||||
#ifdef VIRF_MOUNTPOINT
|
||||
vn_irflag_set_locked(vp, VIRF_MOUNTPOINT);
|
||||
#endif
|
||||
vp->v_mountedhere = mp;
|
||||
VI_UNLOCK(vp);
|
||||
/* Put the new filesystem on the mount list. */
|
||||
mtx_lock(&mountlist_mtx);
|
||||
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
|
||||
|
||||
@@ -209,25 +209,58 @@ uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
|
||||
}
|
||||
EXPORT_SYMBOL(uiomove);
|
||||
|
||||
/*
|
||||
* Fault in the pages of the first n bytes specified by the uio structure.
|
||||
* 1 byte in each page is touched and the uio struct is unmodified. Any
|
||||
* error will terminate the process as this is only a best attempt to get
|
||||
* the pages resident.
|
||||
*/
|
||||
int
|
||||
uio_prefaultpages(ssize_t n, struct uio *uio)
|
||||
{
|
||||
struct iov_iter iter, *iterp = NULL;
|
||||
|
||||
#if defined(HAVE_IOV_ITER_FAULT_IN_READABLE)
|
||||
if (uio->uio_segflg == UIO_USERSPACE) {
|
||||
iterp = &iter;
|
||||
iov_iter_init_compat(iterp, READ, uio->uio_iov,
|
||||
uio->uio_iovcnt, uio->uio_resid);
|
||||
if (uio->uio_segflg == UIO_SYSSPACE || uio->uio_segflg == UIO_BVEC) {
|
||||
/* There's never a need to fault in kernel pages */
|
||||
return (0);
|
||||
#if defined(HAVE_VFS_IOV_ITER)
|
||||
} else if (uio->uio_segflg == UIO_ITER) {
|
||||
iterp = uio->uio_iter;
|
||||
/*
|
||||
* At least a Linux 4.9 kernel, iov_iter_fault_in_readable()
|
||||
* can be relied on to fault in user pages when referenced.
|
||||
*/
|
||||
if (iov_iter_fault_in_readable(uio->uio_iter, n))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
} else {
|
||||
/* Fault in all user pages */
|
||||
ASSERT3S(uio->uio_segflg, ==, UIO_USERSPACE);
|
||||
const struct iovec *iov = uio->uio_iov;
|
||||
int iovcnt = uio->uio_iovcnt;
|
||||
size_t skip = uio->uio_skip;
|
||||
uint8_t tmp;
|
||||
caddr_t p;
|
||||
|
||||
for (; n > 0 && iovcnt > 0; iov++, iovcnt--, skip = 0) {
|
||||
ulong_t cnt = MIN(iov->iov_len - skip, n);
|
||||
/* empty iov */
|
||||
if (cnt == 0)
|
||||
continue;
|
||||
n -= cnt;
|
||||
/* touch each page in this segment. */
|
||||
p = iov->iov_base + skip;
|
||||
while (cnt) {
|
||||
if (get_user(tmp, (uint8_t *)p))
|
||||
return (EFAULT);
|
||||
ulong_t incr = MIN(cnt, PAGESIZE);
|
||||
p += incr;
|
||||
cnt -= incr;
|
||||
}
|
||||
/* touch the last byte in case it straddles a page. */
|
||||
p--;
|
||||
if (get_user(tmp, (uint8_t *)p))
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (iterp && iov_iter_fault_in_readable(iterp, n))
|
||||
return (EFAULT);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
EXPORT_SYMBOL(uio_prefaultpages);
|
||||
|
||||
@@ -87,15 +87,18 @@
|
||||
* must be checked with ZFS_VERIFY_ZP(zp). Both of these macros
|
||||
* can return EIO from the calling function.
|
||||
*
|
||||
* (2) zrele() should always be the last thing except for zil_commit()
|
||||
* (if necessary) and ZFS_EXIT(). This is for 3 reasons:
|
||||
* First, if it's the last reference, the vnode/znode
|
||||
* can be freed, so the zp may point to freed memory. Second, the last
|
||||
* reference will call zfs_zinactive(), which may induce a lot of work --
|
||||
* pushing cached pages (which acquires range locks) and syncing out
|
||||
* cached atime changes. Third, zfs_zinactive() may require a new tx,
|
||||
* which could deadlock the system if you were already holding one.
|
||||
* If you must call zrele() within a tx then use zfs_zrele_async().
|
||||
* (2) zrele() should always be the last thing except for zil_commit() (if
|
||||
* necessary) and ZFS_EXIT(). This is for 3 reasons: First, if it's the
|
||||
* last reference, the vnode/znode can be freed, so the zp may point to
|
||||
* freed memory. Second, the last reference will call zfs_zinactive(),
|
||||
* which may induce a lot of work -- pushing cached pages (which acquires
|
||||
* range locks) and syncing out cached atime changes. Third,
|
||||
* zfs_zinactive() may require a new tx, which could deadlock the system
|
||||
* if you were already holding one. This deadlock occurs because the tx
|
||||
* currently being operated on prevents a txg from syncing, which
|
||||
* prevents the new tx from progressing, resulting in a deadlock. If you
|
||||
* must call zrele() within a tx, use zfs_zrele_async(). Note that iput()
|
||||
* is a synonym for zrele().
|
||||
*
|
||||
* (3) All range locks must be grabbed before calling dmu_tx_assign(),
|
||||
* as they can span dmu_tx_assign() calls.
|
||||
@@ -476,11 +479,18 @@ zfs_zrele_async(znode_t *zp)
|
||||
ASSERT(atomic_read(&ip->i_count) > 0);
|
||||
ASSERT(os != NULL);
|
||||
|
||||
if (atomic_read(&ip->i_count) == 1)
|
||||
/*
|
||||
* If decrementing the count would put us at 0, we can't do it inline
|
||||
* here, because that would be synchronous. Instead, dispatch an iput
|
||||
* to run later.
|
||||
*
|
||||
* For more information on the dangers of a synchronous iput, see the
|
||||
* header comment of this file.
|
||||
*/
|
||||
if (!atomic_add_unless(&ip->i_count, -1, 1)) {
|
||||
VERIFY(taskq_dispatch(dsl_pool_zrele_taskq(dmu_objset_pool(os)),
|
||||
(task_func_t *)iput, ip, TQ_SLEEP) != TASKQID_INVALID);
|
||||
else
|
||||
zrele(zp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
||||
@@ -557,6 +557,7 @@ abd_get_offset_impl(abd_t *sabd, size_t off, size_t size)
|
||||
abd = abd_get_offset_scatter(sabd, off);
|
||||
}
|
||||
|
||||
ASSERT3P(abd, !=, NULL);
|
||||
abd->abd_size = size;
|
||||
abd->abd_parent = sabd;
|
||||
zfs_refcount_create(&abd->abd_children);
|
||||
|
||||
+21
-13
@@ -4050,7 +4050,7 @@ arc_evict_state_impl(multilist_t *ml, int idx, arc_buf_hdr_t *marker,
|
||||
mutex_enter(&arc_evict_lock);
|
||||
arc_evict_count += bytes_evicted;
|
||||
|
||||
if ((int64_t)(arc_free_memory() - arc_sys_free / 2) > 0) {
|
||||
if (arc_free_memory() > arc_sys_free / 2) {
|
||||
arc_evict_waiter_t *aw;
|
||||
while ((aw = list_head(&arc_evict_waiters)) != NULL &&
|
||||
aw->aew_count <= arc_evict_count) {
|
||||
@@ -5136,14 +5136,20 @@ arc_wait_for_eviction(uint64_t amount)
|
||||
list_link_init(&aw.aew_node);
|
||||
cv_init(&aw.aew_cv, NULL, CV_DEFAULT, NULL);
|
||||
|
||||
arc_evict_waiter_t *last =
|
||||
list_tail(&arc_evict_waiters);
|
||||
if (last != NULL) {
|
||||
ASSERT3U(last->aew_count, >, arc_evict_count);
|
||||
aw.aew_count = last->aew_count + amount;
|
||||
} else {
|
||||
aw.aew_count = arc_evict_count + amount;
|
||||
uint64_t last_count = 0;
|
||||
if (!list_is_empty(&arc_evict_waiters)) {
|
||||
arc_evict_waiter_t *last =
|
||||
list_tail(&arc_evict_waiters);
|
||||
last_count = last->aew_count;
|
||||
}
|
||||
/*
|
||||
* Note, the last waiter's count may be less than
|
||||
* arc_evict_count if we are low on memory in which
|
||||
* case arc_evict_state_impl() may have deferred
|
||||
* wakeups (but still incremented arc_evict_count).
|
||||
*/
|
||||
aw.aew_count =
|
||||
MAX(last_count, arc_evict_count) + amount;
|
||||
|
||||
list_insert_tail(&arc_evict_waiters, &aw);
|
||||
|
||||
@@ -8919,6 +8925,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
|
||||
l2arc_write_callback_t *cb = NULL;
|
||||
zio_t *pio, *wzio;
|
||||
uint64_t guid = spa_load_guid(spa);
|
||||
l2arc_dev_hdr_phys_t *l2dhdr = dev->l2ad_dev_hdr;
|
||||
|
||||
ASSERT3P(dev->l2ad_vdev, !=, NULL);
|
||||
|
||||
@@ -8931,17 +8938,17 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
|
||||
/*
|
||||
* Copy buffers for L2ARC writing.
|
||||
*/
|
||||
for (int try = 0; try < L2ARC_FEED_TYPES; try++) {
|
||||
for (int pass = 0; pass < L2ARC_FEED_TYPES; pass++) {
|
||||
/*
|
||||
* If try == 1 or 3, we cache MRU metadata and data
|
||||
* If pass == 1 or 3, we cache MRU metadata and data
|
||||
* respectively.
|
||||
*/
|
||||
if (l2arc_mfuonly) {
|
||||
if (try == 1 || try == 3)
|
||||
if (pass == 1 || pass == 3)
|
||||
continue;
|
||||
}
|
||||
|
||||
multilist_sublist_t *mls = l2arc_sublist_lock(try);
|
||||
multilist_sublist_t *mls = l2arc_sublist_lock(pass);
|
||||
uint64_t passed_sz = 0;
|
||||
|
||||
VERIFY3P(mls, !=, NULL);
|
||||
@@ -9147,7 +9154,8 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
|
||||
* Although we did not write any buffers l2ad_evict may
|
||||
* have advanced.
|
||||
*/
|
||||
l2arc_dev_hdr_update(dev);
|
||||
if (dev->l2ad_evict != l2dhdr->dh_evict)
|
||||
l2arc_dev_hdr_update(dev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ smallblk_changed_cb(void *arg, uint64_t newval)
|
||||
/*
|
||||
* Inheritance and range checking should have been done by now.
|
||||
*/
|
||||
ASSERT(newval <= SPA_OLD_MAXBLOCKSIZE);
|
||||
ASSERT(newval <= SPA_MAXBLOCKSIZE);
|
||||
ASSERT(ISP2(newval));
|
||||
|
||||
os->os_zpl_special_smallblock = newval;
|
||||
|
||||
@@ -528,6 +528,7 @@ zfs_write(znode_t *zp, uio_t *uio, int ioflag, cred_t *cr)
|
||||
((zp->z_mode & S_ISUID) != 0 && uid == 0)) != 0) {
|
||||
uint64_t newmode;
|
||||
zp->z_mode &= ~(S_ISUID | S_ISGID);
|
||||
newmode = zp->z_mode;
|
||||
(void) sa_update(zp->z_sa_hdl, SA_ZPL_MODE(zfsvfs),
|
||||
(void *)&newmode, sizeof (uint64_t), tx);
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ systemctl --system daemon-reload >/dev/null || true
|
||||
# Core utilities
|
||||
%{_sbindir}/*
|
||||
%{_bindir}/raidz_test
|
||||
%{_bindir}/zgenhostid
|
||||
%{_sbindir}/zgenhostid
|
||||
%{_bindir}/zvol_wait
|
||||
# Optional Python 2/3 scripts
|
||||
%{_bindir}/arc_summary
|
||||
|
||||
@@ -317,7 +317,7 @@ tags = ['functional', 'cli_root', 'zpool']
|
||||
tests = ['zpool_add_001_pos', 'zpool_add_002_pos', 'zpool_add_003_pos',
|
||||
'zpool_add_004_pos', 'zpool_add_006_pos', 'zpool_add_007_neg',
|
||||
'zpool_add_008_neg', 'zpool_add_009_neg', 'zpool_add_010_pos',
|
||||
'add-o_ashift', 'add_prop_ashift']
|
||||
'add-o_ashift', 'add_prop_ashift', 'zpool_add_dryrun_output']
|
||||
tags = ['functional', 'cli_root', 'zpool_add']
|
||||
|
||||
[tests/functional/cli_root/zpool_attach]
|
||||
@@ -342,7 +342,7 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
|
||||
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
|
||||
'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
|
||||
'zpool_create_features_005_pos',
|
||||
'create-o_ashift', 'zpool_create_tempname']
|
||||
'create-o_ashift', 'zpool_create_tempname', 'zpool_create_dryrun_output']
|
||||
tags = ['functional', 'cli_root', 'zpool_create']
|
||||
|
||||
[tests/functional/cli_root/zpool_destroy]
|
||||
@@ -460,7 +460,8 @@ tags = ['functional', 'cli_root', 'zpool_set']
|
||||
[tests/functional/cli_root/zpool_split]
|
||||
tests = ['zpool_split_cliargs', 'zpool_split_devices',
|
||||
'zpool_split_encryption', 'zpool_split_props', 'zpool_split_vdevs',
|
||||
'zpool_split_resilver', 'zpool_split_indirect']
|
||||
'zpool_split_resilver', 'zpool_split_indirect',
|
||||
'zpool_split_dryrun_output']
|
||||
tags = ['functional', 'cli_root', 'zpool_split']
|
||||
|
||||
[tests/functional/cli_root/zpool_status]
|
||||
|
||||
@@ -127,6 +127,11 @@ trim_reason = 'DISKS must support discard (TRIM/UNMAP)'
|
||||
#
|
||||
na_reason = "Not applicable"
|
||||
|
||||
#
|
||||
# Some test cases doesn't have all requirements to run on Github actions CI.
|
||||
#
|
||||
ci_reason = 'CI runner doesn\'t have all requirements'
|
||||
|
||||
summary = {
|
||||
'total': float(0),
|
||||
'passed': float(0),
|
||||
@@ -274,6 +279,35 @@ elif sys.platform.startswith('linux'):
|
||||
})
|
||||
|
||||
|
||||
# Not all Github actions runners have scsi_debug module, so we may skip
|
||||
# some tests which use it.
|
||||
if os.environ.get('CI') == 'true':
|
||||
known.update({
|
||||
'cli_root/zpool_expand/zpool_expand_001_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_expand/zpool_expand_003_neg': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_expand/zpool_expand_005_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/setup': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_001_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_002_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_003_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_004_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_005_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_006_neg': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_reopen/zpool_reopen_007_pos': ['SKIP', ci_reason],
|
||||
'cli_root/zpool_split/zpool_split_wholedisk': ['SKIP', ci_reason],
|
||||
'fault/auto_offline_001_pos': ['SKIP', ci_reason],
|
||||
'fault/auto_online_001_pos': ['SKIP', ci_reason],
|
||||
'fault/auto_replace_001_pos': ['SKIP', ci_reason],
|
||||
'fault/auto_spare_ashift': ['SKIP', ci_reason],
|
||||
'fault/auto_spare_shared': ['SKIP', ci_reason],
|
||||
'procfs/pool_state': ['SKIP', ci_reason],
|
||||
})
|
||||
|
||||
maybe.update({
|
||||
'events/events_002_pos': ['FAIL', '11546'],
|
||||
})
|
||||
|
||||
|
||||
def usage(s):
|
||||
print(s)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -32,7 +32,9 @@ typeset -r fs=$TESTPOOL/$TESTFS
|
||||
function cleanup
|
||||
{
|
||||
cd $STF_SUITE
|
||||
[[ -d $TESTDIR/$$ ]] && (rm -rf $TESTDIR/$$ || log_fail)
|
||||
if [[ -d $TESTDIR/$$ ]]; then
|
||||
log_must rm -rf $TESTDIR/$$
|
||||
fi
|
||||
mounted && zfs $mountcmd $TESTPOOL
|
||||
return 0
|
||||
}
|
||||
@@ -50,13 +52,25 @@ force_unmount $fs
|
||||
|
||||
log_note "Verify mount(8) does not canonicalize before calling helper"
|
||||
# Canonicalization is confused by files in PWD matching [device|mountpoint]
|
||||
mkdir -p $TESTDIR/$$/$TESTPOOL && cd $TESTDIR/$$ || log_fail
|
||||
log_must mkdir -p $TESTDIR/$$/$TESTPOOL
|
||||
log_must cd $TESTDIR/$$
|
||||
# The env flag directs zfs to exec /bin/mount, which then calls helper
|
||||
log_must eval ZFS_MOUNT_HELPER=1 zfs $mountcmd -v $TESTPOOL
|
||||
# mount (2.35.2) still suffers from a cosmetic PWD prefix bug
|
||||
log_must mounted $TESTPOOL
|
||||
force_unmount $TESTPOOL
|
||||
|
||||
log_note "Verify CWD prefix filter <dataset> <path>"
|
||||
log_must cd /
|
||||
log_must zfs set mountpoint=legacy $TESTPOOL
|
||||
log_must mkdir -p $mntpoint
|
||||
log_must mount -t zfs $TESTPOOL $mntpoint
|
||||
log_must ismounted $TESTPOOL
|
||||
log_must umount $mntpoint
|
||||
log_must zfs set mountpoint=$mntpoint $TESTPOOL
|
||||
log_must cd -
|
||||
force_unmount $TESTPOOL
|
||||
|
||||
log_note "Verify '-f <dataset> <path>' fakemount"
|
||||
log_must $helper -f $fs $mntpoint
|
||||
log_mustnot ismounted $fs
|
||||
@@ -75,4 +89,4 @@ log_note "Verify '<device> <path>'"
|
||||
log_must $helper ${vdevs[0]} $mntpoint
|
||||
log_must mounted $mntpoint
|
||||
|
||||
log_pass "zfs mount helper correctly handles both device and pool strings"
|
||||
log_pass "zfs mount helper correctly handles both device and pool strings"
|
||||
|
||||
@@ -82,8 +82,8 @@ log_must zfs snapshot $init_snap
|
||||
log_must eval "zfs send $init_snap > $full_bkup"
|
||||
|
||||
log_note "'zfs receive' fails with invalid send streams."
|
||||
log_mustnot eval "zfs receive $rst_init_snap < /dev/zero"
|
||||
log_mustnot eval "zfs receive -d $rst_root </dev/zero"
|
||||
log_mustnot eval "cat </dev/zero | zfs receive $rst_init_snap"
|
||||
log_mustnot eval "cat </dev/zero | zfs receive -d $rst_root"
|
||||
|
||||
log_must eval "zfs receive $rst_init_snap < $full_bkup"
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ function test_n_check #opt num_snap_clone num_rollback
|
||||
if datasetexists $VOL; then
|
||||
if ismounted $TESTDIR1 $NEWFS_DEFAULT_FS; then
|
||||
log_must umount -f $TESTDIR1
|
||||
sleep 0.1
|
||||
fi
|
||||
|
||||
log_must zfs destroy -Rf $VOL
|
||||
|
||||
@@ -58,13 +58,13 @@ log_must zfs set "org.openzfs:snapprop=val" "$SENDFS@s1"
|
||||
# 2. Verify command line options interact with '-b' correctly
|
||||
typeset opts=("" "p" "Rp" "cew" "nv" "D" "DLPRcenpvw")
|
||||
for opt in ${opts[@]}; do
|
||||
log_must eval "zfs send -b$opt $SENDFS@s1 > /dev/null"
|
||||
log_must eval "zfs send -b$opt -i $SENDFS@s1 $SENDFS@s2 > /dev/null"
|
||||
log_must eval "zfs send -b$opt -I $SENDFS@s1 $SENDFS@s2 > /dev/null"
|
||||
log_must eval "zfs send -b$opt $SENDFS@s1 >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send -b$opt -i $SENDFS@s1 $SENDFS@s2 >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send -b$opt -I $SENDFS@s1 $SENDFS@s2 >$TEST_BASE_DIR/devnull"
|
||||
done
|
||||
for opt in ${opts[@]}; do
|
||||
log_mustnot eval "zfs send -b$opt $SENDFS > /dev/null"
|
||||
log_mustnot eval "zfs send -b$opt $SENDFS#bm > /dev/null"
|
||||
log_mustnot eval "zfs send -b$opt $SENDFS >$TEST_BASE_DIR/devnull"
|
||||
log_mustnot eval "zfs send -b$opt $SENDFS#bm >$TEST_BASE_DIR/devnull"
|
||||
done
|
||||
|
||||
# Do 3..6 in a loop to verify various combination of "zfs send" options
|
||||
|
||||
@@ -61,7 +61,7 @@ log_must zfs snapshot $snap2
|
||||
|
||||
typeset -i i=0
|
||||
while (( i < ${#args[*]} )); do
|
||||
log_must eval "zfs send -i ${args[i]} > /dev/null"
|
||||
log_must eval "zfs send -i ${args[i]} >$TEST_BASE_DIR/devnull"
|
||||
|
||||
(( i += 1 ))
|
||||
done
|
||||
|
||||
@@ -96,7 +96,7 @@ log_must zfs snapshot $snap3
|
||||
typeset -i i=0
|
||||
while (( i < ${#badargs[*]} ))
|
||||
do
|
||||
log_mustnot eval "zfs send ${badargs[i]} >/dev/null"
|
||||
log_mustnot eval "zfs send ${badargs[i]} >$TEST_BASE_DIR/devnull"
|
||||
|
||||
(( i = i + 1 ))
|
||||
done
|
||||
|
||||
@@ -61,6 +61,6 @@ log_must zfs snapshot -r $TESTPOOL@snap
|
||||
log_must zpool export $TESTPOOL
|
||||
log_must zpool import -o readonly=on $TESTPOOL
|
||||
|
||||
log_must eval "zfs send -R $TESTPOOL@snap >/dev/null"
|
||||
log_must eval "zfs send -R $TESTPOOL@snap >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_pass "'zfs send -R' can send from read-only pools"
|
||||
|
||||
@@ -62,15 +62,15 @@ log_must eval "echo $passphrase1 | zfs create -o encryption=on" \
|
||||
|
||||
log_must zfs snapshot -r $snap
|
||||
|
||||
log_must eval "zfs send $snap > /dev/null"
|
||||
log_mustnot eval "zfs send -p $snap > /dev/null"
|
||||
log_mustnot eval "zfs send -R $snap > /dev/null"
|
||||
log_must eval "zfs send $snap >$TEST_BASE_DIR/devnull"
|
||||
log_mustnot eval "zfs send -p $snap >$TEST_BASE_DIR/devnull"
|
||||
log_mustnot eval "zfs send -R $snap >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_must zfs unmount $TESTPOOL/$TESTFS1
|
||||
log_must zfs unload-key $TESTPOOL/$TESTFS1
|
||||
|
||||
log_mustnot eval "zfs send $snap > /dev/null"
|
||||
log_must eval "zfs send $TESTPOOL/$TESTFS1/child@snap > /dev/null"
|
||||
log_mustnot eval "zfs send $snap >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send $TESTPOOL/$TESTFS1/child@snap >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_pass "ZFS performs unencrypted sends of encrypted datasets, unless the" \
|
||||
"'-p' or '-R' options are specified"
|
||||
|
||||
@@ -53,7 +53,7 @@ log_must eval "echo $passphrase | zfs create -o encryption=on" \
|
||||
log_must zfs snapshot $snap
|
||||
log_must zfs unmount $TESTPOOL/$TESTFS1
|
||||
log_must zfs unload-key $TESTPOOL/$TESTFS1
|
||||
log_mustnot eval "zfs send $snap > /dev/null"
|
||||
log_mustnot eval "zfs send $snap >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_pass "ZFS does not perform unencrypted sends from encrypted datasets" \
|
||||
"with unloaded keys."
|
||||
|
||||
@@ -59,21 +59,21 @@ log_must eval "echo $passphrase | zfs create -o encryption=on" \
|
||||
log_must zfs snapshot $snap
|
||||
log_must zfs snapshot $snap1
|
||||
|
||||
log_must eval "zfs send -w $snap > /dev/null"
|
||||
log_must eval "zfs send -w $snap1 > /dev/null"
|
||||
log_must eval "zfs send -w $snap >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send -w $snap1 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_note "Verify ZFS can perform raw sends with properties"
|
||||
log_must eval "zfs send -wp $snap > /dev/null"
|
||||
log_must eval "zfs send -wp $snap1 > /dev/null"
|
||||
log_must eval "zfs send -wp $snap >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send -wp $snap1 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_note "Verify ZFS can perform raw replication sends"
|
||||
log_must eval "zfs send -wR $snap > /dev/null"
|
||||
log_must eval "zfs send -wR $snap1 > /dev/null"
|
||||
log_must eval "zfs send -wR $snap >$TEST_BASE_DIR/devnull"
|
||||
log_must eval "zfs send -wR $snap1 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_note "Verify ZFS can perform a raw send of an encrypted datasets with" \
|
||||
"its key unloaded"
|
||||
log_must zfs unmount $TESTPOOL/$TESTFS1
|
||||
log_must zfs unload-key $TESTPOOL/$TESTFS1
|
||||
log_must eval "zfs send -w $snap1 > /dev/null"
|
||||
log_must eval "zfs send -w $snap1 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
log_pass "ZFS performs raw sends of datasets"
|
||||
|
||||
@@ -14,7 +14,8 @@ dist_pkgdata_SCRIPTS = \
|
||||
zpool_add_010_pos.ksh \
|
||||
add-o_ashift.ksh \
|
||||
add_prop_ashift.ksh \
|
||||
add_nested_replacing_spare.ksh
|
||||
add_nested_replacing_spare.ksh \
|
||||
zpool_add_dryrun_output.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
zpool_add.cfg \
|
||||
|
||||
@@ -61,7 +61,7 @@ log_onexit cleanup
|
||||
typeset TMPFILE_PREFIX="$TEST_BASE_DIR/zpool_add_003"
|
||||
typeset STR_DRYRUN="would update '$TESTPOOL' to the following configuration:"
|
||||
typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev"
|
||||
typeset -a VDEV_TYPES=("" "dedup" "special" "log" "cache")
|
||||
typeset -a VDEV_TYPES=("" "dedup" "special" "log" "cache" "spare")
|
||||
|
||||
vdevs=""
|
||||
config=""
|
||||
@@ -91,7 +91,7 @@ log_must zpool add -f $TESTPOOL $config
|
||||
zpool status $TESTPOOL | awk 'NR == 1, /NAME/ { next } /^$/ {exit}
|
||||
{print $1}' > "$TMPFILE_PREFIX-vdevtree"
|
||||
cat "$TMPFILE_PREFIX-dryrun" | awk 'NR == 1, /would/ {next}
|
||||
{print $1}' > "$TMPFILE_PREFIX-vdevtree-n"
|
||||
/^$/ {next} {print $1}' > "$TMPFILE_PREFIX-vdevtree-n"
|
||||
log_must eval "diff $TMPFILE_PREFIX-vdevtree-n $TMPFILE_PREFIX-vdevtree"
|
||||
|
||||
log_pass "'zpool add -n <pool> <vdev> ...' executes successfully."
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2020 Attila Fülöp <attila@fueloep.org>
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
typeset STR_DRYRUN="would update '$TESTPOOL' to the following configuration:"
|
||||
typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev"
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# 'zpool add -n <pool> <vdev> ...' can display the correct configuration
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create different storage pools, use -n to add devices to the pool and
|
||||
# verify the output is as expected.
|
||||
# 2. Create a pool whith a hole vdev and verify it's not listed with add -n.
|
||||
#
|
||||
|
||||
typeset -a dev=(
|
||||
"${VDEV_PREFIX}00" "${VDEV_PREFIX}01" "${VDEV_PREFIX}02"
|
||||
"${VDEV_PREFIX}03" "${VDEV_PREFIX}04" "${VDEV_PREFIX}05"
|
||||
"${VDEV_PREFIX}06" "${VDEV_PREFIX}07" "${VDEV_PREFIX}08"
|
||||
"${VDEV_PREFIX}09" "${VDEV_PREFIX}10" "${VDEV_PREFIX}11"
|
||||
)
|
||||
|
||||
typeset -a tests=(
|
||||
(
|
||||
tree="'${dev[0]}' log '${dev[1]}' special '${dev[2]}' dedup '${dev[3]}'"
|
||||
add="spare '${dev[4]}' cache '${dev[5]}'"
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$TESTPOOL
|
||||
${dev[0]}
|
||||
dedup
|
||||
${dev[3]}
|
||||
special
|
||||
${dev[2]}
|
||||
logs
|
||||
${dev[1]}
|
||||
cache
|
||||
${dev[5]}
|
||||
spares
|
||||
${dev[4]}"
|
||||
)
|
||||
(
|
||||
tree="'${dev[0]}' log '${dev[1]}' special '${dev[2]}' dedup '${dev[3]}' \
|
||||
spare '${dev[4]}' cache '${dev[5]}'"
|
||||
|
||||
add="'${dev[6]}' log '${dev[7]}' special '${dev[8]}' dedup '${dev[9]}' \
|
||||
spare '${dev[10]}' cache '${dev[11]}'"
|
||||
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$TESTPOOL
|
||||
${dev[0]}
|
||||
${dev[6]}
|
||||
dedup
|
||||
${dev[3]}
|
||||
${dev[9]}
|
||||
special
|
||||
${dev[2]}
|
||||
${dev[8]}
|
||||
logs
|
||||
${dev[1]}
|
||||
${dev[7]}
|
||||
cache
|
||||
${dev[5]}
|
||||
${dev[11]}
|
||||
spares
|
||||
${dev[4]}
|
||||
${dev[10]}"
|
||||
)
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}' \
|
||||
log mirror '${dev[2]}' '${dev[3]}' \
|
||||
dedup mirror '${dev[6]}' '${dev[7]}' \
|
||||
spare '${dev[8]}'"
|
||||
|
||||
add="special mirror '${dev[4]}' '${dev[5]}' \
|
||||
spare '${dev[9]}' cache '${dev[10]}' '${dev[11]}'"
|
||||
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$TESTPOOL
|
||||
mirror-0
|
||||
${dev[0]}
|
||||
${dev[1]}
|
||||
dedup
|
||||
mirror
|
||||
${dev[6]}
|
||||
${dev[7]}
|
||||
special
|
||||
mirror
|
||||
${dev[4]}
|
||||
${dev[5]}
|
||||
logs
|
||||
mirror
|
||||
${dev[2]}
|
||||
${dev[3]}
|
||||
cache
|
||||
${dev[10]}
|
||||
${dev[11]}
|
||||
spares
|
||||
${dev[8]}
|
||||
${dev[9]}"
|
||||
)
|
||||
)
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
destroy_pool "$TESTPOOL"
|
||||
rm -f "$VDEV_PREFIX"*
|
||||
}
|
||||
|
||||
log_assert "'zpool add -n <pool> <vdev> ...' can display the configuration"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
# Create needed file vdevs.
|
||||
for (( i=0; i < ${#dev[@]}; i+=1 )); do
|
||||
log_must truncate -s $SPA_MINDEVSIZE "${dev[$i]}"
|
||||
done
|
||||
|
||||
# Foreach test create pool, add -n devices and check output.
|
||||
for (( i=0; i < ${#tests[@]}; i+=1 )); do
|
||||
typeset tree="${tests[$i].tree}"
|
||||
typeset add="${tests[$i].add}"
|
||||
typeset want="${tests[$i].want}"
|
||||
|
||||
log_must eval zpool create "$TESTPOOL" $tree
|
||||
log_must poolexists "$TESTPOOL"
|
||||
typeset out="$(log_must eval "zpool add -n '$TESTPOOL' $add" | \
|
||||
sed /^SUCCESS/d)"
|
||||
|
||||
if [[ "$out" != "$want" ]]; then
|
||||
log_fail "Got:\n" "$out" "\nbut expected:\n" "$want"
|
||||
fi
|
||||
log_must destroy_pool "$TESTPOOL"
|
||||
done
|
||||
|
||||
# Make sure hole vdevs are skiped in output.
|
||||
log_must eval "zpool create '$TESTPOOL' '${dev[0]}' log '${dev[1]}' \
|
||||
cache '${dev[2]}'"
|
||||
|
||||
# Create a hole vdev.
|
||||
log_must eval "zpool remove '$TESTPOOL' '${dev[1]}'"
|
||||
log_mustnot eval "zpool add -n '$TESTPOOL' '${dev[1]}' | \
|
||||
grep -qE '[[:space:]]+hole'"
|
||||
|
||||
log_pass "'zpool add -n <pool> <vdev> ...' displays config correctly."
|
||||
@@ -33,7 +33,8 @@ dist_pkgdata_SCRIPTS = \
|
||||
zpool_create_features_004_neg.ksh \
|
||||
zpool_create_features_005_pos.ksh \
|
||||
create-o_ashift.ksh \
|
||||
zpool_create_tempname.ksh
|
||||
zpool_create_tempname.ksh \
|
||||
zpool_create_dryrun_output.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
zpool_create.cfg \
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2020 Attila Fülöp <attila@fueloep.org>
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
typeset STR_DRYRUN="would create '$TESTPOOL' with the following layout:"
|
||||
typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev"
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# 'zpool create -n <pool> <vdev> ...' can display the correct configuration
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create -n a storage pool and verify the output is as expected.
|
||||
#
|
||||
|
||||
typeset -a dev=(
|
||||
"${VDEV_PREFIX}00" "${VDEV_PREFIX}01" "${VDEV_PREFIX}02"
|
||||
"${VDEV_PREFIX}03" "${VDEV_PREFIX}04" "${VDEV_PREFIX}05"
|
||||
"${VDEV_PREFIX}06" "${VDEV_PREFIX}07" "${VDEV_PREFIX}08"
|
||||
"${VDEV_PREFIX}09" "${VDEV_PREFIX}10" "${VDEV_PREFIX}11"
|
||||
)
|
||||
|
||||
typeset -a tests=(
|
||||
(
|
||||
tree="'${dev[0]}' '${dev[1]}' log '${dev[2]}' '${dev[3]}' \
|
||||
special '${dev[4]}' '${dev[5]}' dedup '${dev[6]}' '${dev[7]}' \
|
||||
spare '${dev[8]}' '${dev[9]}' cache '${dev[10]}' '${dev[11]}'"
|
||||
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$TESTPOOL
|
||||
${dev[0]}
|
||||
${dev[1]}
|
||||
dedup
|
||||
${dev[6]}
|
||||
${dev[7]}
|
||||
special
|
||||
${dev[4]}
|
||||
${dev[5]}
|
||||
logs
|
||||
${dev[2]}
|
||||
${dev[3]}
|
||||
cache
|
||||
${dev[10]}
|
||||
${dev[11]}
|
||||
spares
|
||||
${dev[8]}
|
||||
${dev[9]}"
|
||||
)
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}' \
|
||||
log mirror '${dev[2]}' '${dev[3]}' \
|
||||
special mirror '${dev[4]}' '${dev[5]}' \
|
||||
dedup mirror '${dev[6]}' '${dev[7]}' \
|
||||
spare '${dev[8]}' '${dev[9]}' \
|
||||
cache '${dev[10]}' '${dev[11]}'"
|
||||
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$TESTPOOL
|
||||
mirror
|
||||
${dev[0]}
|
||||
${dev[1]}
|
||||
dedup
|
||||
mirror
|
||||
${dev[6]}
|
||||
${dev[7]}
|
||||
special
|
||||
mirror
|
||||
${dev[4]}
|
||||
${dev[5]}
|
||||
logs
|
||||
mirror
|
||||
${dev[2]}
|
||||
${dev[3]}
|
||||
cache
|
||||
${dev[10]}
|
||||
${dev[11]}
|
||||
spares
|
||||
${dev[8]}
|
||||
${dev[9]}"
|
||||
)
|
||||
)
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
rm -f "$VDEV_PREFIX"*
|
||||
}
|
||||
|
||||
log_assert "'zpool add -n <pool> <vdev> ...' can display the configuration"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
# Create needed file vdevs.
|
||||
for (( i=0; i < ${#dev[@]}; i+=1 )); do
|
||||
log_must truncate -s $SPA_MINDEVSIZE "${dev[$i]}"
|
||||
done
|
||||
|
||||
# Foreach test create pool, add -n devices and check output.
|
||||
for (( i=0; i < ${#tests[@]}; i+=1 )); do
|
||||
typeset tree="${tests[$i].tree}"
|
||||
typeset want="${tests[$i].want}"
|
||||
|
||||
typeset out="$(log_must eval "zpool create -n '$TESTPOOL' $tree" | \
|
||||
sed /^SUCCESS/d)"
|
||||
|
||||
if [[ "$out" != "$want" ]]; then
|
||||
log_fail "Got:\n" "$out" "\nbut expected:\n" "$want"
|
||||
fi
|
||||
done
|
||||
|
||||
log_pass "'zpool add -n <pool> <vdev> ...' displays config correctly."
|
||||
@@ -12,7 +12,8 @@ dist_pkgdata_SCRIPTS = \
|
||||
zpool_split_vdevs.ksh \
|
||||
zpool_split_resilver.ksh \
|
||||
zpool_split_wholedisk.ksh \
|
||||
zpool_split_indirect.ksh
|
||||
zpool_split_indirect.ksh \
|
||||
zpool_split_dryrun_output.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
zpool_split.cfg
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# The contents of this file are subject to the terms of the
|
||||
# Common Development and Distribution License (the "License").
|
||||
# You may not use this file except in compliance with the License.
|
||||
#
|
||||
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
# or http://www.opensolaris.org/os/licensing.
|
||||
# See the License for the specific language governing permissions
|
||||
# and limitations under the License.
|
||||
#
|
||||
# When distributing Covered Code, include this CDDL HEADER in each
|
||||
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
# If applicable, add the following below this CDDL HEADER, with the
|
||||
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2020 Attila Fülöp <attila@fueloep.org>
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
typeset NEWPOOL="${TESTPOOL}split"
|
||||
typeset STR_DRYRUN="would create '$NEWPOOL' with the following layout:"
|
||||
typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev"
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# 'zpool split -n <pool> <newpool> [<vdev> ...]' can display the correct
|
||||
# configuration
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a mirrored storage pool, split -n and verify the output is as
|
||||
# expected.
|
||||
#
|
||||
|
||||
typeset -a dev=(
|
||||
"${VDEV_PREFIX}00" "${VDEV_PREFIX}01" "${VDEV_PREFIX}02"
|
||||
"${VDEV_PREFIX}03" "${VDEV_PREFIX}04" "${VDEV_PREFIX}05"
|
||||
"${VDEV_PREFIX}06" "${VDEV_PREFIX}07" "${VDEV_PREFIX}08"
|
||||
"${VDEV_PREFIX}09" "${VDEV_PREFIX}10" "${VDEV_PREFIX}11"
|
||||
)
|
||||
|
||||
typeset -a tests=(
|
||||
# Test for hole.
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}' log mirror '${dev[2]}' '${dev[3]}' \
|
||||
special mirror '${dev[4]}' '${dev[5]}'"
|
||||
|
||||
devs=""
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$NEWPOOL
|
||||
${dev[1]}
|
||||
special
|
||||
${dev[5]}"
|
||||
)
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}' log mirror '${dev[2]}' '${dev[3]}' \
|
||||
special mirror '${dev[4]}' '${dev[5]}'"
|
||||
|
||||
devs="'${dev[0]}' '${dev[4]}'"
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$NEWPOOL
|
||||
${dev[0]}
|
||||
special
|
||||
${dev[4]}"
|
||||
)
|
||||
|
||||
# Full set of vdev types.
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}'
|
||||
dedup mirror '${dev[2]}' '${dev[3]}' \
|
||||
special mirror '${dev[4]}' '${dev[5]}' \
|
||||
cache '${dev[6]}' '${dev[7]}' \
|
||||
spare '${dev[8]}' '${dev[9]}'\
|
||||
log mirror '${dev[10]}' '${dev[11]}'"
|
||||
|
||||
devs=""
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$NEWPOOL
|
||||
${dev[1]}
|
||||
dedup
|
||||
${dev[3]}
|
||||
special
|
||||
${dev[5]}"
|
||||
)
|
||||
(
|
||||
tree="mirror '${dev[0]}' '${dev[1]}'
|
||||
dedup mirror '${dev[2]}' '${dev[3]}' \
|
||||
special mirror '${dev[4]}' '${dev[5]}' \
|
||||
cache '${dev[6]}' '${dev[7]}' \
|
||||
spare '${dev[8]}' '${dev[9]}'\
|
||||
log mirror '${dev[10]}' '${dev[11]}'"
|
||||
|
||||
devs="'${dev[0]}' '${dev[2]}' '${dev[4]}'"
|
||||
want="$STR_DRYRUN
|
||||
|
||||
$NEWPOOL
|
||||
${dev[0]}
|
||||
dedup
|
||||
${dev[2]}
|
||||
special
|
||||
${dev[4]}"
|
||||
)
|
||||
)
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
destroy_pool "$TESTPOOL"
|
||||
rm -f "$VDEV_PREFIX"*
|
||||
}
|
||||
|
||||
log_assert \
|
||||
"'zpool split -n <pool> <newpool> [<vdev>]...' can display the configuration"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
# Create needed file vdevs.
|
||||
for (( i=0; i < ${#dev[@]}; i+=1 )); do
|
||||
log_must truncate -s $SPA_MINDEVSIZE "${dev[$i]}"
|
||||
done
|
||||
|
||||
# Foreach test create pool, add -n devices and check output.
|
||||
for (( i=0; i < ${#tests[@]}; i+=1 )); do
|
||||
typeset tree="${tests[$i].tree}"
|
||||
typeset devs="${tests[$i].devs}"
|
||||
typeset want="${tests[$i].want}"
|
||||
|
||||
log_must eval zpool create "$TESTPOOL" $tree
|
||||
log_must poolexists "$TESTPOOL"
|
||||
typeset out="$(log_must eval "zpool split -n \
|
||||
'$TESTPOOL' '$NEWPOOL' $devs" | sed /^SUCCESS/d)"
|
||||
|
||||
if [[ "$out" != "$want" ]]; then
|
||||
log_fail "Got:\n" "$out" "\nbut expected:\n" "$want"
|
||||
fi
|
||||
log_must destroy_pool "$TESTPOOL"
|
||||
done
|
||||
|
||||
log_pass \
|
||||
"'zpool split -n <pool> <newpool> [<vdev>]...' displays config correctly."
|
||||
@@ -45,11 +45,11 @@ log_must zfs snapshot $clone2@snap
|
||||
|
||||
# Incompatible flags
|
||||
log_must zfs redact $sendfs@snap2 book $clone1@snap
|
||||
log_mustnot eval "zfs send -R --redact book $sendfs@snap2 >/dev/null"
|
||||
log_mustnot eval "zfs send -R --redact book $sendfs@snap2 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
typeset arg
|
||||
for arg in "$sendfs" "$clone1#book"; do
|
||||
log_mustnot eval "zfs send --redact book $arg >/dev/null"
|
||||
log_mustnot eval "zfs send --redact book $arg >$TEST_BASE_DIR/devnull"
|
||||
done
|
||||
|
||||
# Bad redaction list arguments
|
||||
@@ -58,7 +58,7 @@ log_mustnot zfs redact $sendfs@snap1 book
|
||||
log_mustnot zfs redact $sendfs#book1 book4 $clone1
|
||||
log_mustnot zfs redact $sendfs@snap1 book snap2 snap3
|
||||
log_mustnot zfs redact $sendfs@snap1 book @snap2 @snap3
|
||||
log_mustnot eval "zfs send --redact $sendfs#book $sendfs@snap >/dev/null"
|
||||
log_mustnot eval "zfs send --redact $sendfs#book $sendfs@snap >$TEST_BASE_DIR/devnull"
|
||||
|
||||
# Redaction snapshots not a descendant of tosnap
|
||||
log_mustnot zfs redact $sendfs@snap2 book $sendfs@snap2
|
||||
@@ -66,7 +66,7 @@ log_must zfs redact $sendfs@snap2 book2 $clone1@snap $clone2@snap
|
||||
log_must eval "zfs send --redact book2 $sendfs@snap2 >$stream"
|
||||
log_must zfs redact $sendfs@snap2 book3 $clone1@snap $clone2@snap
|
||||
log_must eval "zfs send -i $sendfs@snap1 --redact book3 $sendfs@snap2 \
|
||||
>/dev/null"
|
||||
>$TEST_BASE_DIR/devnull"
|
||||
log_mustnot zfs redact $sendfs@snap3 $sendfs@snap3 $clone1@snap
|
||||
|
||||
# Full redacted sends of redacted datasets are not allowed.
|
||||
|
||||
@@ -81,7 +81,7 @@ log_must eval "zfs send --redact book1 $sendfs@snap >$stream"
|
||||
dd if=$stream bs=64k count=1 | log_mustnot zfs receive -s $recvfs
|
||||
[[ "-" = $(get_prop receive_resume_token $recvfs) ]] && \
|
||||
log_fail "Receive token not found."
|
||||
log_mustnot eval "zfs send --saved --redact book1 $recvfs > /dev/null"
|
||||
log_mustnot eval "zfs send --saved --redact book1 $recvfs >$TEST_BASE_DIR/devnull"
|
||||
log_must zfs recv -A $recvfs
|
||||
log_must datasetnonexists $recvfs
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ function callback
|
||||
{
|
||||
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
|
||||
log_must ksh -c \
|
||||
"zfs send $TESTPOOL/$TESTFS@$TESTSNAP >/dev/null"
|
||||
"zfs send $TESTPOOL/$TESTFS@$TESTSNAP >$TEST_BASE_DIR/devnull"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ log_must zfs snap $testfs@snap0
|
||||
log_must zfs snap $testfs@snap1
|
||||
|
||||
# Test bad send with the CLI
|
||||
log_mustnot eval "zfs send -i $testfs@snap1 $testfs@snap0 >/dev/null"
|
||||
log_mustnot eval "zfs send -i $testfs@snap1 $testfs@snap0 >$TEST_BASE_DIR/devnull"
|
||||
|
||||
# Test bad send with libzfs/libzfs_core
|
||||
log_must badsend $testfs@snap0 $testfs@snap1
|
||||
|
||||
@@ -103,7 +103,7 @@ set -A badargs \
|
||||
|
||||
while (( i < ${#badargs[*]} ))
|
||||
do
|
||||
log_mustnot eval "zfs send --saved ${badargs[i]} >/dev/null"
|
||||
log_mustnot eval "zfs send --saved ${badargs[i]} >$TEST_BASE_DIR/devnull"
|
||||
(( i = i + 1 ))
|
||||
done
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#
|
||||
if is_linux; then
|
||||
SAVESWAPDEVS=$(swapon -s | nawk '(NR != 1) {print $1}')
|
||||
elif is_freebsd; then
|
||||
SAVESWAPDEVS=$(swapctl -l | nawk '(NR != 1) {print $1}')
|
||||
else
|
||||
SAVESWAPDEVS=$(swap -l | nawk '(NR != 1) {print $1}')
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user