zfs: merge openzfs/zfs@5605a6d79
Notable upstream pull request merges: #1602526b0f561bdnode_next_offset: backtrack if lower level does not match #17758c722bf881Add interface to interface spa_get_worst_case_min_alloc() function #177658d4c3ee9ezvol: Fix blk-mq sync #177878869caae5zinject: Introduce ready delay fault injection #17780b2196fbedFix 'zpool add' safety check corner cases #177835c38029f4zdb: add ZFS_KEYFORMAT_RAW support for -K option #17786f0a95e897zpool iostat: refresh pool list every interval #17807 -multiple zpool iostat: fix regressions in "all pools" mode after #17786 #17793 -multiple ddt prune: Add SCL_ZIO deadlock workaround #17799ac2d8c80bMake mount/share errors non-fatal for zfs create/clone Obtained from: OpenZFS OpenZFS commit:5605a6d79b
This commit is contained in:
@@ -14,7 +14,7 @@ Please check our issue tracker before opening a new feature request.
|
||||
Filling out the following template will help other contributors better understand your proposed feature.
|
||||
-->
|
||||
|
||||
### Describe the feature would like to see added to OpenZFS
|
||||
### Describe the feature you would like to see added to OpenZFS
|
||||
|
||||
<!--
|
||||
Provide a clear and concise description of the feature.
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
<!--- Provide a general summary of your changes in the Title above -->
|
||||
|
||||
<!---
|
||||
Documentation on ZFS Buildbot options can be found at
|
||||
https://openzfs.github.io/openzfs-docs/Developer%20Resources/Buildbot%20Options.html
|
||||
-->
|
||||
|
||||
### Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
@@ -121,7 +121,7 @@ case "$OS" in
|
||||
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
|
||||
;;
|
||||
freebsd15-0c)
|
||||
FreeBSD="15.0-ALPHA2"
|
||||
FreeBSD="15.0-ALPHA3"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
OSv="freebsd14.0"
|
||||
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
|
||||
|
||||
@@ -20,7 +20,7 @@ function archlinux() {
|
||||
sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \
|
||||
fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \
|
||||
parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \
|
||||
samba sysstat rng-tools rsync wget xxhash
|
||||
samba strace sysstat rng-tools rsync wget xxhash
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ function debian() {
|
||||
lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
|
||||
python3-cffi python3-dev python3-distlib python3-packaging libtirpc-dev \
|
||||
python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
|
||||
rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev
|
||||
rsync samba strace sysstat uuid-dev watchdog wget xfslibs-dev xxhash \
|
||||
zlib1g-dev
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
@@ -87,8 +88,8 @@ function rhel() {
|
||||
libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \
|
||||
parted perf python3 python3-cffi python3-devel python3-packaging \
|
||||
kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
|
||||
rpm-build rsync samba sysstat systemd watchdog wget xfsprogs-devel xxhash \
|
||||
zlib-devel
|
||||
rpm-build rsync samba strace sysstat systemd watchdog wget xfsprogs-devel \
|
||||
xxhash zlib-devel
|
||||
echo "##[endgroup]"
|
||||
}
|
||||
|
||||
@@ -104,7 +105,7 @@ function install_fedora_experimental_kernel {
|
||||
our_version="$1"
|
||||
sudo dnf -y copr enable @kernel-vanilla/stable
|
||||
sudo dnf -y copr enable @kernel-vanilla/mainline
|
||||
all="$(sudo dnf list --showduplicates kernel-*)"
|
||||
all="$(sudo dnf list --showduplicates kernel-* python3-perf* perf* bpftool*)"
|
||||
echo "Available versions:"
|
||||
echo "$all"
|
||||
|
||||
|
||||
@@ -108,19 +108,30 @@ echo '*/5 * * * * /root/cronjob.sh' > crontab.txt
|
||||
sudo crontab crontab.txt
|
||||
rm crontab.txt
|
||||
|
||||
# check if the machines are okay
|
||||
echo "Waiting for vm's to come up... (${VMs}x CPU=$CPU RAM=$RAM)"
|
||||
for ((i=1; i<=VMs; i++)); do
|
||||
.github/workflows/scripts/qemu-wait-for-vm.sh vm$i
|
||||
done
|
||||
echo "All $VMs VMs are up now."
|
||||
|
||||
# Save the VM's serial output (ttyS0) to /var/tmp/console.txt
|
||||
# - ttyS0 on the VM corresponds to a local /dev/pty/N entry
|
||||
# - use 'virsh ttyconsole' to lookup the /dev/pty/N entry
|
||||
for ((i=1; i<=VMs; i++)); do
|
||||
mkdir -p $RESPATH/vm$i
|
||||
read "pty" <<< $(sudo virsh ttyconsole vm$i)
|
||||
|
||||
# Create the file so we can tail it, even if there's no output.
|
||||
touch $RESPATH/vm$i/console.txt
|
||||
|
||||
sudo nohup bash -c "cat $pty > $RESPATH/vm$i/console.txt" &
|
||||
|
||||
# Write all VM boot lines to the console to aid in debugging failed boots.
|
||||
# The boot lines from all the VMs will be munged together, so prepend each
|
||||
# line with the vm hostname (like 'vm1:').
|
||||
(while IFS=$'\n' read -r line; do echo "vm$i: $line" ; done < <(sudo tail -f $RESPATH/vm$i/console.txt)) &
|
||||
|
||||
done
|
||||
echo "Console logging for ${VMs}x $OS started."
|
||||
|
||||
|
||||
# check if the machines are okay
|
||||
echo "Waiting for vm's to come up... (${VMs}x CPU=$CPU RAM=$RAM)"
|
||||
for ((i=1; i<=VMs; i++)); do
|
||||
.github/workflows/scripts/qemu-wait-for-vm.sh vm$i
|
||||
done
|
||||
echo "All $VMs VMs are up now."
|
||||
|
||||
@@ -111,7 +111,7 @@ fi
|
||||
sudo dmesg -c > dmesg-prerun.txt
|
||||
mount > mount.txt
|
||||
df -h > df-prerun.txt
|
||||
$TDIR/zfs-tests.sh -vK -s 3GB -T $TAGS
|
||||
$TDIR/zfs-tests.sh -vKO -s 3GB -T $TAGS
|
||||
RV=$?
|
||||
df -h > df-postrun.txt
|
||||
echo $RV > tests-exitcode.txt
|
||||
|
||||
@@ -6,5 +6,5 @@ Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
Author: OpenZFS
|
||||
Linux-Maximum: 6.16
|
||||
Linux-Maximum: 6.17
|
||||
Linux-Minimum: 4.18
|
||||
|
||||
@@ -3301,6 +3301,7 @@ zdb_derive_key(dsl_dir_t *dd, uint8_t *key_out)
|
||||
uint64_t keyformat, salt, iters;
|
||||
int i;
|
||||
unsigned char c;
|
||||
FILE *f;
|
||||
|
||||
VERIFY0(zap_lookup(dd->dd_pool->dp_meta_objset, dd->dd_crypto_obj,
|
||||
zfs_prop_to_name(ZFS_PROP_KEYFORMAT), sizeof (uint64_t),
|
||||
@@ -3333,6 +3334,25 @@ zdb_derive_key(dsl_dir_t *dd, uint8_t *key_out)
|
||||
|
||||
break;
|
||||
|
||||
case ZFS_KEYFORMAT_RAW:
|
||||
if ((f = fopen(key_material, "r")) == NULL)
|
||||
return (B_FALSE);
|
||||
|
||||
if (fread(key_out, 1, WRAPPING_KEY_LEN, f) !=
|
||||
WRAPPING_KEY_LEN) {
|
||||
(void) fclose(f);
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
/* Check the key length */
|
||||
if (fgetc(f) != EOF) {
|
||||
(void) fclose(f);
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
(void) fclose(f);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("no support for key format %u\n",
|
||||
(unsigned int) keyformat);
|
||||
|
||||
@@ -914,7 +914,11 @@ zfs_do_clone(int argc, char **argv)
|
||||
log_history = B_FALSE;
|
||||
}
|
||||
|
||||
ret = zfs_mount_and_share(g_zfs, argv[1], ZFS_TYPE_DATASET);
|
||||
/*
|
||||
* Dataset cloned successfully, mount/share failures are
|
||||
* non-fatal.
|
||||
*/
|
||||
(void) zfs_mount_and_share(g_zfs, argv[1], ZFS_TYPE_DATASET);
|
||||
}
|
||||
|
||||
zfs_close(zhp);
|
||||
@@ -930,19 +934,15 @@ zfs_do_clone(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a default volblocksize for the pool which always uses more than
|
||||
* half of the data sectors. This primarily applies to dRAID which always
|
||||
* writes full stripe widths.
|
||||
* Calculate the minimum allocation size based on the top-level vdevs.
|
||||
*/
|
||||
static uint64_t
|
||||
default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
|
||||
calculate_volblocksize(nvlist_t *config)
|
||||
{
|
||||
uint64_t volblocksize, asize = SPA_MINBLOCKSIZE;
|
||||
uint64_t asize = SPA_MINBLOCKSIZE;
|
||||
nvlist_t *tree, **vdevs;
|
||||
uint_t nvdevs;
|
||||
|
||||
nvlist_t *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) {
|
||||
@@ -973,6 +973,24 @@ default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
|
||||
}
|
||||
}
|
||||
|
||||
return (asize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a default volblocksize for the pool which always uses more than
|
||||
* half of the data sectors. This primarily applies to dRAID which always
|
||||
* writes full stripe widths.
|
||||
*/
|
||||
static uint64_t
|
||||
default_volblocksize(zpool_handle_t *zhp, nvlist_t *props)
|
||||
{
|
||||
uint64_t volblocksize, asize = SPA_MINBLOCKSIZE;
|
||||
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
|
||||
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_MAX_ALLOC, &asize) != 0)
|
||||
asize = calculate_volblocksize(config);
|
||||
|
||||
/*
|
||||
* Calculate the target volblocksize such that more than half
|
||||
* of the asize is used. The following table is for 4k sectors.
|
||||
@@ -1319,7 +1337,9 @@ zfs_do_create(int argc, char **argv)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = zfs_mount_and_share(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||
/* Dataset created successfully, mount/share failures are non-fatal */
|
||||
ret = 0;
|
||||
(void) zfs_mount_and_share(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||
error:
|
||||
nvlist_free(props);
|
||||
return (ret);
|
||||
|
||||
@@ -107,6 +107,8 @@
|
||||
* zinject
|
||||
* zinject <-a | -u pool>
|
||||
* zinject -c <id|all>
|
||||
* zinject -E <delay> [-a] [-m] [-f freq] [-l level] [-r range]
|
||||
* [-T iotype] [-t type object | -b bookmark pool]
|
||||
* zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
|
||||
* [-r range] <object>
|
||||
* zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
|
||||
@@ -132,14 +134,18 @@
|
||||
* The '-f' flag controls the frequency of errors injected, expressed as a
|
||||
* real number percentage between 0.0001 and 100. The default is 100.
|
||||
*
|
||||
* The this form is responsible for actually injecting the handler into the
|
||||
* The <object> form is responsible for actually injecting the handler into the
|
||||
* framework. It takes the arguments described above, translates them to the
|
||||
* internal tuple using libzpool, and then issues an ioctl() to register the
|
||||
* handler.
|
||||
*
|
||||
* The final form can target a specific bookmark, regardless of whether a
|
||||
* The '-b' option can target a specific bookmark, regardless of whether a
|
||||
* human-readable interface has been designed. It allows developers to specify
|
||||
* a particular block by number.
|
||||
*
|
||||
* The '-E' option injects pipeline ready stage delays for the given object or
|
||||
* bookmark. The delay is specified in milliseconds, and it supports I/O type
|
||||
* and range filters.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -346,6 +352,13 @@ usage(void)
|
||||
"\t\tsuch that the operation takes a minimum of supplied seconds\n"
|
||||
"\t\tto complete.\n"
|
||||
"\n"
|
||||
"\tzinject -E <delay> [-a] [-m] [-f freq] [-l level] [-r range]\n"
|
||||
"\t\t[-T iotype] [-t type object | -b bookmark pool]\n"
|
||||
"\n"
|
||||
"\t\tInject pipeline ready stage delays for the given object path\n"
|
||||
"\t\t(data or dnode) or raw bookmark. The delay is specified in\n"
|
||||
"\t\tmilliseconds.\n"
|
||||
"\n"
|
||||
"\tzinject -I [-s <seconds> | -g <txgs>] pool\n"
|
||||
"\t\tCause the pool to stop writing blocks yet not\n"
|
||||
"\t\treport errors for a duration. Simulates buggy hardware\n"
|
||||
@@ -724,12 +737,15 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
||||
if (quiet) {
|
||||
(void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
|
||||
} else {
|
||||
boolean_t show_object = B_FALSE;
|
||||
boolean_t show_iotype = B_FALSE;
|
||||
(void) printf("Added handler %llu with the following "
|
||||
"properties:\n", (u_longlong_t)zc.zc_guid);
|
||||
(void) printf(" pool: %s\n", pool);
|
||||
if (record->zi_guid) {
|
||||
(void) printf(" vdev: %llx\n",
|
||||
(u_longlong_t)record->zi_guid);
|
||||
show_iotype = B_TRUE;
|
||||
} else if (record->zi_func[0] != '\0') {
|
||||
(void) printf(" panic function: %s\n",
|
||||
record->zi_func);
|
||||
@@ -742,7 +758,18 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
||||
} else if (record->zi_timer > 0) {
|
||||
(void) printf(" timer: %lld ms\n",
|
||||
(u_longlong_t)NSEC2MSEC(record->zi_timer));
|
||||
if (record->zi_cmd == ZINJECT_DELAY_READY) {
|
||||
show_object = B_TRUE;
|
||||
show_iotype = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
show_object = B_TRUE;
|
||||
}
|
||||
if (show_iotype) {
|
||||
(void) printf("iotype: %s\n",
|
||||
iotype_to_str(record->zi_iotype));
|
||||
}
|
||||
if (show_object) {
|
||||
(void) printf("objset: %llu\n",
|
||||
(u_longlong_t)record->zi_objset);
|
||||
(void) printf("object: %llu\n",
|
||||
@@ -910,6 +937,7 @@ main(int argc, char **argv)
|
||||
int ret;
|
||||
int flags = 0;
|
||||
uint32_t dvas = 0;
|
||||
hrtime_t ready_delay = -1;
|
||||
|
||||
if ((g_zfs = libzfs_init()) == NULL) {
|
||||
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
|
||||
@@ -940,7 +968,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
":aA:b:C:d:D:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) {
|
||||
":aA:b:C:d:D:E:f:Fg:qhIc:t:T:l:mr:s:e:uL:p:P:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
flags |= ZINJECT_FLUSH_ARC;
|
||||
@@ -1113,6 +1141,18 @@ main(int argc, char **argv)
|
||||
case 'u':
|
||||
flags |= ZINJECT_UNLOAD_SPA;
|
||||
break;
|
||||
case 'E':
|
||||
ready_delay = MSEC2NSEC(strtol(optarg, &end, 10));
|
||||
if (ready_delay <= 0 || *end != '\0') {
|
||||
(void) fprintf(stderr, "invalid delay '%s': "
|
||||
"must be a positive duration\n", optarg);
|
||||
usage();
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
}
|
||||
record.zi_cmd = ZINJECT_DELAY_READY;
|
||||
record.zi_timer = ready_delay;
|
||||
break;
|
||||
case 'L':
|
||||
if ((label = name_to_type(optarg)) == TYPE_INVAL &&
|
||||
!LABEL_TYPE(type)) {
|
||||
@@ -1150,7 +1190,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
||||
record.zi_freq > 0 || dvas != 0) {
|
||||
record.zi_freq > 0 || dvas != 0 || ready_delay >= 0) {
|
||||
(void) fprintf(stderr, "cancel (-c) incompatible with "
|
||||
"any other options\n");
|
||||
usage();
|
||||
@@ -1186,7 +1226,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || record.zi_cmd != ZINJECT_UNINITIALIZED ||
|
||||
dvas != 0) {
|
||||
dvas != 0 || ready_delay >= 0) {
|
||||
(void) fprintf(stderr, "device (-d) incompatible with "
|
||||
"data error injection\n");
|
||||
usage();
|
||||
@@ -1276,13 +1316,23 @@ main(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
|
||||
record.zi_cmd = ZINJECT_DATA_FAULT;
|
||||
if (record.zi_cmd == ZINJECT_UNINITIALIZED) {
|
||||
record.zi_cmd = ZINJECT_DATA_FAULT;
|
||||
if (!error)
|
||||
error = EIO;
|
||||
} else if (error != 0) {
|
||||
(void) fprintf(stderr, "error type -e incompatible "
|
||||
"with delay injection\n");
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
} else {
|
||||
record.zi_iotype = io_type;
|
||||
}
|
||||
|
||||
if (translate_raw(raw, &record) != 0) {
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
}
|
||||
if (!error)
|
||||
error = EIO;
|
||||
} else if (record.zi_cmd == ZINJECT_PANIC) {
|
||||
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
|
||||
level != 0 || device != NULL || record.zi_freq > 0 ||
|
||||
@@ -1410,6 +1460,13 @@ main(int argc, char **argv)
|
||||
record.zi_dvas = dvas;
|
||||
}
|
||||
|
||||
if (record.zi_cmd != ZINJECT_UNINITIALIZED && error != 0) {
|
||||
(void) fprintf(stderr, "error type -e incompatible "
|
||||
"with delay injection\n");
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (error == EACCES) {
|
||||
if (type != TYPE_DATA) {
|
||||
(void) fprintf(stderr, "decryption errors "
|
||||
@@ -1425,8 +1482,12 @@ main(int argc, char **argv)
|
||||
* not found.
|
||||
*/
|
||||
error = ECKSUM;
|
||||
} else {
|
||||
} else if (record.zi_cmd == ZINJECT_UNINITIALIZED) {
|
||||
record.zi_cmd = ZINJECT_DATA_FAULT;
|
||||
if (!error)
|
||||
error = EIO;
|
||||
} else {
|
||||
record.zi_iotype = io_type;
|
||||
}
|
||||
|
||||
if (translate_record(type, argv[0], range, level, &record, pool,
|
||||
@@ -1434,8 +1495,6 @@ main(int argc, char **argv)
|
||||
libzfs_fini(g_zfs);
|
||||
return (1);
|
||||
}
|
||||
if (!error)
|
||||
error = EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <libintl.h>
|
||||
@@ -52,7 +53,7 @@
|
||||
typedef struct zpool_node {
|
||||
zpool_handle_t *zn_handle;
|
||||
uu_avl_node_t zn_avlnode;
|
||||
int zn_mark;
|
||||
hrtime_t zn_last_refresh;
|
||||
} zpool_node_t;
|
||||
|
||||
struct zpool_list {
|
||||
@@ -62,6 +63,7 @@ struct zpool_list {
|
||||
uu_avl_pool_t *zl_pool;
|
||||
zprop_list_t **zl_proplist;
|
||||
zfs_type_t zl_type;
|
||||
hrtime_t zl_last_refresh;
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -81,32 +83,48 @@ zpool_compare(const void *larg, const void *rarg, void *unused)
|
||||
* of known pools.
|
||||
*/
|
||||
static int
|
||||
add_pool(zpool_handle_t *zhp, void *data)
|
||||
add_pool(zpool_handle_t *zhp, zpool_list_t *zlp)
|
||||
{
|
||||
zpool_list_t *zlp = data;
|
||||
zpool_node_t *node = safe_malloc(sizeof (zpool_node_t));
|
||||
zpool_node_t *node, *new = safe_malloc(sizeof (zpool_node_t));
|
||||
uu_avl_index_t idx;
|
||||
|
||||
node->zn_handle = zhp;
|
||||
uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
|
||||
if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
|
||||
new->zn_handle = zhp;
|
||||
uu_avl_node_init(new, &new->zn_avlnode, zlp->zl_pool);
|
||||
|
||||
node = uu_avl_find(zlp->zl_avl, new, NULL, &idx);
|
||||
if (node == NULL) {
|
||||
if (zlp->zl_proplist &&
|
||||
zpool_expand_proplist(zhp, zlp->zl_proplist,
|
||||
zlp->zl_type, zlp->zl_literal) != 0) {
|
||||
zpool_close(zhp);
|
||||
free(node);
|
||||
free(new);
|
||||
return (-1);
|
||||
}
|
||||
uu_avl_insert(zlp->zl_avl, node, idx);
|
||||
new->zn_last_refresh = zlp->zl_last_refresh;
|
||||
uu_avl_insert(zlp->zl_avl, new, idx);
|
||||
} else {
|
||||
zpool_refresh_stats_from_handle(node->zn_handle, zhp);
|
||||
node->zn_last_refresh = zlp->zl_last_refresh;
|
||||
zpool_close(zhp);
|
||||
free(node);
|
||||
free(new);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* add_pool(), but always returns 0. This allows zpool_iter() to continue
|
||||
* even if a pool exists in the tree, or we fail to get the properties for
|
||||
* a new one.
|
||||
*/
|
||||
static int
|
||||
add_pool_cb(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
(void) add_pool(zhp, data);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a list of pools based on the given arguments. If we're given no
|
||||
* arguments, then iterate over all pools in the system and add them to the AVL
|
||||
@@ -135,9 +153,10 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
|
||||
zlp->zl_type = type;
|
||||
|
||||
zlp->zl_literal = literal;
|
||||
zlp->zl_last_refresh = gethrtime();
|
||||
|
||||
if (argc == 0) {
|
||||
(void) zpool_iter(g_zfs, add_pool, zlp);
|
||||
(void) zpool_iter(g_zfs, add_pool_cb, zlp);
|
||||
zlp->zl_findall = B_TRUE;
|
||||
} else {
|
||||
int i;
|
||||
@@ -159,15 +178,61 @@ pool_list_get(int argc, char **argv, zprop_list_t **proplist, zfs_type_t type,
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for any new pools, adding them to the list. We only add pools when no
|
||||
* options were given on the command line. Otherwise, we keep the list fixed as
|
||||
* those that were explicitly specified.
|
||||
* Refresh the state of all pools on the list. Additionally, if no options were
|
||||
* given on the command line, add any new pools and remove any that are no
|
||||
* longer available.
|
||||
*/
|
||||
void
|
||||
pool_list_update(zpool_list_t *zlp)
|
||||
int
|
||||
pool_list_refresh(zpool_list_t *zlp)
|
||||
{
|
||||
if (zlp->zl_findall)
|
||||
(void) zpool_iter(g_zfs, add_pool, zlp);
|
||||
zlp->zl_last_refresh = gethrtime();
|
||||
|
||||
if (!zlp->zl_findall) {
|
||||
/*
|
||||
* This list is a fixed list of pools, so we must not add
|
||||
* or remove any. Just walk over them and refresh their
|
||||
* state.
|
||||
*/
|
||||
int navail = 0;
|
||||
for (zpool_node_t *node = uu_avl_first(zlp->zl_avl);
|
||||
node != NULL; node = uu_avl_next(zlp->zl_avl, node)) {
|
||||
boolean_t missing;
|
||||
zpool_refresh_stats(node->zn_handle, &missing);
|
||||
navail += !missing;
|
||||
node->zn_last_refresh = zlp->zl_last_refresh;
|
||||
}
|
||||
return (navail);
|
||||
}
|
||||
|
||||
/* Search for any new pools and add them to the list. */
|
||||
(void) zpool_iter(g_zfs, add_pool_cb, zlp);
|
||||
|
||||
/* Walk the list of existing pools, and update or remove them. */
|
||||
zpool_node_t *node, *next;
|
||||
for (node = uu_avl_first(zlp->zl_avl); node != NULL; node = next) {
|
||||
next = uu_avl_next(zlp->zl_avl, node);
|
||||
|
||||
/*
|
||||
* Skip any that were refreshed and are online; they were added
|
||||
* by zpool_iter() and are already up to date.
|
||||
*/
|
||||
if (node->zn_last_refresh == zlp->zl_last_refresh &&
|
||||
zpool_get_state(node->zn_handle) != POOL_STATE_UNAVAIL)
|
||||
continue;
|
||||
|
||||
/* Refresh and remove if necessary. */
|
||||
boolean_t missing;
|
||||
zpool_refresh_stats(node->zn_handle, &missing);
|
||||
if (missing) {
|
||||
uu_avl_remove(zlp->zl_avl, node);
|
||||
zpool_close(node->zn_handle);
|
||||
free(node);
|
||||
} else {
|
||||
node->zn_last_refresh = zlp->zl_last_refresh;
|
||||
}
|
||||
}
|
||||
|
||||
return (uu_avl_numnodes(zlp->zl_avl));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -190,23 +255,6 @@ pool_list_iter(zpool_list_t *zlp, int unavail, zpool_iter_f func,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the given pool from the list. When running iostat, we want to remove
|
||||
* those pools that no longer exist.
|
||||
*/
|
||||
void
|
||||
pool_list_remove(zpool_list_t *zlp, zpool_handle_t *zhp)
|
||||
{
|
||||
zpool_node_t search, *node;
|
||||
|
||||
search.zn_handle = zhp;
|
||||
if ((node = uu_avl_find(zlp->zl_avl, &search, NULL, NULL)) != NULL) {
|
||||
uu_avl_remove(zlp->zl_avl, node);
|
||||
zpool_close(node->zn_handle);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all the handles associated with this list.
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
|
||||
* Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
|
||||
* Copyright (c) 2021, 2023, Klara Inc.
|
||||
* Copyright (c) 2021, 2023, 2025, Klara, Inc.
|
||||
* Copyright (c) 2021, 2025 Hewlett Packard Enterprise Development LP.
|
||||
*/
|
||||
|
||||
@@ -5761,24 +5761,6 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
refresh_iostat(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
iostat_cbdata_t *cb = data;
|
||||
boolean_t missing;
|
||||
|
||||
/*
|
||||
* If the pool has disappeared, remove it from the list and continue.
|
||||
*/
|
||||
if (zpool_refresh_stats(zhp, &missing) != 0)
|
||||
return (-1);
|
||||
|
||||
if (missing)
|
||||
pool_list_remove(cb->cb_list, zhp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback to print out the iostats for the given pool.
|
||||
*/
|
||||
@@ -6359,15 +6341,14 @@ get_namewidth_iostat(zpool_handle_t *zhp, void *data)
|
||||
* This command can be tricky because we want to be able to deal with pool
|
||||
* creation/destruction as well as vdev configuration changes. The bulk of this
|
||||
* processing is handled by the pool_list_* routines in zpool_iter.c. We rely
|
||||
* on pool_list_update() to detect the addition of new pools. Configuration
|
||||
* changes are all handled within libzfs.
|
||||
* on pool_list_refresh() to detect the addition and removal of pools.
|
||||
* Configuration changes are all handled within libzfs.
|
||||
*/
|
||||
int
|
||||
zpool_do_iostat(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int ret;
|
||||
int npools;
|
||||
float interval = 0;
|
||||
unsigned long count = 0;
|
||||
zpool_list_t *list;
|
||||
@@ -6618,10 +6599,24 @@ zpool_do_iostat(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
|
||||
int last_npools = 0;
|
||||
for (;;) {
|
||||
if ((npools = pool_list_count(list)) == 0)
|
||||
/*
|
||||
* Refresh all pools in list, adding or removing pools as
|
||||
* necessary.
|
||||
*/
|
||||
int npools = pool_list_refresh(list);
|
||||
if (npools == 0) {
|
||||
(void) fprintf(stderr, gettext("no pools available\n"));
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* If the list of pools has changed since last time
|
||||
* around, reset the iteration count to force the
|
||||
* header to be redisplayed.
|
||||
*/
|
||||
if (last_npools != npools)
|
||||
cb.cb_iteration = 0;
|
||||
|
||||
/*
|
||||
* If this is the first iteration and -y was supplied
|
||||
* we skip any printing.
|
||||
@@ -6629,15 +6624,6 @@ zpool_do_iostat(int argc, char **argv)
|
||||
boolean_t skip = (omit_since_boot &&
|
||||
cb.cb_iteration == 0);
|
||||
|
||||
/*
|
||||
* Refresh all statistics. This is done as an
|
||||
* explicit step before calculating the maximum name
|
||||
* width, so that any * configuration changes are
|
||||
* properly accounted for.
|
||||
*/
|
||||
(void) pool_list_iter(list, B_FALSE, refresh_iostat,
|
||||
&cb);
|
||||
|
||||
/*
|
||||
* Iterate over all pools to determine the maximum width
|
||||
* for the pool / device name column across all pools.
|
||||
@@ -6691,6 +6677,7 @@ zpool_do_iostat(int argc, char **argv)
|
||||
if (skip) {
|
||||
(void) fflush(stdout);
|
||||
(void) fsleep(interval);
|
||||
last_npools = npools;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6728,6 +6715,8 @@ zpool_do_iostat(int argc, char **argv)
|
||||
|
||||
(void) fflush(stdout);
|
||||
(void) fsleep(interval);
|
||||
|
||||
last_npools = npools;
|
||||
}
|
||||
|
||||
pool_list_free(list);
|
||||
|
||||
@@ -76,11 +76,10 @@ typedef struct zpool_list zpool_list_t;
|
||||
|
||||
zpool_list_t *pool_list_get(int, char **, zprop_list_t **, zfs_type_t,
|
||||
boolean_t, int *);
|
||||
void pool_list_update(zpool_list_t *);
|
||||
int pool_list_refresh(zpool_list_t *);
|
||||
int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
|
||||
void pool_list_free(zpool_list_t *);
|
||||
int pool_list_count(zpool_list_t *);
|
||||
void pool_list_remove(zpool_list_t *, zpool_handle_t *);
|
||||
|
||||
extern libzfs_handle_t *g_zfs;
|
||||
|
||||
|
||||
@@ -609,22 +609,28 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||
ZPOOL_CONFIG_PATH, &path) == 0);
|
||||
|
||||
/*
|
||||
* If we have a raidz/mirror that combines disks
|
||||
* with files, report it as an error.
|
||||
* Skip active spares they should never cause
|
||||
* the pool to be evaluated as inconsistent.
|
||||
*/
|
||||
if (!dontreport && type != NULL &&
|
||||
if (is_spare(NULL, path))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If we have a raidz/mirror that combines disks
|
||||
* with files, only report it as an error when
|
||||
* fatal is set to ensure all the replication
|
||||
* checks aren't skipped in check_replication().
|
||||
*/
|
||||
if (fatal && !dontreport && type != NULL &&
|
||||
strcmp(type, childtype) != 0) {
|
||||
if (ret != NULL)
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
if (fatal)
|
||||
vdev_error(gettext(
|
||||
"mismatched replication "
|
||||
"level: %s contains both "
|
||||
"files and devices\n"),
|
||||
rep.zprl_type);
|
||||
else
|
||||
return (NULL);
|
||||
vdev_error(gettext(
|
||||
"mismatched replication "
|
||||
"level: %s contains both "
|
||||
"files and devices\n"),
|
||||
rep.zprl_type);
|
||||
dontreport = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ This contrib contains community compatibility patches to get Intel QAT working o
|
||||
These patches are based on the following Intel QAT version:
|
||||
[1.7.l.4.10.0-00014](https://01.org/sites/default/files/downloads/qat1.7.l.4.10.0-00014.tar.gz)
|
||||
|
||||
When using QAT with above kernels versions, the following patches needs to be applied using:
|
||||
When using QAT with the above kernel versions, the following patches need to be applied using:
|
||||
patch -p1 < _$PATCH_
|
||||
_Where $PATCH refers to the path of the patch in question_
|
||||
|
||||
|
||||
@@ -4223,7 +4223,7 @@ def reset(self):
|
||||
self.getRoot().reset()
|
||||
return
|
||||
|
||||
# On the Buildbot builders this may fail with "pool is busy"
|
||||
# On the CI builders this may fail with "pool is busy"
|
||||
# Retry 5 times before raising an error
|
||||
retry = 0
|
||||
while True:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
DESCRIPTION
|
||||
These script were written with the primary intention of being portable and
|
||||
These scripts were written with the primary intention of being portable and
|
||||
usable on as many systems as possible.
|
||||
|
||||
This is, in practice, usually not possible. But the intention is there.
|
||||
|
||||
@@ -479,6 +479,8 @@ _LIBZFS_H zpool_status_t zpool_import_status(nvlist_t *, const char **,
|
||||
_LIBZFS_H nvlist_t *zpool_get_config(zpool_handle_t *, nvlist_t **);
|
||||
_LIBZFS_H nvlist_t *zpool_get_features(zpool_handle_t *);
|
||||
_LIBZFS_H int zpool_refresh_stats(zpool_handle_t *, boolean_t *);
|
||||
_LIBZFS_H void zpool_refresh_stats_from_handle(zpool_handle_t *,
|
||||
zpool_handle_t *);
|
||||
_LIBZFS_H int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
|
||||
_LIBZFS_H void zpool_add_propname(zpool_handle_t *, const char *);
|
||||
|
||||
|
||||
@@ -542,24 +542,6 @@ blk_generic_alloc_queue(make_request_fn make_request, int node_id)
|
||||
}
|
||||
#endif /* !HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS */
|
||||
|
||||
/*
|
||||
* All the io_*() helper functions below can operate on a bio, or a rq, but
|
||||
* not both. The older submit_bio() codepath will pass a bio, and the
|
||||
* newer blk-mq codepath will pass a rq.
|
||||
*/
|
||||
static inline int
|
||||
io_data_dir(struct bio *bio, struct request *rq)
|
||||
{
|
||||
if (rq != NULL) {
|
||||
if (op_is_write(req_op(rq))) {
|
||||
return (WRITE);
|
||||
} else {
|
||||
return (READ);
|
||||
}
|
||||
}
|
||||
return (bio_data_dir(bio));
|
||||
}
|
||||
|
||||
static inline int
|
||||
io_is_flush(struct bio *bio, struct request *rq)
|
||||
{
|
||||
|
||||
@@ -748,6 +748,8 @@ typedef struct zpool_load_policy {
|
||||
#define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift"
|
||||
#define ZPOOL_CONFIG_ASHIFT "ashift"
|
||||
#define ZPOOL_CONFIG_ASIZE "asize"
|
||||
#define ZPOOL_CONFIG_MIN_ALLOC "min_alloc"
|
||||
#define ZPOOL_CONFIG_MAX_ALLOC "max_alloc"
|
||||
#define ZPOOL_CONFIG_DTL "DTL"
|
||||
#define ZPOOL_CONFIG_SCAN_STATS "scan_stats" /* not stored on disk */
|
||||
#define ZPOOL_CONFIG_REMOVAL_STATS "removal_stats" /* not stored on disk */
|
||||
|
||||
@@ -238,8 +238,7 @@ zfs_rs_set_end_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t end)
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfs_zfs_rs_set_fill_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt,
|
||||
uint64_t fill)
|
||||
zfs_rs_set_fill_raw(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t fill)
|
||||
{
|
||||
ASSERT3U(rt->rt_type, <=, ZFS_RANGE_SEG_NUM_TYPES);
|
||||
switch (rt->rt_type) {
|
||||
@@ -277,7 +276,7 @@ static inline void
|
||||
zfs_rs_set_fill(zfs_range_seg_t *rs, zfs_range_tree_t *rt, uint64_t fill)
|
||||
{
|
||||
ASSERT(IS_P2ALIGNED(fill, 1ULL << rt->rt_shift));
|
||||
zfs_zfs_rs_set_fill_raw(rs, rt, fill >> rt->rt_shift);
|
||||
zfs_rs_set_fill_raw(rs, rt, fill >> rt->rt_shift);
|
||||
}
|
||||
|
||||
typedef void zfs_range_tree_func_t(void *arg, uint64_t start, uint64_t size);
|
||||
|
||||
@@ -1030,7 +1030,7 @@ extern void spa_import_progress_set_notes_nolog(spa_t *spa,
|
||||
extern int spa_config_tryenter(spa_t *spa, int locks, const void *tag,
|
||||
krw_t rw);
|
||||
extern void spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw);
|
||||
extern void spa_config_enter_mmp(spa_t *spa, int locks, const void *tag,
|
||||
extern void spa_config_enter_priority(spa_t *spa, int locks, const void *tag,
|
||||
krw_t rw);
|
||||
extern void spa_config_exit(spa_t *spa, int locks, const void *tag);
|
||||
extern int spa_config_held(spa_t *spa, int locks, krw_t rw);
|
||||
@@ -1084,6 +1084,7 @@ extern pool_state_t spa_state(spa_t *spa);
|
||||
extern spa_load_state_t spa_load_state(spa_t *spa);
|
||||
extern uint64_t spa_freeze_txg(spa_t *spa);
|
||||
extern uint64_t spa_get_worst_case_asize(spa_t *spa, uint64_t lsize);
|
||||
extern void spa_get_min_alloc_range(spa_t *spa, uint64_t *min, uint64_t *max);
|
||||
extern uint64_t spa_get_dspace(spa_t *spa);
|
||||
extern uint64_t spa_get_checkpoint_space(spa_t *spa);
|
||||
extern uint64_t spa_get_slop_space(spa_t *spa);
|
||||
|
||||
@@ -265,6 +265,7 @@ struct spa {
|
||||
uint64_t spa_min_ashift; /* of vdevs in normal class */
|
||||
uint64_t spa_max_ashift; /* of vdevs in normal class */
|
||||
uint64_t spa_min_alloc; /* of vdevs in normal class */
|
||||
uint64_t spa_max_alloc; /* of vdevs in normal class */
|
||||
uint64_t spa_gcd_alloc; /* of vdevs in normal class */
|
||||
uint64_t spa_config_guid; /* config pool guid */
|
||||
uint64_t spa_load_guid; /* spa_load initialized guid */
|
||||
|
||||
@@ -455,6 +455,7 @@ typedef enum zinject_type {
|
||||
ZINJECT_DECRYPT_FAULT,
|
||||
ZINJECT_DELAY_IMPORT,
|
||||
ZINJECT_DELAY_EXPORT,
|
||||
ZINJECT_DELAY_READY,
|
||||
} zinject_type_t;
|
||||
|
||||
typedef enum zinject_iotype {
|
||||
|
||||
@@ -718,6 +718,7 @@ extern void zio_handle_ignored_writes(zio_t *zio);
|
||||
extern hrtime_t zio_handle_io_delay(zio_t *zio);
|
||||
extern void zio_handle_import_delay(spa_t *spa, hrtime_t elapsed);
|
||||
extern void zio_handle_export_delay(spa_t *spa, hrtime_t elapsed);
|
||||
extern hrtime_t zio_handle_ready_delay(zio_t *zio);
|
||||
|
||||
/*
|
||||
* Checksum ereport functions
|
||||
|
||||
@@ -616,6 +616,7 @@
|
||||
<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>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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>
|
||||
@@ -1020,13 +1021,6 @@
|
||||
<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>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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'/>
|
||||
@@ -1061,93 +1055,6 @@
|
||||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' 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'/>
|
||||
@@ -1237,8 +1144,6 @@
|
||||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<pointer-type-def type-id='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
@@ -1254,14 +1159,6 @@
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
|
||||
@@ -571,6 +571,7 @@
|
||||
<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'/>
|
||||
@@ -641,7 +642,7 @@
|
||||
<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='528' 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'/>
|
||||
@@ -1458,103 +1459,8 @@
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<pointer-type-def type-id='56fe4a37' size-in-bits='64' id='b6b61d2f'/>
|
||||
<qualified-type-def type-id='b6b61d2f' restrict='yes' id='3cad23cd'/>
|
||||
<pointer-type-def type-id='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
@@ -1566,14 +1472,6 @@
|
||||
<parameter type-id='822cd80b'/>
|
||||
<return type-id='95e97e5e'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<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'/>
|
||||
@@ -3194,6 +3092,10 @@
|
||||
<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'/>
|
||||
@@ -3238,6 +3140,11 @@
|
||||
<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'/>
|
||||
@@ -9398,10 +9305,6 @@
|
||||
<parameter type-id='5ce45b60'/>
|
||||
<return type-id='48b5725f'/>
|
||||
</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='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>
|
||||
@@ -9774,8 +9677,8 @@
|
||||
</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='4224' id='55e705e7'>
|
||||
<subrange length='33' type-id='7359adad' id='6a5934df'/>
|
||||
<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'/>
|
||||
@@ -9805,30 +9708,31 @@
|
||||
<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_RECEIVE' value='8'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_ALLOW' value='9'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_USERPROP' value='10'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_MOUNT' value='11'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_SHARE' value='12'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_USERQUOTA' value='13'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_GROUPQUOTA' value='14'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_USERUSED' value='15'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_GROUPUSED' value='16'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_USEROBJQUOTA' value='17'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_GROUPOBJQUOTA' value='18'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_USEROBJUSED' value='19'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_GROUPOBJUSED' value='20'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_HOLD' value='21'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_RELEASE' value='22'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_DIFF' value='23'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_BOOKMARK' value='24'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_LOAD_KEY' value='25'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_CHANGE_KEY' value='26'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_PROJECTUSED' value='27'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_PROJECTQUOTA' value='28'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_PROJECTOBJUSED' value='29'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_PROJECTOBJQUOTA' value='30'/>
|
||||
<enumerator name='ZFS_DELEG_NOTE_NONE' value='31'/>
|
||||
<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'>
|
||||
|
||||
@@ -307,6 +307,23 @@ zpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing)
|
||||
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:
|
||||
|
||||
@@ -617,6 +617,7 @@
|
||||
<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>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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>
|
||||
@@ -988,13 +989,6 @@
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
<abi-instr address-size='64' path='lib/libspl/os/linux/getmntany.c' language='LANG_C99'>
|
||||
<array-type-def dimensions='1' type-id='d315442e' size-in-bits='16' id='811205dc'>
|
||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||
</array-type-def>
|
||||
<array-type-def dimensions='1' type-id='d3130597' size-in-bits='768' id='f63f23b9'>
|
||||
<subrange length='12' type-id='7359adad' id='84827bdc'/>
|
||||
</array-type-def>
|
||||
<type-decl name='long long int' size-in-bits='64' id='1eb56b1e'/>
|
||||
<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'/>
|
||||
@@ -1029,93 +1023,6 @@
|
||||
<var-decl name='mnt_minor' type-id='3502e3ff' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<typedef-decl name='__u16' type-id='8efea9e5' id='d315442e'/>
|
||||
<typedef-decl name='__s32' type-id='95e97e5e' id='3158a266'/>
|
||||
<typedef-decl name='__u32' type-id='f0981eeb' id='3f1a6b60'/>
|
||||
<typedef-decl name='__s64' type-id='1eb56b1e' id='49659421'/>
|
||||
<typedef-decl name='__u64' type-id='3a47d82b' id='d3130597'/>
|
||||
<class-decl name='statx_timestamp' size-in-bits='128' is-struct='yes' visibility='default' id='94101016'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='tv_sec' type-id='49659421' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='tv_nsec' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='96'>
|
||||
<var-decl name='__reserved' type-id='3158a266' visibility='default'/>
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<class-decl name='statx' size-in-bits='2048' is-struct='yes' visibility='default' id='720b04c5'>
|
||||
<data-member access='public' layout-offset-in-bits='0'>
|
||||
<var-decl name='stx_mask' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='32'>
|
||||
<var-decl name='stx_blksize' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='64'>
|
||||
<var-decl name='stx_attributes' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='128'>
|
||||
<var-decl name='stx_nlink' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='160'>
|
||||
<var-decl name='stx_uid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='192'>
|
||||
<var-decl name='stx_gid' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='224'>
|
||||
<var-decl name='stx_mode' type-id='d315442e' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='240'>
|
||||
<var-decl name='__spare0' type-id='811205dc' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='256'>
|
||||
<var-decl name='stx_ino' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='320'>
|
||||
<var-decl name='stx_size' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='384'>
|
||||
<var-decl name='stx_blocks' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='448'>
|
||||
<var-decl name='stx_attributes_mask' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='512'>
|
||||
<var-decl name='stx_atime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='640'>
|
||||
<var-decl name='stx_btime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='768'>
|
||||
<var-decl name='stx_ctime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='896'>
|
||||
<var-decl name='stx_mtime' type-id='94101016' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1024'>
|
||||
<var-decl name='stx_rdev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1056'>
|
||||
<var-decl name='stx_rdev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1088'>
|
||||
<var-decl name='stx_dev_major' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1120'>
|
||||
<var-decl name='stx_dev_minor' type-id='3f1a6b60' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1152'>
|
||||
<var-decl name='stx_mnt_id' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1216'>
|
||||
<var-decl name='__spare2' type-id='d3130597' visibility='default'/>
|
||||
</data-member>
|
||||
<data-member access='public' layout-offset-in-bits='1280'>
|
||||
<var-decl name='__spare3' type-id='f63f23b9' 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'/>
|
||||
@@ -1191,8 +1098,6 @@
|
||||
<pointer-type-def type-id='1b055409' size-in-bits='64' id='9d424d31'/>
|
||||
<pointer-type-def type-id='0bbec9cd' size-in-bits='64' id='62f7a03d'/>
|
||||
<qualified-type-def type-id='62f7a03d' restrict='yes' id='f1cadedf'/>
|
||||
<pointer-type-def type-id='720b04c5' size-in-bits='64' id='936b8e35'/>
|
||||
<qualified-type-def type-id='936b8e35' restrict='yes' id='31d265b7'/>
|
||||
<function-decl name='getmntent_r' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='e75a27e9'/>
|
||||
<parameter type-id='3cad23cd'/>
|
||||
@@ -1208,14 +1113,6 @@
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<return type-id='26a90f95'/>
|
||||
</function-decl>
|
||||
<function-decl name='statx' visibility='default' binding='global' size-in-bits='64'>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='9d26089a'/>
|
||||
<parameter type-id='95e97e5e'/>
|
||||
<parameter type-id='f0981eeb'/>
|
||||
<parameter type-id='31d265b7'/>
|
||||
<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'/>
|
||||
|
||||
@@ -138,6 +138,20 @@ This injector is automatically cleared after the import is finished.
|
||||
.
|
||||
.It Xo
|
||||
.Nm zinject
|
||||
.Fl E Ar delay
|
||||
.Op Fl a
|
||||
.Op Fl m
|
||||
.Op Fl f Ar freq
|
||||
.Op Fl l Ar level
|
||||
.Op Fl r Ar range
|
||||
.Op Fl T Ar iotype
|
||||
.Op Fl t Ar type Ns | Ns Fl b Ar bookmark
|
||||
.Xc
|
||||
Inject pipeline ready stage delays for the given object or bookmark.
|
||||
The delay is specified in milliseconds.
|
||||
.
|
||||
.It Xo
|
||||
.Nm zinject
|
||||
.Fl I
|
||||
.Op Fl s Ar seconds Ns | Ns Fl g Ar txgs
|
||||
.Ar pool
|
||||
|
||||
@@ -65,10 +65,10 @@ property).
|
||||
.Cm upgrade
|
||||
.Fl v
|
||||
.Xc
|
||||
Displays legacy ZFS versions supported by the this version of ZFS.
|
||||
Displays legacy ZFS versions supported by this version of ZFS.
|
||||
See
|
||||
.Xr zpool-features 7
|
||||
for a description of feature flags features supported by this version of ZFS.
|
||||
for a description of features supported by this version of ZFS.
|
||||
.It Xo
|
||||
.Nm zpool
|
||||
.Cm upgrade
|
||||
|
||||
@@ -484,7 +484,28 @@ zvol_request_impl(zvol_state_t *zv, struct bio *bio, struct request *rq,
|
||||
fstrans_cookie_t cookie = spl_fstrans_mark();
|
||||
uint64_t offset = io_offset(bio, rq);
|
||||
uint64_t size = io_size(bio, rq);
|
||||
int rw = io_data_dir(bio, rq);
|
||||
int rw;
|
||||
|
||||
if (rq != NULL) {
|
||||
/*
|
||||
* Flush & trim requests go down the zvol_write codepath. Or
|
||||
* more specifically:
|
||||
*
|
||||
* If request is a write, or if it's op_is_sync() and not a
|
||||
* read, or if it's a flush, or if it's a discard, then send the
|
||||
* request down the write path.
|
||||
*/
|
||||
if (op_is_write(rq->cmd_flags) ||
|
||||
(op_is_sync(rq->cmd_flags) && req_op(rq) != REQ_OP_READ) ||
|
||||
req_op(rq) == REQ_OP_FLUSH ||
|
||||
op_is_discard(rq->cmd_flags)) {
|
||||
rw = WRITE;
|
||||
} else {
|
||||
rw = READ;
|
||||
}
|
||||
} else {
|
||||
rw = bio_data_dir(bio);
|
||||
}
|
||||
|
||||
if (unlikely(zv->zv_flags & ZVOL_REMOVING)) {
|
||||
zvol_end_io(bio, rq, SET_ERROR(ENXIO));
|
||||
|
||||
@@ -364,8 +364,8 @@ zfs_prop_init(void)
|
||||
|
||||
static const zprop_index_t xattr_table[] = {
|
||||
{ "off", ZFS_XATTR_OFF },
|
||||
{ "on", ZFS_XATTR_SA },
|
||||
{ "sa", ZFS_XATTR_SA },
|
||||
{ "on", ZFS_XATTR_SA },
|
||||
{ "dir", ZFS_XATTR_DIR },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -2655,6 +2655,32 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust *offset to the next (or previous) block byte offset at lvl.
|
||||
* Returns FALSE if *offset would overflow or underflow.
|
||||
*/
|
||||
static boolean_t
|
||||
dnode_next_block(dnode_t *dn, int flags, uint64_t *offset, int lvl)
|
||||
{
|
||||
int epbs = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
|
||||
int span = lvl * epbs + dn->dn_datablkshift;
|
||||
uint64_t blkid, maxblkid;
|
||||
|
||||
if (span >= 8 * sizeof (uint64_t))
|
||||
return (B_FALSE);
|
||||
|
||||
blkid = *offset >> span;
|
||||
maxblkid = 1ULL << (8 * sizeof (*offset) - span);
|
||||
if (!(flags & DNODE_FIND_BACKWARDS) && blkid + 1 < maxblkid)
|
||||
*offset = (blkid + 1) << span;
|
||||
else if ((flags & DNODE_FIND_BACKWARDS) && blkid > 0)
|
||||
*offset = (blkid << span) - 1;
|
||||
else
|
||||
return (B_FALSE);
|
||||
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the next hole, data, or sparse region at or after *offset.
|
||||
* The value 'blkfill' tells us how many items we expect to find
|
||||
@@ -2682,7 +2708,7 @@ int
|
||||
dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
|
||||
int minlvl, uint64_t blkfill, uint64_t txg)
|
||||
{
|
||||
uint64_t initial_offset = *offset;
|
||||
uint64_t matched = *offset;
|
||||
int lvl, maxlvl;
|
||||
int error = 0;
|
||||
|
||||
@@ -2706,16 +2732,36 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
|
||||
|
||||
maxlvl = dn->dn_phys->dn_nlevels;
|
||||
|
||||
for (lvl = minlvl; lvl <= maxlvl; lvl++) {
|
||||
for (lvl = minlvl; lvl <= maxlvl; ) {
|
||||
error = dnode_next_offset_level(dn,
|
||||
flags, offset, lvl, blkfill, txg);
|
||||
if (error != ESRCH)
|
||||
if (error == 0 && lvl > minlvl) {
|
||||
--lvl;
|
||||
matched = *offset;
|
||||
} else if (error == ESRCH && lvl < maxlvl &&
|
||||
dnode_next_block(dn, flags, &matched, lvl)) {
|
||||
/*
|
||||
* Continue search at next/prev offset in lvl+1 block.
|
||||
*
|
||||
* Usually we only search upwards at the start of the
|
||||
* search as higher level blocks point at a matching
|
||||
* minlvl block in most cases, but we backtrack if not.
|
||||
*
|
||||
* This can happen for txg > 0 searches if the block
|
||||
* contains only BPs/dnodes freed at that txg. It also
|
||||
* happens if we are still syncing out the tree, and
|
||||
* some BP's at higher levels are not updated yet.
|
||||
*
|
||||
* We must adjust offset to avoid coming back to the
|
||||
* same offset and getting stuck looping forever. This
|
||||
* also deals with the case where offset is already at
|
||||
* the beginning or end of the object.
|
||||
*/
|
||||
++lvl;
|
||||
*offset = matched;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
while (error == 0 && --lvl >= minlvl) {
|
||||
error = dnode_next_offset_level(dn,
|
||||
flags, offset, lvl, blkfill, txg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2727,9 +2773,6 @@ dnode_next_offset(dnode_t *dn, int flags, uint64_t *offset,
|
||||
error = 0;
|
||||
}
|
||||
|
||||
if (error == 0 && (flags & DNODE_FIND_BACKWARDS ?
|
||||
initial_offset < *offset : initial_offset > *offset))
|
||||
error = SET_ERROR(ESRCH);
|
||||
out:
|
||||
if (!(flags & DNODE_FIND_HAVELOCK))
|
||||
rw_exit(&dn->dn_struct_rwlock);
|
||||
|
||||
@@ -446,7 +446,7 @@ mmp_write_uberblock(spa_t *spa)
|
||||
uint64_t offset;
|
||||
|
||||
hrtime_t lock_acquire_time = gethrtime();
|
||||
spa_config_enter_mmp(spa, SCL_STATE, mmp_tag, RW_READER);
|
||||
spa_config_enter_priority(spa, SCL_STATE, mmp_tag, RW_READER);
|
||||
lock_acquire_time = gethrtime() - lock_acquire_time;
|
||||
if (lock_acquire_time > (MSEC2NSEC(MMP_MIN_INTERVAL) / 10))
|
||||
zfs_dbgmsg("MMP SCL_STATE acquisition pool '%s' took %llu ns "
|
||||
|
||||
@@ -585,7 +585,7 @@ zfs_range_tree_remove_impl(zfs_range_tree_t *rt, uint64_t start, uint64_t size,
|
||||
* the size, since we do not support removing partial segments
|
||||
* of range trees with gaps.
|
||||
*/
|
||||
zfs_zfs_rs_set_fill_raw(rs, rt, zfs_rs_get_end_raw(rs, rt) -
|
||||
zfs_rs_set_fill_raw(rs, rt, zfs_rs_get_end_raw(rs, rt) -
|
||||
zfs_rs_get_start_raw(rs, rt));
|
||||
zfs_range_tree_stat_incr(rt, &rs_tmp);
|
||||
|
||||
|
||||
@@ -372,6 +372,8 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
|
||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg);
|
||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa));
|
||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_ERRATA, spa->spa_errata);
|
||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_MIN_ALLOC, spa->spa_min_alloc);
|
||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_MAX_ALLOC, spa->spa_max_alloc);
|
||||
if (spa->spa_comment != NULL)
|
||||
fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT,
|
||||
spa->spa_comment);
|
||||
|
||||
@@ -510,7 +510,7 @@ spa_config_tryenter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||
|
||||
static void
|
||||
spa_config_enter_impl(spa_t *spa, int locks, const void *tag, krw_t rw,
|
||||
int mmp_flag)
|
||||
int priority_flag)
|
||||
{
|
||||
(void) tag;
|
||||
int wlocks_held = 0;
|
||||
@@ -526,7 +526,7 @@ spa_config_enter_impl(spa_t *spa, int locks, const void *tag, krw_t rw,
|
||||
mutex_enter(&scl->scl_lock);
|
||||
if (rw == RW_READER) {
|
||||
while (scl->scl_writer ||
|
||||
(!mmp_flag && scl->scl_write_wanted)) {
|
||||
(!priority_flag && scl->scl_write_wanted)) {
|
||||
cv_wait(&scl->scl_cv, &scl->scl_lock);
|
||||
}
|
||||
} else {
|
||||
@@ -551,7 +551,7 @@ spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||
}
|
||||
|
||||
/*
|
||||
* The spa_config_enter_mmp() allows the mmp thread to cut in front of
|
||||
* The spa_config_enter_priority() allows the mmp thread to cut in front of
|
||||
* outstanding write lock requests. This is needed since the mmp updates are
|
||||
* time sensitive and failure to service them promptly will result in a
|
||||
* suspended pool. This pool suspension has been seen in practice when there is
|
||||
@@ -560,7 +560,7 @@ spa_config_enter(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||
*/
|
||||
|
||||
void
|
||||
spa_config_enter_mmp(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||
spa_config_enter_priority(spa_t *spa, int locks, const void *tag, krw_t rw)
|
||||
{
|
||||
spa_config_enter_impl(spa, locks, tag, rw, 1);
|
||||
}
|
||||
@@ -806,6 +806,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
|
||||
spa->spa_min_ashift = INT_MAX;
|
||||
spa->spa_max_ashift = 0;
|
||||
spa->spa_min_alloc = INT_MAX;
|
||||
spa->spa_max_alloc = 0;
|
||||
spa->spa_gcd_alloc = INT_MAX;
|
||||
|
||||
/* Reset cached value */
|
||||
@@ -1864,6 +1865,19 @@ spa_get_worst_case_asize(spa_t *spa, uint64_t lsize)
|
||||
return (MAX(lsize, 1 << spa->spa_max_ashift) * spa_asize_inflation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the range of minimum allocation sizes for the normal allocation
|
||||
* class. This can be used by external consumers of the DMU to estimate
|
||||
* potential wasted capacity when setting the recordsize for an object.
|
||||
* This is mainly for dRAID pools which always pad to a full stripe width.
|
||||
*/
|
||||
void
|
||||
spa_get_min_alloc_range(spa_t *spa, uint64_t *min_alloc, uint64_t *max_alloc)
|
||||
{
|
||||
*min_alloc = spa->spa_min_alloc;
|
||||
*max_alloc = spa->spa_max_alloc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the amount of slop space in bytes. It is typically 1/32 of the pool
|
||||
* (3.2%), minus the embedded log space. On very small pools, it may be
|
||||
@@ -3085,6 +3099,7 @@ EXPORT_SYMBOL(spa_version);
|
||||
EXPORT_SYMBOL(spa_state);
|
||||
EXPORT_SYMBOL(spa_load_state);
|
||||
EXPORT_SYMBOL(spa_freeze_txg);
|
||||
EXPORT_SYMBOL(spa_get_min_alloc_range); /* for Lustre */
|
||||
EXPORT_SYMBOL(spa_get_dspace);
|
||||
EXPORT_SYMBOL(spa_update_dspace);
|
||||
EXPORT_SYMBOL(spa_deflate);
|
||||
|
||||
@@ -1497,12 +1497,14 @@ vdev_spa_set_alloc(spa_t *spa, uint64_t min_alloc)
|
||||
{
|
||||
if (min_alloc < spa->spa_min_alloc)
|
||||
spa->spa_min_alloc = min_alloc;
|
||||
if (spa->spa_gcd_alloc == INT_MAX) {
|
||||
|
||||
if (min_alloc > spa->spa_max_alloc)
|
||||
spa->spa_max_alloc = min_alloc;
|
||||
|
||||
if (spa->spa_gcd_alloc == INT_MAX)
|
||||
spa->spa_gcd_alloc = min_alloc;
|
||||
} else {
|
||||
spa->spa_gcd_alloc = vdev_gcd(min_alloc,
|
||||
spa->spa_gcd_alloc);
|
||||
}
|
||||
else
|
||||
spa->spa_gcd_alloc = vdev_gcd(min_alloc, spa->spa_gcd_alloc);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1560,8 +1562,7 @@ vdev_metaslab_group_create(vdev_t *vd)
|
||||
if (vd->vdev_ashift < spa->spa_min_ashift)
|
||||
spa->spa_min_ashift = vd->vdev_ashift;
|
||||
|
||||
uint64_t min_alloc = vdev_get_min_alloc(vd);
|
||||
vdev_spa_set_alloc(spa, min_alloc);
|
||||
vdev_spa_set_alloc(spa, vdev_get_min_alloc(vd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,6 +511,8 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
|
||||
fnvlist_add_uint64(nv, ZPOOL_CONFIG_ASHIFT, vd->vdev_ashift);
|
||||
fnvlist_add_uint64(nv, ZPOOL_CONFIG_ASIZE,
|
||||
vd->vdev_asize);
|
||||
fnvlist_add_uint64(nv, ZPOOL_CONFIG_MIN_ALLOC,
|
||||
vdev_get_min_alloc(vd));
|
||||
fnvlist_add_uint64(nv, ZPOOL_CONFIG_IS_LOG, vd->vdev_islog);
|
||||
if (vd->vdev_noalloc) {
|
||||
fnvlist_add_uint64(nv, ZPOOL_CONFIG_NONALLOCATING,
|
||||
|
||||
@@ -4574,8 +4574,29 @@ zio_vdev_io_start(zio_t *zio)
|
||||
ASSERT0(zio->io_child_error[ZIO_CHILD_VDEV]);
|
||||
|
||||
if (vd == NULL) {
|
||||
if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER))
|
||||
spa_config_enter(spa, SCL_ZIO, zio, RW_READER);
|
||||
if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER)) {
|
||||
/*
|
||||
* A deadlock workaround. The ddt_prune_unique_entries()
|
||||
* -> prune_candidates_sync() code path takes the
|
||||
* SCL_ZIO reader lock and may request it again here.
|
||||
* If there is another thread who wants the SCL_ZIO
|
||||
* writer lock, then scl_write_wanted will be set.
|
||||
* Thus, the spa_config_enter_priority() is used to
|
||||
* ignore pending writer requests.
|
||||
*
|
||||
* The locking should be revised to remove the need
|
||||
* for this workaround. If that's not workable then
|
||||
* it should only be applied to the zios involved in
|
||||
* the pruning process. This impacts the read/write
|
||||
* I/O balance while pruning.
|
||||
*/
|
||||
if (spa->spa_active_ddt_prune)
|
||||
spa_config_enter_priority(spa, SCL_ZIO, zio,
|
||||
RW_READER);
|
||||
else
|
||||
spa_config_enter(spa, SCL_ZIO, zio,
|
||||
RW_READER);
|
||||
}
|
||||
|
||||
/*
|
||||
* The mirror_ops handle multiple DVAs in a single BP.
|
||||
@@ -5305,6 +5326,16 @@ zio_ready(zio_t *zio)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (zio_injection_enabled) {
|
||||
hrtime_t target = zio_handle_ready_delay(zio);
|
||||
if (target != 0 && zio->io_target_timestamp == 0) {
|
||||
zio->io_stage >>= 1;
|
||||
zio->io_target_timestamp = target;
|
||||
zio_delay_interrupt(zio);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (zio->io_ready) {
|
||||
ASSERT(IO_IS_ALLOCATING(zio));
|
||||
ASSERT(BP_GET_BIRTH(bp) == zio->io_txg ||
|
||||
|
||||
@@ -827,6 +827,44 @@ zio_handle_export_delay(spa_t *spa, hrtime_t elapsed)
|
||||
zio_handle_pool_delay(spa, elapsed, ZINJECT_DELAY_EXPORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* For testing, inject a delay before ready state.
|
||||
*/
|
||||
hrtime_t
|
||||
zio_handle_ready_delay(zio_t *zio)
|
||||
{
|
||||
inject_handler_t *handler;
|
||||
hrtime_t now = gethrtime();
|
||||
hrtime_t target = 0;
|
||||
|
||||
/*
|
||||
* Ignore I/O not associated with any logical data.
|
||||
*/
|
||||
if (zio->io_logical == NULL)
|
||||
return (0);
|
||||
|
||||
rw_enter(&inject_lock, RW_READER);
|
||||
|
||||
for (handler = list_head(&inject_handlers); handler != NULL;
|
||||
handler = list_next(&inject_handlers, handler)) {
|
||||
if (zio->io_spa != handler->zi_spa ||
|
||||
handler->zi_record.zi_cmd != ZINJECT_DELAY_READY)
|
||||
continue;
|
||||
|
||||
/* If this handler matches, inject the delay */
|
||||
if (zio_match_iotype(zio, handler->zi_record.zi_iotype) &&
|
||||
zio_match_handler(&zio->io_logical->io_bookmark,
|
||||
zio->io_bp ? BP_GET_TYPE(zio->io_bp) : DMU_OT_NONE,
|
||||
zio_match_dva(zio), &handler->zi_record, zio->io_error)) {
|
||||
target = now + (hrtime_t)handler->zi_record.zi_timer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rw_exit(&inject_lock);
|
||||
return (target);
|
||||
}
|
||||
|
||||
static int
|
||||
zio_calculate_range(const char *pool, zinject_record_t *record)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ DEBUG=""
|
||||
CLEANUP="yes"
|
||||
CLEANUPALL="no"
|
||||
KMSG=""
|
||||
TIMEOUT_DEBUG=""
|
||||
LOOPBACK="yes"
|
||||
STACK_TRACER="no"
|
||||
FILESIZE="4G"
|
||||
@@ -364,6 +365,7 @@ OPTIONS:
|
||||
-k Disable cleanup after test failure
|
||||
-K Log test names to /dev/kmsg
|
||||
-f Use files only, disables block device tests
|
||||
-O Dump debugging info to /dev/kmsg on test timeout
|
||||
-S Enable stack tracer (negative performance impact)
|
||||
-c Only create and populate constrained path
|
||||
-R Automatically rerun failing tests
|
||||
@@ -402,7 +404,7 @@ $0 -x
|
||||
EOF
|
||||
}
|
||||
|
||||
while getopts 'hvqxkKfScRmn:d:Ds:r:?t:T:u:I:' OPTION; do
|
||||
while getopts 'hvqxkKfScRmOn:d:Ds:r:?t:T:u:I:' OPTION; do
|
||||
case $OPTION in
|
||||
h)
|
||||
usage
|
||||
@@ -445,6 +447,9 @@ while getopts 'hvqxkKfScRmn:d:Ds:r:?t:T:u:I:' OPTION; do
|
||||
export NFS=1
|
||||
. "$nfsfile"
|
||||
;;
|
||||
O)
|
||||
TIMEOUT_DEBUG="yes"
|
||||
;;
|
||||
d)
|
||||
FILEDIR="$OPTARG"
|
||||
;;
|
||||
@@ -773,6 +778,7 @@ msg "${TEST_RUNNER}" \
|
||||
"${DEBUG:+-D}" \
|
||||
"${KMEMLEAK:+-m}" \
|
||||
"${KMSG:+-K}" \
|
||||
"${TIMEOUT_DEBUG:+-O}" \
|
||||
"-c \"${RUNFILES}\"" \
|
||||
"-T \"${TAGS}\"" \
|
||||
"-i \"${STF_SUITE}\"" \
|
||||
@@ -783,6 +789,7 @@ msg "${TEST_RUNNER}" \
|
||||
${DEBUG:+-D} \
|
||||
${KMEMLEAK:+-m} \
|
||||
${KMSG:+-K} \
|
||||
${TIMEOUT_DEBUG:+-O} \
|
||||
-c "${RUNFILES}" \
|
||||
-T "${TAGS}" \
|
||||
-i "${STF_SUITE}" \
|
||||
|
||||
@@ -168,10 +168,10 @@ tags = ['functional', 'cli_root', 'zinject']
|
||||
tests = ['zdb_002_pos', 'zdb_003_pos', 'zdb_004_pos', 'zdb_005_pos',
|
||||
'zdb_006_pos', 'zdb_args_neg', 'zdb_args_pos',
|
||||
'zdb_block_size_histogram', 'zdb_checksum', 'zdb_decompress',
|
||||
'zdb_display_block', 'zdb_encrypted', 'zdb_label_checksum',
|
||||
'zdb_object_range_neg', 'zdb_object_range_pos', 'zdb_objset_id',
|
||||
'zdb_decompress_zstd', 'zdb_recover', 'zdb_recover_2', 'zdb_backup',
|
||||
'zdb_tunables']
|
||||
'zdb_display_block', 'zdb_encrypted', 'zdb_encrypted_raw',
|
||||
'zdb_label_checksum', 'zdb_object_range_neg', 'zdb_object_range_pos',
|
||||
'zdb_objset_id', 'zdb_decompress_zstd', 'zdb_recover', 'zdb_recover_2',
|
||||
'zdb_backup', 'zdb_tunables']
|
||||
pre =
|
||||
post =
|
||||
tags = ['functional', 'cli_root', 'zdb']
|
||||
@@ -395,8 +395,9 @@ tags = ['functional', 'cli_root', 'zpool']
|
||||
[tests/functional/cli_root/zpool_add]
|
||||
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', 'zpool_add_dryrun_output']
|
||||
'zpool_add_008_neg', 'zpool_add_009_neg', 'zpool_add_warn_create',
|
||||
'zpool_add_warn_degraded', 'zpool_add_warn_removal', 'add-o_ashift',
|
||||
'add_prop_ashift', 'zpool_add_dryrun_output']
|
||||
tags = ['functional', 'cli_root', 'zpool_add']
|
||||
|
||||
[tests/functional/cli_root/zpool_attach]
|
||||
@@ -490,6 +491,10 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
|
||||
tags = ['functional', 'cli_root', 'zpool_import']
|
||||
timeout = 1200
|
||||
|
||||
[tests/functional/cli_root/zpool_iostat]
|
||||
tests = ['zpool_iostat_interval_all', 'zpool_iostat_interval_some']
|
||||
tags = ['functional', 'cli_root', 'zpool_iostat']
|
||||
|
||||
[tests/functional/cli_root/zpool_labelclear]
|
||||
tests = ['zpool_labelclear_active', 'zpool_labelclear_exported',
|
||||
'zpool_labelclear_removed', 'zpool_labelclear_valid']
|
||||
@@ -1085,7 +1090,8 @@ tags = ['functional', 'write_dirs']
|
||||
[tests/functional/xattr]
|
||||
tests = ['xattr_001_pos', 'xattr_002_neg', 'xattr_003_neg', 'xattr_004_pos',
|
||||
'xattr_005_pos', 'xattr_006_pos', 'xattr_007_neg',
|
||||
'xattr_011_pos', 'xattr_012_pos', 'xattr_013_pos', 'xattr_compat']
|
||||
'xattr_011_pos', 'xattr_012_pos', 'xattr_013_pos', 'xattr_014_pos',
|
||||
'xattr_compat']
|
||||
tags = ['functional', 'xattr']
|
||||
|
||||
[tests/functional/zvol/zvol_ENOSPC]
|
||||
|
||||
@@ -622,7 +622,7 @@ tags = ['functional', 'vdev_zaps']
|
||||
[tests/functional/xattr]
|
||||
tests = ['xattr_001_pos', 'xattr_002_neg', 'xattr_003_neg', 'xattr_004_pos',
|
||||
'xattr_005_pos', 'xattr_006_pos', 'xattr_007_neg',
|
||||
'xattr_011_pos', 'xattr_013_pos', 'xattr_compat']
|
||||
'xattr_011_pos', 'xattr_013_pos', 'xattr_014_pos', 'xattr_compat']
|
||||
tags = ['functional', 'xattr']
|
||||
|
||||
[tests/functional/zvol/zvol_ENOSPC]
|
||||
|
||||
@@ -34,6 +34,7 @@ from select import select
|
||||
from subprocess import PIPE
|
||||
from subprocess import Popen
|
||||
from subprocess import check_output
|
||||
from subprocess import run
|
||||
from threading import Timer
|
||||
from time import time, CLOCK_MONOTONIC
|
||||
from os.path import exists
|
||||
@@ -187,6 +188,63 @@ User: %s
|
||||
''' % (self.pathname, self.identifier, self.outputdir, self.timeout, self.user)
|
||||
|
||||
def kill_cmd(self, proc, options, kmemleak, keyboard_interrupt=False):
|
||||
|
||||
"""
|
||||
We're about to kill a command due to a timeout.
|
||||
If we're running with the -O option, then dump debug info about the
|
||||
process with the highest CPU usage to /dev/kmsg (Linux only). This can
|
||||
help debug the timeout.
|
||||
|
||||
Debug info includes:
|
||||
- 30 lines from 'top'
|
||||
- /proc/<PID>/stack output of process with highest CPU usage
|
||||
- Last lines strace-ing process with highest CPU usage
|
||||
"""
|
||||
if exists("/dev/kmsg"):
|
||||
c = """
|
||||
TOP_OUT="$(COLUMNS=160 top -b -n 1 | head -n 30)"
|
||||
read -r PID CMD <<< $(echo "$TOP_OUT" | /usr/bin/awk \
|
||||
"/COMMAND/{
|
||||
print_next=1
|
||||
next
|
||||
}
|
||||
{
|
||||
if (print_next == 1) {
|
||||
print \\$1\\" \\"\\$12
|
||||
exit
|
||||
}
|
||||
}")
|
||||
echo "##### ZTS timeout debug #####"
|
||||
echo "----- top -----"
|
||||
echo "$TOP_OUT"
|
||||
echo "----- /proc/$PID/stack ($CMD)) -----"
|
||||
cat /proc/$PID/stack
|
||||
echo "----- strace ($CMD) -----"
|
||||
TMPFILE="$(mktemp --suffix=ZTS)"
|
||||
/usr/bin/strace -k --stack-traces -p $PID &> "$TMPFILE" &
|
||||
sleep 0.1
|
||||
killall strace
|
||||
tail -n 30 $TMPFILE
|
||||
rm "$TMPFILE"
|
||||
echo "##### /proc/sysrq-trigger stack #####"
|
||||
"""
|
||||
c = "sudo bash -c '" + c + "'"
|
||||
data = run(c, capture_output=True, shell=True, text=True)
|
||||
out = data.stdout
|
||||
try:
|
||||
kp = Popen([SUDO, "sh", "-c",
|
||||
"echo '" + out + "' > /dev/kmsg"])
|
||||
kp.wait()
|
||||
|
||||
"""
|
||||
Trigger kernel stack traces
|
||||
"""
|
||||
kp = Popen([SUDO, "sh", "-c",
|
||||
"echo l > /proc/sysrq-trigger"])
|
||||
kp.wait()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
"""
|
||||
Kill a running command due to timeout, or ^C from the keyboard. If
|
||||
sudo is required, this user was verified previously.
|
||||
@@ -1129,6 +1187,9 @@ def parse_args():
|
||||
parser.add_option('-o', action='callback', callback=options_cb,
|
||||
default=BASEDIR, dest='outputdir', type='string',
|
||||
metavar='outputdir', help='Specify an output directory.')
|
||||
parser.add_option('-O', action='store_true', default=False,
|
||||
dest='timeout_debug',
|
||||
help='Dump debugging info to /dev/kmsg on test timeout')
|
||||
parser.add_option('-i', action='callback', callback=options_cb,
|
||||
default=TESTDIR, dest='testdir', type='string',
|
||||
metavar='testdir', help='Specify a test directory.')
|
||||
|
||||
@@ -197,6 +197,7 @@ nobase_dist_datadir_zfs_tests_tests_DATA += \
|
||||
functional/cli_root/zpool_import/blockfiles/unclean_export.dat.bz2 \
|
||||
functional/cli_root/zpool_import/zpool_import.cfg \
|
||||
functional/cli_root/zpool_import/zpool_import.kshlib \
|
||||
functional/cli_root/zpool_iostat/zpool_iostat.kshlib \
|
||||
functional/cli_root/zpool_initialize/zpool_initialize.kshlib \
|
||||
functional/cli_root/zpool_labelclear/labelclear.cfg \
|
||||
functional/cli_root/zpool_remove/zpool_remove.cfg \
|
||||
@@ -640,6 +641,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/cli_root/zdb/zdb_decompress_zstd.ksh \
|
||||
functional/cli_root/zdb/zdb_display_block.ksh \
|
||||
functional/cli_root/zdb/zdb_encrypted.ksh \
|
||||
functional/cli_root/zdb/zdb_encrypted_raw.ksh \
|
||||
functional/cli_root/zdb/zdb_label_checksum.ksh \
|
||||
functional/cli_root/zdb/zdb_object_range_neg.ksh \
|
||||
functional/cli_root/zdb/zdb_object_range_pos.ksh \
|
||||
@@ -1027,7 +1029,9 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/cli_root/zpool_add/zpool_add_007_neg.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_008_neg.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_009_neg.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_010_pos.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_warn_create.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_warn_degraded.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_warn_removal.ksh \
|
||||
functional/cli_root/zpool_add/zpool_add_dryrun_output.ksh \
|
||||
functional/cli_root/zpool_attach/attach-o_ashift.ksh \
|
||||
functional/cli_root/zpool_attach/cleanup.ksh \
|
||||
@@ -1178,6 +1182,10 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/cli_root/zpool_import/zpool_import_parallel_admin.ksh \
|
||||
functional/cli_root/zpool_import/zpool_import_parallel_neg.ksh \
|
||||
functional/cli_root/zpool_import/zpool_import_parallel_pos.ksh \
|
||||
functional/cli_root/zpool_iostat/setup.ksh \
|
||||
functional/cli_root/zpool_iostat/cleanup.ksh \
|
||||
functional/cli_root/zpool_iostat/zpool_iostat_interval_all.ksh \
|
||||
functional/cli_root/zpool_iostat/zpool_iostat_interval_some.ksh \
|
||||
functional/cli_root/zpool_initialize/cleanup.ksh \
|
||||
functional/cli_root/zpool_initialize/zpool_initialize_attach_detach_add_remove.ksh \
|
||||
functional/cli_root/zpool_initialize/zpool_initialize_fault_export_import_online.ksh \
|
||||
@@ -2226,6 +2234,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/xattr/xattr_011_pos.ksh \
|
||||
functional/xattr/xattr_012_pos.ksh \
|
||||
functional/xattr/xattr_013_pos.ksh \
|
||||
functional/xattr/xattr_014_pos.ksh \
|
||||
functional/xattr/xattr_compat.ksh \
|
||||
functional/zap_shrink/cleanup.ksh \
|
||||
functional/zap_shrink/zap_shrink_001_pos.ksh \
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2023, Klara Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zfs_load-key/zfs_load-key_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# 'zdb -K ...' should enable reading from a raw-encrypted dataset
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create an encrypted dataset
|
||||
# 2. Write some data to a file
|
||||
# 3. Run zdb -dddd on the file, confirm it can't be read
|
||||
# 4. Run zdb -K ... -ddddd on the file, confirm it can be read
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
dataset="$TESTPOOL/$TESTFS2"
|
||||
file="$TESTDIR2/somefile"
|
||||
keyfile="$TEST_BASE_DIR/keyfile"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
datasetexists "$dataset" && destroy_dataset "$dataset" -f
|
||||
rm -f "$keyfile"
|
||||
default_cleanup_noexit
|
||||
}
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
log_must default_setup_noexit $DISKS
|
||||
|
||||
log_assert "'zdb -K' should enable reading from a raw-encrypted dataset"
|
||||
|
||||
# The key must be 32 bytes long.
|
||||
echo -n "$RAWKEY" > "$keyfile"
|
||||
|
||||
log_must zfs create -o mountpoint="$TESTDIR2" \
|
||||
-o encryption=on -o keyformat=raw -o keylocation="file://$keyfile" \
|
||||
"$dataset"
|
||||
|
||||
echo 'my great encrypted text' > "$file"
|
||||
|
||||
typeset -i obj=$(ls -i "$file" | cut -d' ' -f1)
|
||||
typeset -i size=$(wc -c < "$file")
|
||||
|
||||
log_note "test file $file is objid $obj, size $size"
|
||||
|
||||
sync_pool "$TESTPOOL" true
|
||||
|
||||
log_must eval "zdb -dddd $dataset $obj | grep -q 'object encrypted'"
|
||||
|
||||
log_must eval "zdb -K $keyfile -dddd $dataset $obj | grep -q 'size\s$size$'"
|
||||
|
||||
log_pass "'zdb -K' enables reading from a raw-encrypted dataset"
|
||||
+42
@@ -27,6 +27,7 @@
|
||||
|
||||
#
|
||||
# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
# Copyright 2025 by Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
@@ -89,3 +90,44 @@ function save_dump_dev
|
||||
fi
|
||||
echo $dumpdev
|
||||
}
|
||||
|
||||
function zpool_create_add_setup
|
||||
{
|
||||
typeset -i i=0
|
||||
|
||||
while ((i < 10)); do
|
||||
log_must truncate -s $MINVDEVSIZE $TEST_BASE_DIR/vdev$i
|
||||
|
||||
eval vdev$i=$TEST_BASE_DIR/vdev$i
|
||||
((i += 1))
|
||||
done
|
||||
|
||||
if is_linux; then
|
||||
vdev_lo="$(losetup -f "$vdev4" --show)"
|
||||
elif is_freebsd; then
|
||||
vdev_lo=/dev/"$(mdconfig -a -t vnode -f "$vdev4")"
|
||||
else
|
||||
vdev_lo="$(lofiadm -a "$vdev4")"
|
||||
fi
|
||||
}
|
||||
|
||||
function zpool_create_add_cleanup
|
||||
{
|
||||
datasetexists $TESTPOOL1 && destroy_pool $TESTPOOL1
|
||||
|
||||
if [[ -e $vdev_lo ]]; then
|
||||
if is_linux; then
|
||||
log_must losetup -d "$vdev_lo"
|
||||
elif is_freebsd; then
|
||||
log_must mdconfig -d -u "$vdev_lo"
|
||||
else
|
||||
log_must lofiadm -d "$vdev_lo"
|
||||
fi
|
||||
fi
|
||||
|
||||
typeset -i i=0
|
||||
while ((i < 10)); do
|
||||
rm -f $TEST_BASE_DIR/vdev$i
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
|
||||
+23
-78
@@ -23,67 +23,51 @@
|
||||
|
||||
#
|
||||
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||
# Copyright 2012, 2016 by Delphix. All rights reserved.
|
||||
# Copyright 2025 by Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_create/zpool_create.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_add/zpool_add.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify zpool add succeed when adding vdevs with matching redundancy.
|
||||
# Verify zpool add succeeds when adding vdevs with matching redundancy
|
||||
# and warns with differing redundancy for a healthy pool.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create several files == $MINVDEVSIZE.
|
||||
# 2. Verify 'zpool add' succeeds with matching redundancy.
|
||||
# 3. Verify 'zpool add' warns with differing redundancy.
|
||||
# 4. Verify 'zpool add' warns with differing redundancy after removal.
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
datasetexists $TESTPOOL1 && destroy_pool $TESTPOOL1
|
||||
log_assert "Verify 'zpool add' warns for differing redundancy."
|
||||
log_onexit zpool_create_add_cleanup
|
||||
|
||||
typeset -i i=0
|
||||
while ((i < 10)); do
|
||||
rm -f $TEST_BASE_DIR/vdev$i
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
zpool_create_add_setup
|
||||
|
||||
|
||||
log_assert "Verify 'zpool add' succeed with keywords combination."
|
||||
log_onexit cleanup
|
||||
|
||||
# 1. Create several files == $MINVDEVSIZE.
|
||||
typeset -i i=0
|
||||
while ((i < 10)); do
|
||||
log_must truncate -s $MINVDEVSIZE $TEST_BASE_DIR/vdev$i
|
||||
|
||||
eval vdev$i=$TEST_BASE_DIR/vdev$i
|
||||
((i += 1))
|
||||
done
|
||||
typeset -i j=0
|
||||
|
||||
set -A redundancy0_create_args \
|
||||
"$vdev0"
|
||||
|
||||
set -A redundancy1_create_args \
|
||||
"mirror $vdev0 $vdev1" \
|
||||
"raidz1 $vdev0 $vdev1"
|
||||
"raidz1 $vdev0 $vdev1" \
|
||||
"draid1:1s $vdev0 $vdev1 $vdev9"
|
||||
|
||||
set -A redundancy2_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2" \
|
||||
"raidz2 $vdev0 $vdev1 $vdev2"
|
||||
"raidz2 $vdev0 $vdev1 $vdev2" \
|
||||
"draid2:1s $vdev0 $vdev1 $vdev2 $vdev9"
|
||||
|
||||
set -A redundancy3_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"raidz3 $vdev0 $vdev1 $vdev2 $vdev3"
|
||||
"raidz3 $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"draid3:1s $vdev0 $vdev1 $vdev2 $vdev3 $vdev9"
|
||||
|
||||
set -A redundancy0_add_args \
|
||||
"$vdev5" \
|
||||
@@ -93,21 +77,19 @@ set -A redundancy1_add_args \
|
||||
"mirror $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 raidz1 $vdev7 $vdev8"
|
||||
"mirror $vdev5 $vdev6 raidz1 $vdev7 $vdev8" \
|
||||
"draid1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 draid1 $vdev7 $vdev8"
|
||||
|
||||
set -A redundancy2_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7" \
|
||||
"raidz2 $vdev5 $vdev6 $vdev7"
|
||||
"raidz2 $vdev5 $vdev6 $vdev7" \
|
||||
"draid2 $vdev5 $vdev6 $vdev7"
|
||||
|
||||
set -A redundancy3_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"raidz3 $vdev5 $vdev6 $vdev7 $vdev8"
|
||||
|
||||
set -A log_args "log" "$vdev4"
|
||||
set -A cache_args "cache" "$vdev4"
|
||||
set -A spare_args "spare" "$vdev4"
|
||||
|
||||
typeset -i j=0
|
||||
"raidz3 $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"draid3 $vdev5 $vdev6 $vdev7 $vdev8"
|
||||
|
||||
function zpool_create_add
|
||||
{
|
||||
@@ -148,30 +130,6 @@ function zpool_create_forced_add
|
||||
done
|
||||
}
|
||||
|
||||
function zpool_create_rm_add
|
||||
{
|
||||
typeset -n create_args=$1
|
||||
typeset -n add_args=$2
|
||||
typeset -n rm_args=$3
|
||||
|
||||
i=0
|
||||
while ((i < ${#create_args[@]})); do
|
||||
j=0
|
||||
while ((j < ${#add_args[@]})); do
|
||||
log_must zpool create $TESTPOOL1 ${create_args[$i]}
|
||||
log_must zpool add $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_must zpool add $TESTPOOL1 ${add_args[$j]}
|
||||
log_must zpool remove $TESTPOOL1 ${rm_args[1]}
|
||||
log_mustnot zpool add $TESTPOOL1 ${rm_args[1]}
|
||||
log_must zpool add $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_must zpool destroy -f $TESTPOOL1
|
||||
|
||||
((j += 1))
|
||||
done
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
|
||||
# 2. Verify 'zpool add' succeeds with matching redundancy.
|
||||
zpool_create_add redundancy0_create_args redundancy0_add_args
|
||||
zpool_create_add redundancy1_create_args redundancy1_add_args
|
||||
@@ -195,17 +153,4 @@ zpool_create_forced_add redundancy3_create_args redundancy0_add_args
|
||||
zpool_create_forced_add redundancy3_create_args redundancy1_add_args
|
||||
zpool_create_forced_add redundancy3_create_args redundancy2_add_args
|
||||
|
||||
# 4. Verify 'zpool add' warns with differing redundancy after removal.
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args log_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args log_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args log_args
|
||||
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args cache_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args cache_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args cache_args
|
||||
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args spare_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args spare_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args spare_args
|
||||
|
||||
log_pass "'zpool add' succeed with keywords combination."
|
||||
log_pass "Verify 'zpool add' warns for differing redundancy."
|
||||
Executable
+204
@@ -0,0 +1,204 @@
|
||||
#!/bin/ksh -p
|
||||
# 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.
|
||||
# Copyright 2012, 2016 by Delphix. All rights reserved.
|
||||
# Copyright 2025 by Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_add/zpool_add.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify zpool add succeeds when adding vdevs with matching redundancy
|
||||
# and warns with differing redundancy for a degraded pool.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create several files == $MINVDEVSIZE.
|
||||
# 2. Verify 'zpool add' succeeds with matching redundancy
|
||||
# 3. Verify 'zpool add' warns with differing redundancy when
|
||||
# a. Degraded pool with replaced mismatch vdev (file vs disk)
|
||||
# b. Degraded pool dRAID distributed spare active
|
||||
# c. Degraded pool hot spare active
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Verify 'zpool add' warns for differing redundancy."
|
||||
log_onexit zpool_create_add_cleanup
|
||||
|
||||
zpool_create_add_setup
|
||||
|
||||
set -A redundancy1_create_args \
|
||||
"mirror $vdev0 $vdev1" \
|
||||
"raidz1 $vdev0 $vdev1" \
|
||||
"draid1:1s $vdev0 $vdev1 $vdev9"
|
||||
|
||||
set -A redundancy2_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2" \
|
||||
"raidz2 $vdev0 $vdev1 $vdev2" \
|
||||
"draid2:1s $vdev0 $vdev1 $vdev2 $vdev9"
|
||||
|
||||
set -A redundancy3_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"raidz3 $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"draid3:1s $vdev0 $vdev1 $vdev2 $vdev3 $vdev9"
|
||||
|
||||
set -A redundancy1_add_args \
|
||||
"mirror $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 raidz1 $vdev7 $vdev8" \
|
||||
"draid1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 draid1 $vdev7 $vdev8"
|
||||
|
||||
set -A redundancy2_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7" \
|
||||
"raidz2 $vdev5 $vdev6 $vdev7" \
|
||||
"draid2 $vdev5 $vdev6 $vdev7"
|
||||
|
||||
set -A redundancy3_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"raidz3 $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"draid3 $vdev5 $vdev6 $vdev7 $vdev8"
|
||||
|
||||
set -A redundancy1_create_draid_args \
|
||||
"draid1:1s $vdev0 $vdev1 $vdev2"
|
||||
|
||||
set -A redundancy2_create_draid_args \
|
||||
"draid2:1s $vdev0 $vdev1 $vdev2 $vdev3"
|
||||
|
||||
set -A redundancy3_create_draid_args \
|
||||
"draid3:1s $vdev0 $vdev1 $vdev2 $vdev3 $vdev9"
|
||||
|
||||
set -A redundancy1_create_spare_args \
|
||||
"mirror $vdev0 $vdev1 spare $vdev_lo" \
|
||||
"raidz1 $vdev0 $vdev1 spare $vdev_lo" \
|
||||
"draid1 $vdev0 $vdev1 spare $vdev_lo"
|
||||
|
||||
set -A redundancy2_create_spare_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2 spare $vdev_lo" \
|
||||
"raidz2 $vdev0 $vdev1 $vdev2 spare $vdev_lo" \
|
||||
"draid2 $vdev0 $vdev1 $vdev2 spare $vdev_lo"
|
||||
|
||||
set -A redundancy3_create_spare_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2 $vdev3 spare $vdev_lo" \
|
||||
"raidz3 $vdev0 $vdev1 $vdev2 $vdev3 spare $vdev_lo" \
|
||||
"draid3 $vdev0 $vdev1 $vdev2 $vdev3 spare $vdev_lo"
|
||||
|
||||
set -A replace_args "$vdev1" "$vdev_lo"
|
||||
set -A draid1_args "$vdev1" "draid1-0-0"
|
||||
set -A draid2_args "$vdev1" "draid2-0-0"
|
||||
set -A draid3_args "$vdev1" "draid3-0-0"
|
||||
|
||||
typeset -i i=0
|
||||
typeset -i j=0
|
||||
|
||||
function zpool_create_degraded_add
|
||||
{
|
||||
typeset -n create_args=$1
|
||||
typeset -n add_args=$2
|
||||
typeset -n rm_args=$3
|
||||
|
||||
i=0
|
||||
while ((i < ${#create_args[@]})); do
|
||||
j=0
|
||||
while ((j < ${#add_args[@]})); do
|
||||
log_must zpool create $TESTPOOL1 ${create_args[$i]}
|
||||
log_must zpool offline -f $TESTPOOL1 ${rm_args[0]}
|
||||
log_must zpool replace -w $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_must zpool add $TESTPOOL1 ${add_args[$j]}
|
||||
log_must zpool destroy -f $TESTPOOL1
|
||||
log_must zpool labelclear -f ${rm_args[0]}
|
||||
|
||||
((j += 1))
|
||||
done
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
|
||||
function zpool_create_forced_degraded_add
|
||||
{
|
||||
typeset -n create_args=$1
|
||||
typeset -n add_args=$2
|
||||
typeset -n rm_args=$3
|
||||
|
||||
i=0
|
||||
while ((i < ${#create_args[@]})); do
|
||||
j=0
|
||||
while ((j < ${#add_args[@]})); do
|
||||
log_must zpool create $TESTPOOL1 ${create_args[$i]}
|
||||
log_must zpool offline -f $TESTPOOL1 ${rm_args[0]}
|
||||
log_must zpool replace -w $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_mustnot zpool add $TESTPOOL1 ${add_args[$j]}
|
||||
log_must zpool add --allow-replication-mismatch $TESTPOOL1 ${add_args[$j]}
|
||||
log_must zpool destroy -f $TESTPOOL1
|
||||
log_must zpool labelclear -f ${rm_args[0]}
|
||||
|
||||
((j += 1))
|
||||
done
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
|
||||
# 2. Verify 'zpool add' succeeds with matching redundancy and a degraded pool.
|
||||
zpool_create_degraded_add redundancy1_create_args redundancy1_add_args replace_args
|
||||
zpool_create_degraded_add redundancy2_create_args redundancy2_add_args replace_args
|
||||
zpool_create_degraded_add redundancy3_create_args redundancy3_add_args replace_args
|
||||
|
||||
# 3. Verify 'zpool add' warns with differing redundancy and a degraded pool.
|
||||
#
|
||||
# a. Degraded pool with replaced mismatch vdev (file vs disk)
|
||||
zpool_create_forced_degraded_add redundancy1_create_args redundancy2_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy1_create_args redundancy3_add_args replace_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy2_create_args redundancy1_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy2_create_args redundancy3_add_args replace_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy3_create_args redundancy1_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy3_create_args redundancy2_add_args replace_args
|
||||
|
||||
# b. Degraded pool dRAID distributed spare active
|
||||
|
||||
zpool_create_forced_degraded_add redundancy1_create_draid_args redundancy2_add_args draid1_args
|
||||
zpool_create_forced_degraded_add redundancy1_create_draid_args redundancy3_add_args draid1_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy2_create_draid_args redundancy1_add_args draid2_args
|
||||
zpool_create_forced_degraded_add redundancy2_create_draid_args redundancy3_add_args draid2_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy3_create_draid_args redundancy1_add_args draid3_args
|
||||
zpool_create_forced_degraded_add redundancy3_create_draid_args redundancy2_add_args draid3_args
|
||||
|
||||
# c. Degraded pool hot spare active
|
||||
zpool_create_forced_degraded_add redundancy1_create_spare_args redundancy2_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy1_create_spare_args redundancy3_add_args replace_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy2_create_spare_args redundancy1_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy2_create_spare_args redundancy3_add_args replace_args
|
||||
|
||||
zpool_create_forced_degraded_add redundancy3_create_spare_args redundancy1_add_args replace_args
|
||||
zpool_create_forced_degraded_add redundancy3_create_spare_args redundancy2_add_args replace_args
|
||||
|
||||
log_pass "Verify 'zpool add' warns for differing redundancy."
|
||||
Executable
+126
@@ -0,0 +1,126 @@
|
||||
#!/bin/ksh -p
|
||||
# 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.
|
||||
# Copyright 2012, 2016 by Delphix. All rights reserved.
|
||||
# Copyright 2025 by Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_add/zpool_add.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify zpool add succeeds when adding vdevs with matching redundancy
|
||||
# and warns with differing redundancy after removal.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create several files == $MINVDEVSIZE.
|
||||
# 2. Verify 'zpool add' warns with differing redundancy after removal.
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_assert "Verify 'zpool add' warns for differing redundancy."
|
||||
log_onexit zpool_create_add_cleanup
|
||||
|
||||
zpool_create_add_setup
|
||||
|
||||
typeset -i i=0
|
||||
typeset -i j=0
|
||||
|
||||
set -A redundancy1_create_args \
|
||||
"mirror $vdev0 $vdev1" \
|
||||
"raidz1 $vdev0 $vdev1" \
|
||||
"draid1:1s $vdev0 $vdev1 $vdev9"
|
||||
|
||||
set -A redundancy2_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2" \
|
||||
"raidz2 $vdev0 $vdev1 $vdev2" \
|
||||
"draid2:1s $vdev0 $vdev1 $vdev2 $vdev9"
|
||||
|
||||
set -A redundancy3_create_args \
|
||||
"mirror $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"raidz3 $vdev0 $vdev1 $vdev2 $vdev3" \
|
||||
"draid3:1s $vdev0 $vdev1 $vdev2 $vdev3 $vdev9"
|
||||
|
||||
set -A redundancy1_add_args \
|
||||
"mirror $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6" \
|
||||
"raidz1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 raidz1 $vdev7 $vdev8" \
|
||||
"draid1 $vdev5 $vdev6 mirror $vdev7 $vdev8" \
|
||||
"mirror $vdev5 $vdev6 draid1 $vdev7 $vdev8"
|
||||
|
||||
set -A redundancy2_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7" \
|
||||
"raidz2 $vdev5 $vdev6 $vdev7" \
|
||||
"draid2 $vdev5 $vdev6 $vdev7"
|
||||
|
||||
set -A redundancy3_add_args \
|
||||
"mirror $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"raidz3 $vdev5 $vdev6 $vdev7 $vdev8" \
|
||||
"draid3 $vdev5 $vdev6 $vdev7 $vdev8"
|
||||
|
||||
set -A log_args "log" "$vdev_lo"
|
||||
set -A cache_args "cache" "$vdev_lo"
|
||||
set -A spare_args "spare" "$vdev_lo"
|
||||
|
||||
|
||||
function zpool_create_rm_add
|
||||
{
|
||||
typeset -n create_args=$1
|
||||
typeset -n add_args=$2
|
||||
typeset -n rm_args=$3
|
||||
|
||||
i=0
|
||||
while ((i < ${#create_args[@]})); do
|
||||
j=0
|
||||
while ((j < ${#add_args[@]})); do
|
||||
log_must zpool create $TESTPOOL1 ${create_args[$i]}
|
||||
log_must zpool add $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_must zpool add $TESTPOOL1 ${add_args[$j]}
|
||||
log_must zpool remove $TESTPOOL1 ${rm_args[1]}
|
||||
log_mustnot zpool add $TESTPOOL1 ${rm_args[1]}
|
||||
log_must zpool add $TESTPOOL1 ${rm_args[0]} ${rm_args[1]}
|
||||
log_must zpool destroy -f $TESTPOOL1
|
||||
|
||||
((j += 1))
|
||||
done
|
||||
((i += 1))
|
||||
done
|
||||
}
|
||||
|
||||
# 2. Verify 'zpool add' warns with differing redundancy after removal.
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args log_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args log_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args log_args
|
||||
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args cache_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args cache_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args cache_args
|
||||
|
||||
zpool_create_rm_add redundancy1_create_args redundancy1_add_args spare_args
|
||||
zpool_create_rm_add redundancy2_create_args redundancy2_add_args spare_args
|
||||
zpool_create_rm_add redundancy3_create_args redundancy3_add_args spare_args
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2025, Klara, Inc.
|
||||
#
|
||||
#
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
log_pass
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2025, Klara, Inc.
|
||||
#
|
||||
#
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_pass
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
# 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) 2025, Klara, Inc.
|
||||
#
|
||||
|
||||
# Since we want to make sure that iostat responds correctly as pools appear and
|
||||
# disappear, we run it in the background and capture its output to a file.
|
||||
# Once we're done, we parse the output and ensure it matches what we'd expect
|
||||
# from the operations we performed.
|
||||
#
|
||||
# Because iostat is producing output every interval, it may produce the "same"
|
||||
# output for each step of the change; in fact, we want that to make sure we
|
||||
# don't miss anything. So, we describe what we expect as a series of "chunks".
|
||||
# Each chunk is a particular kind of output, which may repeat. Current known
|
||||
# chunk types are:
|
||||
#
|
||||
# NOPOOL: the text "no pools available"
|
||||
# HEADER: three lines, starting with "capacity", "pool" and "----" respectively.
|
||||
# (the rough shape of the normal iostat header).
|
||||
# POOL1: a line starting with "pool1" (stats line for a pool of that name)
|
||||
# POOL2: a line starting with "pool2"
|
||||
# POOLBOTH: three lines, starting with "pool1", "pool2" (either order) and
|
||||
# "-----" respectively. (the pool stat output for multiple pools)
|
||||
#
|
||||
# (the parser may produce other chunks in a failed parse to assist with
|
||||
# debugging, but they should never be part of the "wanted" output See the
|
||||
# parser commentary below).
|
||||
#
|
||||
# To help recognise the start of a new interval output, we run iostat with the
|
||||
# -T u option, which will output a numeric timestamp before each header or
|
||||
# second-or-later pool stat after the header.
|
||||
#
|
||||
# To keep the test run shorter, we use a subsecond interval, but to make sure
|
||||
# nothing is missed, we sleep for three intervals after each change.
|
||||
|
||||
typeset _iostat_out=$(mktemp)
|
||||
typeset _iostat_pid=""
|
||||
|
||||
function cleanup_iostat {
|
||||
if [[ -n $_iostat_pid ]] ; then
|
||||
kill -KILL $_iostat_pid || true
|
||||
fi
|
||||
rm -f $_iostat_out
|
||||
}
|
||||
|
||||
function start_iostat {
|
||||
zpool iostat -T u $@ 0.1 > $_iostat_out 2>&1 &
|
||||
_iostat_pid=$!
|
||||
}
|
||||
|
||||
function stop_iostat {
|
||||
kill -TERM $_iostat_pid
|
||||
wait $_iostat_pid
|
||||
_iostat_pid=""
|
||||
}
|
||||
|
||||
function delay_iostat {
|
||||
sleep 0.3
|
||||
}
|
||||
|
||||
typeset -a _iostat_expect
|
||||
function expect_iostat {
|
||||
typeset chunk=$1
|
||||
_iostat_expect+=($chunk)
|
||||
}
|
||||
|
||||
# Parse the output The `state` var is used to track state across
|
||||
# multiple lines. The `last` var and the `_got_iostat` function are used
|
||||
# to record the completed chunks, and to collapse repetitions.
|
||||
typeset -a _iostat_got
|
||||
typeset _iostat_last=""
|
||||
typeset _iostat_state=""
|
||||
|
||||
function _got_iostat {
|
||||
typeset chunk=$1
|
||||
if [[ -n $chunk && $_iostat_last != $chunk ]] ; then
|
||||
_iostat_last=$chunk
|
||||
_iostat_got+=($chunk)
|
||||
fi
|
||||
_iostat_state=""
|
||||
}
|
||||
|
||||
function verify_iostat {
|
||||
|
||||
cat $_iostat_out | while read line ; do
|
||||
|
||||
# The "no pools available" text has no timestamp or other
|
||||
# header, and should never appear in the middle of multiline
|
||||
# chunk, so we can close any in-flight state.
|
||||
if [[ $line = "no pools available" ]] ; then
|
||||
_got_iostat $_iostat_state
|
||||
_got_iostat "NOPOOL"
|
||||
continue
|
||||
fi
|
||||
|
||||
# A run of digits alone on the line is a timestamp (the `-T u`
|
||||
# switch to `iostat`). It closes any in-flight state as a
|
||||
# complete chunk, and indicates the start of a new chunk.
|
||||
if [[ -z ${line/#+([0-9])/} ]] ; then
|
||||
_got_iostat $_iostat_state
|
||||
_iostat_state="TIMESTAMP"
|
||||
continue
|
||||
fi
|
||||
|
||||
# For this test, the first word of each line should be unique,
|
||||
# so we extract it and use it for simplicity.
|
||||
typeset first=${line%% *}
|
||||
|
||||
# Header is emitted whenever the pool list changes. It has
|
||||
# three lines:
|
||||
#
|
||||
# capacity operations bandwidth
|
||||
# pool alloc free read write read write
|
||||
# ---------- ----- ----- ----- ----- ----- -----
|
||||
#
|
||||
# Each line moves the state; when we get to a run of dashes, we
|
||||
# commit. Note that we check for one-or-more dashes, because
|
||||
# the width can vary depending on the length of pool name.
|
||||
#
|
||||
if [[ $_iostat_state = "TIMESTAMP" &&
|
||||
$first = "capacity" ]] ; then
|
||||
_iostat_state="INHEADER1"
|
||||
continue
|
||||
fi
|
||||
if [[ $_iostat_state = "INHEADER1" &&
|
||||
$first = "pool" ]] ; then
|
||||
_iostat_state="INHEADER2"
|
||||
continue
|
||||
fi
|
||||
if [[ $_iostat_state = "INHEADER2" &&
|
||||
-z ${first/#+(-)/} ]] ; then
|
||||
# Headers never repeat, so if the last committed chunk
|
||||
# was a header, we commit this one as EXTRAHEADER so we
|
||||
# can see it in the error output.
|
||||
if [[ $_iostat_last = "HEADER" ]] ; then
|
||||
_got_iostat "EXTRAHEADER"
|
||||
elif [[ $_iostat_last != "EXTRAHEADER" ]] ; then
|
||||
_got_iostat "HEADER"
|
||||
fi
|
||||
_iostat_state="HEADER"
|
||||
continue
|
||||
fi
|
||||
|
||||
# A pool stat line looks like:
|
||||
#
|
||||
# pool1 147K 240M 0 0 0 0
|
||||
#
|
||||
# If there are multiple pools, iostat follows them with a
|
||||
# separator of dashed lines:
|
||||
#
|
||||
# pool1 147K 240M 0 0 0 0
|
||||
# pool2 147K 240M 0 0 0 0
|
||||
# ---------- ----- ----- ----- ----- ----- -----
|
||||
#
|
||||
# Stats rows always start after a timestamp or a header. If the
|
||||
# header was emitted, we won't see a timestamp here (it goes
|
||||
# before the header).
|
||||
#
|
||||
# Because our test exercises both pools on their own and
|
||||
# together, we allow pools in either order. In practice they
|
||||
# are sorted, but that's a side-effect of the implementation
|
||||
# (see zpool_compare()), so we're not going to rely on it here.
|
||||
if [[ $first = "pool1" ]] || [[ $first = "pool2" ]] ; then
|
||||
|
||||
# First line, track which one we saw. If it's a
|
||||
# standalone line, it will be committed by the next
|
||||
# NOPOOL or TIMESTAMP above (or the `_got_iostat` after
|
||||
# the loop if this is the last line).
|
||||
if [[ $_iostat_state == "TIMESTAMP" ||
|
||||
$_iostat_state == "HEADER" ]] ; then
|
||||
if [[ $first = "pool1" ]] ; then
|
||||
_iostat_state="POOL1"
|
||||
elif [[ $first = "pool2" ]] ; then
|
||||
_iostat_state="POOL2"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# If this is the second pool, we're in a multi-pool
|
||||
# block, and need to look for the separator to close it
|
||||
# out.
|
||||
if [[ $_iostat_state = "POOL1" && $first = "pool2" ]] ||
|
||||
[[ $_iostat_state = "POOL2" && $first = "pool1" ]] ;
|
||||
then
|
||||
_iostat_state="INPOOLBOTH"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Separator after the stats block.
|
||||
if [[ $_iostat_state = "INPOOLBOTH" &&
|
||||
-z ${first/#+(-)/} ]] ; then
|
||||
_got_iostat "POOLBOTH"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Anything else will fall through to here. We commit any
|
||||
# in-flight state, then "UNKNOWN", all to help with debugging..
|
||||
if [[ $_iostat_state != "UNKNOWN" ]] ; then
|
||||
_got_iostat $_iostat_state
|
||||
_got_iostat "UNKNOWN"
|
||||
fi
|
||||
done
|
||||
|
||||
# Close out any remaining state.
|
||||
_got_iostat $_iostat_state
|
||||
|
||||
# Compare what we wanted with what we got, and pass/fail the test!
|
||||
if [[ "${_iostat_expect[*]}" != "${_iostat_got[*]}" ]] ; then
|
||||
log_note "expected: ${_iostat_expect[*]}"
|
||||
log_note " got: ${_iostat_got[*]}"
|
||||
log_fail "zpool iostat did not produce expected output"
|
||||
fi
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2025, Klara, Inc.
|
||||
#
|
||||
|
||||
# `zpool iostat <N>` should keep running and update the pools it displays as
|
||||
# pools are created/destroyed/imported/export.
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_iostat/zpool_iostat.kshlib
|
||||
|
||||
typeset vdev1=$(mktemp)
|
||||
typeset vdev2=$(mktemp)
|
||||
|
||||
function cleanup {
|
||||
cleanup_iostat
|
||||
|
||||
poolexists pool1 && destroy_pool pool1
|
||||
poolexists pool2 && destroy_pool pool2
|
||||
rm -f $vdev1 $vdev2
|
||||
}
|
||||
|
||||
log_must mkfile $MINVDEVSIZE $vdev1 $vdev2
|
||||
|
||||
expect_iostat "NOPOOL"
|
||||
|
||||
start_iostat
|
||||
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOL1"
|
||||
log_must zpool create pool1 $vdev1
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOLBOTH"
|
||||
log_must zpool create pool2 $vdev2
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "NOPOOL"
|
||||
log_must zpool export -a
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOL2"
|
||||
log_must zpool import -d $vdev2 pool2
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOLBOTH"
|
||||
log_must zpool import -d $vdev1 pool1
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOL2"
|
||||
log_must zpool destroy pool1
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "NOPOOL"
|
||||
log_must zpool destroy pool2
|
||||
delay_iostat
|
||||
|
||||
stop_iostat
|
||||
|
||||
verify_iostat
|
||||
|
||||
log_pass "zpool iostat in interval mode follows pool updates"
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2025, Klara, Inc.
|
||||
#
|
||||
|
||||
# `zpool iostat <pools> <N>` should keep running and only show the listed pools.
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_iostat/zpool_iostat.kshlib
|
||||
|
||||
typeset vdev1=$(mktemp)
|
||||
typeset vdev2=$(mktemp)
|
||||
|
||||
function cleanup {
|
||||
cleanup_iostat
|
||||
|
||||
poolexists pool1 && destroy_pool pool1
|
||||
poolexists pool2 && destroy_pool pool2
|
||||
rm -f $vdev1 $vdev2
|
||||
}
|
||||
|
||||
log_must mkfile $MINVDEVSIZE $vdev1 $vdev2
|
||||
|
||||
log_must zpool create pool1 $vdev1
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOL1"
|
||||
start_iostat pool1
|
||||
delay_iostat
|
||||
|
||||
log_must zpool create pool2 $vdev2
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "NOPOOL"
|
||||
log_must zpool export -a
|
||||
delay_iostat
|
||||
|
||||
log_must zpool import -d $vdev2 pool2
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "HEADER"
|
||||
expect_iostat "POOL1"
|
||||
log_must zpool import -d $vdev1 pool1
|
||||
delay_iostat
|
||||
|
||||
expect_iostat "NOPOOL"
|
||||
log_must zpool destroy pool1
|
||||
delay_iostat
|
||||
|
||||
log_must zpool destroy pool2
|
||||
delay_iostat
|
||||
|
||||
stop_iostat
|
||||
|
||||
verify_iostat
|
||||
|
||||
log_pass "zpool iostat in interval mode with pools follows listed pool updates"
|
||||
+3
-3
@@ -1234,10 +1234,10 @@ function verify_fs_aedsx
|
||||
typeset oldval
|
||||
set -A modes "on" "off"
|
||||
oldval=$(get_prop $perm $fs)
|
||||
if [[ $oldval == "on" ]]; then
|
||||
n=1
|
||||
elif [[ $oldval == "off" ]]; then
|
||||
if [[ $oldval == "off" ]]; then
|
||||
n=0
|
||||
else
|
||||
n=1
|
||||
fi
|
||||
log_note "$user zfs set $perm=${modes[$n]} $fs"
|
||||
user_run $user zfs set $perm=${modes[$n]} $fs
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
verify_runnable "global"
|
||||
|
||||
# create a pool without any features
|
||||
log_must mkfile 128m $TMPDEV
|
||||
log_must truncate -s $MINVDEVSIZE $TMPDEV
|
||||
|
||||
log_pass
|
||||
|
||||
+8
-6
@@ -35,17 +35,19 @@
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
TESTFILE="$TESTDIR/file.bin"
|
||||
|
||||
log_assert "User accounting upgrade should not be executed on readonly pool"
|
||||
log_onexit cleanup_upgrade
|
||||
|
||||
# 1. Create a pool with the feature@userobj_accounting disabled to simulate
|
||||
# a legacy pool from a previous ZFS version.
|
||||
log_must zpool create -d -m $TESTDIR $TESTPOOL $TMPDEV
|
||||
log_must zpool create -d $TESTPOOL $TMPDEV
|
||||
log_must zfs create $TESTPOOL/$TESTFS
|
||||
|
||||
MNTPNT=$(get_prop mountpoint $TESTPOOL/$TESTFS)
|
||||
TESTFILE="$MNTPNT/file.bin"
|
||||
|
||||
# 2. Create a file on the "legecy" dataset
|
||||
log_must touch $TESTDIR/file.bin
|
||||
log_must touch $TESTFILE
|
||||
|
||||
# 3. Enable feature@userobj_accounting on the pool and verify it is only
|
||||
# "enabled" and not "active": upgrading starts when the filesystem is mounted
|
||||
@@ -54,12 +56,12 @@ log_must test "enabled" == "$(get_pool_prop 'feature@userobj_accounting' $TESTPO
|
||||
|
||||
# 4. Export the pool and re-import is readonly, without mounting any filesystem
|
||||
log_must zpool export $TESTPOOL
|
||||
log_must zpool import -o readonly=on -N -d "$(dirname $TMPDEV)" $TESTPOOL
|
||||
log_must zpool import -o readonly=on -N -d $TEST_BASE_DIR $TESTPOOL
|
||||
|
||||
# 5. Try to mount the root dataset manually without the "ro" option, then verify
|
||||
# filesystem status and the pool feature status (not "active") to ensure the
|
||||
# pool "readonly" status is enforced.
|
||||
log_must mount -t zfs -o zfsutil $TESTPOOL $TESTDIR
|
||||
log_must zfs mount -R $TESTPOOL
|
||||
log_must stat "$TESTFILE"
|
||||
log_mustnot touch "$TESTFILE"
|
||||
log_must test "enabled" == "$(get_pool_prop 'feature@userobj_accounting' $TESTPOOL)"
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
#!/bin/ksh -p
|
||||
# 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) 2025 by Klara, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/xattr/xattr_common.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# The default xattr should be shown as 'sa', not 'on', for clarity.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a filesystem.
|
||||
# 2. Verify that the xattra is shown as 'sa'.
|
||||
# 3. Manually set the value to 'dir', 'sa', 'on', and 'off'.
|
||||
# 4. Verify that it is shown as 'dir', 'sa', 'sa', and 'off.
|
||||
#
|
||||
|
||||
log_assert "The default and specific xattr values are displayed correctly."
|
||||
|
||||
set -A args "dir" "sa" "on" "off"
|
||||
set -A display "dir" "sa" "sa" "off"
|
||||
|
||||
log_must eval "[[ 'sa' == '$(zfs get -Hpo value xattr $TESTPOOL)' ]]"
|
||||
|
||||
for i in `seq 0 3`; do
|
||||
log_must zfs set xattr="${args[$i]}" $TESTPOOL
|
||||
log_must eval "[[ '${display[$i]}' == '$(zfs get -Hpo value xattr $TESTPOOL)' ]]"
|
||||
done
|
||||
log_pass "The default and specific xattr values are displayed correctly."
|
||||
+39
-1
@@ -50,17 +50,53 @@ fi
|
||||
|
||||
typeset datafile1="$(mktemp -t zvol_misc_fua1.XXXXXX)"
|
||||
typeset datafile2="$(mktemp -t zvol_misc_fua2.XXXXXX)"
|
||||
typeset datafile3="$(mktemp -t zvol_misc_fua3_log.XXXXXX)"
|
||||
typeset zvolpath=${ZVOL_DEVDIR}/$TESTPOOL/$TESTVOL
|
||||
|
||||
typeset DISK1=${DISKS%% *}
|
||||
function cleanup
|
||||
{
|
||||
rm "$datafile1" "$datafile2"
|
||||
log_must zpool remove $TESTPOOL $datafile3
|
||||
rm "$datafile1" "$datafile2" "$datafile2"
|
||||
}
|
||||
|
||||
# Prints the total number of sync writes for a vdev
|
||||
# $1: vdev
|
||||
function get_sync
|
||||
{
|
||||
zpool iostat -p -H -v -r $TESTPOOL $1 | \
|
||||
awk '/[0-9]+$/{s+=$4+$5} END{print s}'
|
||||
}
|
||||
|
||||
function do_test {
|
||||
# Wait for udev to create symlinks to our zvol
|
||||
block_device_wait $zvolpath
|
||||
|
||||
# Write using sync (creates FLUSH calls after writes, but not FUA)
|
||||
old_vdev_writes=$(get_sync $DISK1)
|
||||
old_log_writes=$(get_sync $datafile3)
|
||||
|
||||
log_must fio --name=write_iops --size=5M \
|
||||
--ioengine=libaio --verify=0 --bs=4K \
|
||||
--iodepth=1 --rw=randwrite --group_reporting=1 \
|
||||
--filename=$zvolpath --sync=1
|
||||
|
||||
vdev_writes=$(( $(get_sync $DISK1) - $old_vdev_writes))
|
||||
log_writes=$(( $(get_sync $datafile3) - $old_log_writes))
|
||||
|
||||
# When we're doing sync writes, we should see many more writes go to
|
||||
# the log vs the first vdev. Experiments show anywhere from a 160-320x
|
||||
# ratio of writes to the log vs the first vdev (due to some straggler
|
||||
# writes to the first vdev).
|
||||
#
|
||||
# Check that we have a large ratio (100x) of sync writes going to the
|
||||
# log device
|
||||
ratio=$(($log_writes / $vdev_writes))
|
||||
log_note "Got $log_writes log writes, $vdev_writes vdev writes."
|
||||
if [ $ratio -lt 100 ] ; then
|
||||
log_fail "Expected > 100x more log writes than vdev writes. "
|
||||
fi
|
||||
|
||||
# Create a data file
|
||||
log_must dd if=/dev/urandom of="$datafile1" bs=1M count=5
|
||||
|
||||
@@ -81,6 +117,8 @@ log_assert "Verify that a ZFS volume can do Force Unit Access (FUA)"
|
||||
log_onexit cleanup
|
||||
|
||||
log_must zfs set compression=off $TESTPOOL/$TESTVOL
|
||||
log_must truncate -s 100M $datafile3
|
||||
log_must zpool add $TESTPOOL log $datafile3
|
||||
|
||||
log_note "Testing without blk-mq"
|
||||
|
||||
|
||||
@@ -843,7 +843,7 @@
|
||||
/* #undef ZFS_DEVICE_MINOR */
|
||||
|
||||
/* Define the project alias string. */
|
||||
#define ZFS_META_ALIAS "zfs-2.4.99-72-FreeBSD_gb2196fbed"
|
||||
#define ZFS_META_ALIAS "zfs-2.4.99-95-FreeBSD_g5605a6d79"
|
||||
|
||||
/* Define the project author. */
|
||||
#define ZFS_META_AUTHOR "OpenZFS"
|
||||
@@ -852,7 +852,7 @@
|
||||
/* #undef ZFS_META_DATA */
|
||||
|
||||
/* Define the maximum compatible kernel version. */
|
||||
#define ZFS_META_KVER_MAX "6.16"
|
||||
#define ZFS_META_KVER_MAX "6.17"
|
||||
|
||||
/* Define the minimum compatible kernel version. */
|
||||
#define ZFS_META_KVER_MIN "4.18"
|
||||
@@ -873,7 +873,7 @@
|
||||
#define ZFS_META_NAME "zfs"
|
||||
|
||||
/* Define the project release. */
|
||||
#define ZFS_META_RELEASE "72-FreeBSD_gb2196fbed"
|
||||
#define ZFS_META_RELEASE "95-FreeBSD_g5605a6d79"
|
||||
|
||||
/* Define the project version. */
|
||||
#define ZFS_META_VERSION "2.4.99"
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define ZFS_META_GITREV "zfs-2.4.99-72-gb2196fbed"
|
||||
#define ZFS_META_GITREV "zfs-2.4.99-95-g5605a6d79"
|
||||
|
||||
Reference in New Issue
Block a user