zfs: merge OpenZFS master-9305ff2ed
Notable upstream pull request merges: #11153 Scalable teardown lock for FreeBSD #11651 Don't bomb out when using keylocation=file:// #11667 zvol: call zil_replaying() during replay #11683 abd_get_offset_struct() may allocate new abd #11693 Intentionally allow ZFS_READONLY in zfs_write #11716 zpool import cachefile improvements #11720 FreeBSD: Clean up zfsdev_close to match Linux #11730 FreeBSD: bring back possibility to rewind the checkpoint from bootloader Obtained from: OpenZFS MFC after: 2 weeks
This commit is contained in:
commit
9db44a8e5d
@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
checkstyle:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
@ -298,8 +298,15 @@ sas_handler() {
|
||||
|
||||
# Utilize DM device name to gather subordinate block devices
|
||||
# using sysfs to avoid userspace utilities
|
||||
DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
|
||||
|
||||
# If our DEVNAME is something like /dev/dm-177, then we may be
|
||||
# able to get our DMDEV from it.
|
||||
DMDEV=$(echo $DEVNAME | sed 's;/dev/;;g')
|
||||
if [ ! -e /sys/block/$DMDEV/slaves/* ] ; then
|
||||
# It's not there, try looking in /dev/mapper
|
||||
DMDEV=$(ls -l --full-time /dev/mapper | grep $DM_NAME |
|
||||
awk '{gsub("../", " "); print $NF}')
|
||||
fi
|
||||
|
||||
# Use sysfs pointers in /sys/block/dm-X/slaves because using
|
||||
# userspace tools creates lots of overhead and should be avoided
|
||||
|
@ -2623,8 +2623,8 @@ print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv,
|
||||
/*
|
||||
* Display the status for the given pool.
|
||||
*/
|
||||
static void
|
||||
show_import(nvlist_t *config)
|
||||
static int
|
||||
show_import(nvlist_t *config, boolean_t report_error)
|
||||
{
|
||||
uint64_t pool_state;
|
||||
vdev_stat_t *vs;
|
||||
@ -2656,6 +2656,13 @@ show_import(nvlist_t *config)
|
||||
|
||||
reason = zpool_import_status(config, &msgid, &errata);
|
||||
|
||||
/*
|
||||
* If we're importing using a cachefile, then we won't report any
|
||||
* errors unless we are in the scan phase of the import.
|
||||
*/
|
||||
if (reason != ZPOOL_STATUS_OK && !report_error)
|
||||
return (reason);
|
||||
|
||||
(void) printf(gettext(" pool: %s\n"), name);
|
||||
(void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
|
||||
(void) printf(gettext(" state: %s"), health);
|
||||
@ -2983,6 +2990,7 @@ show_import(nvlist_t *config)
|
||||
"be part of this pool, though their\n\texact "
|
||||
"configuration cannot be determined.\n"));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
@ -3121,6 +3129,121 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
||||
char *orig_name, char *new_name,
|
||||
boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all,
|
||||
importargs_t *import)
|
||||
{
|
||||
nvlist_t *config = NULL;
|
||||
nvlist_t *found_config = NULL;
|
||||
uint64_t pool_state;
|
||||
|
||||
/*
|
||||
* At this point we have a list of import candidate configs. Even if
|
||||
* we were searching by pool name or guid, we still need to
|
||||
* post-process the list to deal with pool state and possible
|
||||
* duplicate names.
|
||||
*/
|
||||
int err = 0;
|
||||
nvpair_t *elem = NULL;
|
||||
boolean_t first = B_TRUE;
|
||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
|
||||
|
||||
verify(nvpair_value_nvlist(elem, &config) == 0);
|
||||
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||
&pool_state) == 0);
|
||||
if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
|
||||
verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
|
||||
import->policy) == 0);
|
||||
|
||||
if (!pool_specified) {
|
||||
if (first)
|
||||
first = B_FALSE;
|
||||
else if (!do_all)
|
||||
(void) printf("\n");
|
||||
|
||||
if (do_all) {
|
||||
err |= do_import(config, NULL, mntopts,
|
||||
props, flags);
|
||||
} else {
|
||||
/*
|
||||
* If we're importing from cachefile, then
|
||||
* we don't want to report errors until we
|
||||
* are in the scan phase of the import. If
|
||||
* we get an error, then we return that error
|
||||
* to invoke the scan phase.
|
||||
*/
|
||||
if (import->cachefile && !import->scan)
|
||||
err = show_import(config, B_FALSE);
|
||||
else
|
||||
(void) show_import(config, B_TRUE);
|
||||
}
|
||||
} else if (import->poolname != NULL) {
|
||||
char *name;
|
||||
|
||||
/*
|
||||
* We are searching for a pool based on name.
|
||||
*/
|
||||
verify(nvlist_lookup_string(config,
|
||||
ZPOOL_CONFIG_POOL_NAME, &name) == 0);
|
||||
|
||||
if (strcmp(name, import->poolname) == 0) {
|
||||
if (found_config != NULL) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"cannot import '%s': more than "
|
||||
"one matching pool\n"),
|
||||
import->poolname);
|
||||
(void) fprintf(stderr, gettext(
|
||||
"import by numeric ID instead\n"));
|
||||
err = B_TRUE;
|
||||
}
|
||||
found_config = config;
|
||||
}
|
||||
} else {
|
||||
uint64_t guid;
|
||||
|
||||
/*
|
||||
* Search for a pool by guid.
|
||||
*/
|
||||
verify(nvlist_lookup_uint64(config,
|
||||
ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
|
||||
|
||||
if (guid == import->guid)
|
||||
found_config = config;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were searching for a specific pool, verify that we found a
|
||||
* pool, and then do the import.
|
||||
*/
|
||||
if (pool_specified && err == 0) {
|
||||
if (found_config == NULL) {
|
||||
(void) fprintf(stderr, gettext("cannot import '%s': "
|
||||
"no such pool available\n"), orig_name);
|
||||
err = B_TRUE;
|
||||
} else {
|
||||
err |= do_import(found_config, new_name,
|
||||
mntopts, props, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were just looking for pools, report an error if none were
|
||||
* found.
|
||||
*/
|
||||
if (!pool_specified && first)
|
||||
(void) fprintf(stderr,
|
||||
gettext("no pools available to import\n"));
|
||||
return (err);
|
||||
}
|
||||
|
||||
typedef struct target_exists_args {
|
||||
const char *poolname;
|
||||
uint64_t poolguid;
|
||||
@ -3248,51 +3371,54 @@ zpool_do_checkpoint(int argc, char **argv)
|
||||
/*
|
||||
* zpool import [-d dir] [-D]
|
||||
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
||||
* [-d dir | -c cachefile] [-f] -a
|
||||
* [-d dir | -c cachefile | -s] [-f] -a
|
||||
* import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l]
|
||||
* [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
|
||||
* [-d dir | -c cachefile | -s] [-f] [-n] [-F] <pool | id>
|
||||
* [newpool]
|
||||
*
|
||||
* -c Read pool information from a cachefile instead of searching
|
||||
* devices.
|
||||
* -c Read pool information from a cachefile instead of searching
|
||||
* devices. If importing from a cachefile config fails, then
|
||||
* fallback to searching for devices only in the directories that
|
||||
* exist in the cachefile.
|
||||
*
|
||||
* -d Scan in a specific directory, other than /dev/. More than
|
||||
* -d Scan in a specific directory, other than /dev/. More than
|
||||
* one directory can be specified using multiple '-d' options.
|
||||
*
|
||||
* -D Scan for previously destroyed pools or import all or only
|
||||
* specified destroyed pools.
|
||||
* -D Scan for previously destroyed pools or import all or only
|
||||
* specified destroyed pools.
|
||||
*
|
||||
* -R Temporarily import the pool, with all mountpoints relative to
|
||||
* -R Temporarily import the pool, with all mountpoints relative to
|
||||
* the given root. The pool will remain exported when the machine
|
||||
* is rebooted.
|
||||
*
|
||||
* -V Import even in the presence of faulted vdevs. This is an
|
||||
* intentionally undocumented option for testing purposes, and
|
||||
* treats the pool configuration as complete, leaving any bad
|
||||
* -V Import even in the presence of faulted vdevs. This is an
|
||||
* intentionally undocumented option for testing purposes, and
|
||||
* treats the pool configuration as complete, leaving any bad
|
||||
* vdevs in the FAULTED state. In other words, it does verbatim
|
||||
* import.
|
||||
*
|
||||
* -f Force import, even if it appears that the pool is active.
|
||||
* -f Force import, even if it appears that the pool is active.
|
||||
*
|
||||
* -F Attempt rewind if necessary.
|
||||
* -F Attempt rewind if necessary.
|
||||
*
|
||||
* -n See if rewind would work, but don't actually rewind.
|
||||
* -n See if rewind would work, but don't actually rewind.
|
||||
*
|
||||
* -N Import the pool but don't mount datasets.
|
||||
* -N Import the pool but don't mount datasets.
|
||||
*
|
||||
* -T Specify a starting txg to use for import. This option is
|
||||
* intentionally undocumented option for testing purposes.
|
||||
* -T Specify a starting txg to use for import. This option is
|
||||
* intentionally undocumented option for testing purposes.
|
||||
*
|
||||
* -a Import all pools found.
|
||||
* -a Import all pools found.
|
||||
*
|
||||
* -l Load encryption keys while importing.
|
||||
* -l Load encryption keys while importing.
|
||||
*
|
||||
* -o Set property=value and/or temporary mount options (without '=').
|
||||
* -o Set property=value and/or temporary mount options (without '=').
|
||||
*
|
||||
* -s Scan using the default search path, the libblkid cache will
|
||||
* not be consulted.
|
||||
* -s Scan using the default search path, the libblkid cache will
|
||||
* not be consulted.
|
||||
*
|
||||
* --rewind-to-checkpoint
|
||||
* Import the pool and revert back to the checkpoint.
|
||||
* --rewind-to-checkpoint
|
||||
* Import the pool and revert back to the checkpoint.
|
||||
*
|
||||
* The import command scans for pools to import, and import pools based on pool
|
||||
* name and GUID. The pool can also be renamed as part of the import process.
|
||||
@ -3309,15 +3435,11 @@ zpool_do_import(int argc, char **argv)
|
||||
boolean_t do_all = B_FALSE;
|
||||
boolean_t do_destroyed = B_FALSE;
|
||||
char *mntopts = NULL;
|
||||
nvpair_t *elem;
|
||||
nvlist_t *config;
|
||||
uint64_t searchguid = 0;
|
||||
char *searchname = NULL;
|
||||
char *propval;
|
||||
nvlist_t *found_config;
|
||||
nvlist_t *policy = NULL;
|
||||
nvlist_t *props = NULL;
|
||||
boolean_t first;
|
||||
int flags = ZFS_IMPORT_NORMAL;
|
||||
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
||||
boolean_t dryrun = B_FALSE;
|
||||
@ -3325,7 +3447,8 @@ zpool_do_import(int argc, char **argv)
|
||||
boolean_t xtreme_rewind = B_FALSE;
|
||||
boolean_t do_scan = B_FALSE;
|
||||
boolean_t pool_exists = B_FALSE;
|
||||
uint64_t pool_state, txg = -1ULL;
|
||||
boolean_t pool_specified = B_FALSE;
|
||||
uint64_t txg = -1ULL;
|
||||
char *cachefile = NULL;
|
||||
importargs_t idata = { 0 };
|
||||
char *endptr;
|
||||
@ -3447,6 +3570,11 @@ zpool_do_import(int argc, char **argv)
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (cachefile && do_scan) {
|
||||
(void) fprintf(stderr, gettext("-c is incompatible with -s\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) {
|
||||
(void) fprintf(stderr, gettext("-l is incompatible with -N\n"));
|
||||
usage(B_FALSE);
|
||||
@ -3527,7 +3655,7 @@ zpool_do_import(int argc, char **argv)
|
||||
searchname = argv[0];
|
||||
searchguid = 0;
|
||||
}
|
||||
found_config = NULL;
|
||||
pool_specified = B_TRUE;
|
||||
|
||||
/*
|
||||
* User specified a name or guid. Ensure it's unique.
|
||||
@ -3606,98 +3734,33 @@ zpool_do_import(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
|
||||
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||
do_all, &idata);
|
||||
|
||||
/*
|
||||
* At this point we have a list of import candidate configs. Even if
|
||||
* we were searching by pool name or guid, we still need to
|
||||
* post-process the list to deal with pool state and possible
|
||||
* duplicate names.
|
||||
* If we're using the cachefile and we failed to import, then
|
||||
* fallback to scanning the directory for pools that match
|
||||
* those in the cachefile.
|
||||
*/
|
||||
err = 0;
|
||||
elem = NULL;
|
||||
first = B_TRUE;
|
||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
|
||||
if (err != 0 && cachefile != NULL) {
|
||||
(void) printf(gettext("cachefile import failed, retrying\n"));
|
||||
|
||||
verify(nvpair_value_nvlist(elem, &config) == 0);
|
||||
/*
|
||||
* We use the scan flag to gather the directories that exist
|
||||
* in the cachefile. If we need to fallback to searching for
|
||||
* the pool config, we will only search devices in these
|
||||
* directories.
|
||||
*/
|
||||
idata.scan = B_TRUE;
|
||||
nvlist_free(pools);
|
||||
pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
|
||||
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||
&pool_state) == 0);
|
||||
if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
|
||||
continue;
|
||||
|
||||
verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
|
||||
policy) == 0);
|
||||
|
||||
if (argc == 0) {
|
||||
if (first)
|
||||
first = B_FALSE;
|
||||
else if (!do_all)
|
||||
(void) printf("\n");
|
||||
|
||||
if (do_all) {
|
||||
err |= do_import(config, NULL, mntopts,
|
||||
props, flags);
|
||||
} else {
|
||||
show_import(config);
|
||||
}
|
||||
} else if (searchname != NULL) {
|
||||
char *name;
|
||||
|
||||
/*
|
||||
* We are searching for a pool based on name.
|
||||
*/
|
||||
verify(nvlist_lookup_string(config,
|
||||
ZPOOL_CONFIG_POOL_NAME, &name) == 0);
|
||||
|
||||
if (strcmp(name, searchname) == 0) {
|
||||
if (found_config != NULL) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"cannot import '%s': more than "
|
||||
"one matching pool\n"), searchname);
|
||||
(void) fprintf(stderr, gettext(
|
||||
"import by numeric ID instead\n"));
|
||||
err = B_TRUE;
|
||||
}
|
||||
found_config = config;
|
||||
}
|
||||
} else {
|
||||
uint64_t guid;
|
||||
|
||||
/*
|
||||
* Search for a pool by guid.
|
||||
*/
|
||||
verify(nvlist_lookup_uint64(config,
|
||||
ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
|
||||
|
||||
if (guid == searchguid)
|
||||
found_config = config;
|
||||
}
|
||||
err = import_pools(pools, props, mntopts, flags, argv[0],
|
||||
argc == 1 ? NULL : argv[1], do_destroyed, pool_specified,
|
||||
do_all, &idata);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were searching for a specific pool, verify that we found a
|
||||
* pool, and then do the import.
|
||||
*/
|
||||
if (argc != 0 && err == 0) {
|
||||
if (found_config == NULL) {
|
||||
(void) fprintf(stderr, gettext("cannot import '%s': "
|
||||
"no such pool available\n"), argv[0]);
|
||||
err = B_TRUE;
|
||||
} else {
|
||||
err |= do_import(found_config, argc == 1 ? NULL :
|
||||
argv[1], mntopts, props, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were just looking for pools, report an error if none were
|
||||
* found.
|
||||
*/
|
||||
if (argc == 0 && first)
|
||||
(void) fprintf(stderr,
|
||||
gettext("no pools available to import\n"));
|
||||
|
||||
error:
|
||||
nvlist_free(props);
|
||||
nvlist_free(pools);
|
||||
@ -7785,8 +7848,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
|
||||
* do not print estimated time if hours_left is more than
|
||||
* 30 days
|
||||
*/
|
||||
(void) printf(gettext(" %s copied out of %s at %s/s, "
|
||||
"%.2f%% done"),
|
||||
(void) printf(gettext(
|
||||
"\t%s copied out of %s at %s/s, %.2f%% done"),
|
||||
examined_buf, total_buf, rate_buf, 100 * fraction_done);
|
||||
if (hours_left < (30 * 24)) {
|
||||
(void) printf(gettext(", %lluh%um to go\n"),
|
||||
@ -7801,8 +7864,8 @@ print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs)
|
||||
if (prs->prs_mapping_memory > 0) {
|
||||
char mem_buf[7];
|
||||
zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf));
|
||||
(void) printf(gettext(" %s memory used for "
|
||||
"removed device mappings\n"),
|
||||
(void) printf(gettext(
|
||||
"\t%s memory used for removed device mappings\n"),
|
||||
mem_buf);
|
||||
}
|
||||
}
|
||||
|
@ -248,6 +248,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
|
||||
fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
|
||||
fflags &= ~(DMU_BACKUP_FEATURE_DEDUP |
|
||||
DMU_BACKUP_FEATURE_DEDUPPROPS);
|
||||
/* cppcheck-suppress syntaxError */
|
||||
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
|
||||
|
||||
int sz = drr->drr_payloadlen;
|
||||
|
@ -11,6 +11,7 @@ AC_DEFUN([ZFS_AC_DEBUG_ENABLE], [
|
||||
DEBUG_CPPFLAGS="-DDEBUG -UNDEBUG"
|
||||
DEBUG_LDFLAGS=""
|
||||
DEBUG_ZFS="_with_debug"
|
||||
WITH_DEBUG="true"
|
||||
AC_DEFINE(ZFS_DEBUG, 1, [zfs debugging enabled])
|
||||
|
||||
KERNEL_DEBUG_CFLAGS="-Werror"
|
||||
@ -22,6 +23,7 @@ AC_DEFUN([ZFS_AC_DEBUG_DISABLE], [
|
||||
DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG"
|
||||
DEBUG_LDFLAGS=""
|
||||
DEBUG_ZFS="_without_debug"
|
||||
WITH_DEBUG=""
|
||||
|
||||
KERNEL_DEBUG_CFLAGS=""
|
||||
KERNEL_DEBUG_CPPFLAGS="-UDEBUG -DNDEBUG"
|
||||
@ -51,6 +53,7 @@ AC_DEFUN([ZFS_AC_DEBUG], [
|
||||
AC_SUBST(DEBUG_CPPFLAGS)
|
||||
AC_SUBST(DEBUG_LDFLAGS)
|
||||
AC_SUBST(DEBUG_ZFS)
|
||||
AC_SUBST(WITH_DEBUG)
|
||||
|
||||
AC_SUBST(KERNEL_DEBUG_CFLAGS)
|
||||
AC_SUBST(KERNEL_DEBUG_CPPFLAGS)
|
||||
@ -152,6 +155,39 @@ AC_DEFUN([ZFS_AC_DEBUG_KMEM_TRACKING], [
|
||||
AC_MSG_RESULT([$enable_debug_kmem_tracking])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD], [
|
||||
AS_IF([sysctl -n kern.conftxt | fgrep -qx $'options\tINVARIANTS'],
|
||||
[enable_invariants="yes"],
|
||||
[enable_invariants="no"])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS_DETECT], [
|
||||
AM_COND_IF([BUILD_FREEBSD],
|
||||
[ZFS_AC_DEBUG_INVARIANTS_DETECT_FREEBSD],
|
||||
[enable_invariants="no"])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Detected for the running kernel by default, enables INVARIANTS features
|
||||
dnl # in the FreeBSD kernel module. This feature must be used when building
|
||||
dnl # for a FreeBSD kernel with "options INVARIANTS" in the KERNCONF and must
|
||||
dnl # not be used when the INVARIANTS option is absent.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_DEBUG_INVARIANTS], [
|
||||
AC_MSG_CHECKING([whether FreeBSD kernel INVARIANTS checks are enabled])
|
||||
AC_ARG_ENABLE([invariants],
|
||||
[AS_HELP_STRING([--enable-invariants],
|
||||
[Enable FreeBSD kernel INVARIANTS checks [[default: detect]]])],
|
||||
[], [ZFS_AC_DEBUG_INVARIANTS_DETECT])
|
||||
|
||||
AS_IF([test "x$enable_invariants" = xyes],
|
||||
[WITH_INVARIANTS="true"],
|
||||
[WITH_INVARIANTS=""])
|
||||
AC_SUBST(WITH_INVARIANTS)
|
||||
|
||||
AC_MSG_RESULT([$enable_invariants])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
|
||||
AX_COUNT_CPUS([])
|
||||
AC_SUBST(CPU_COUNT)
|
||||
|
@ -61,6 +61,7 @@ ZFS_AC_DEBUG
|
||||
ZFS_AC_DEBUGINFO
|
||||
ZFS_AC_DEBUG_KMEM
|
||||
ZFS_AC_DEBUG_KMEM_TRACKING
|
||||
ZFS_AC_DEBUG_INVARIANTS
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
|
@ -4,6 +4,7 @@ KERNEL_H = \
|
||||
atomic.h \
|
||||
byteorder.h \
|
||||
callb.h \
|
||||
ccompat.h \
|
||||
ccompile.h \
|
||||
cmn_err.h \
|
||||
condvar.h \
|
||||
@ -18,9 +19,11 @@ KERNEL_H = \
|
||||
fcntl.h \
|
||||
file.h \
|
||||
freebsd_rwlock.h \
|
||||
idmap.h \
|
||||
inttypes.h \
|
||||
isa_defs.h \
|
||||
kmem_cache.h \
|
||||
kidmap.h \
|
||||
kmem.h \
|
||||
kstat.h \
|
||||
list_impl.h \
|
||||
|
@ -68,65 +68,65 @@ void spl_dumpstack(void);
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s", "VERIFY(" #cond ") failed\n"))
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT);\
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%d " #OP " %d)\n", \
|
||||
(boolean_t) (_verify3_left), \
|
||||
(boolean_t) (_verify3_right)); \
|
||||
"failed (%d " #OP " %d)\n", \
|
||||
(boolean_t) (_verify3_left), \
|
||||
(boolean_t) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||
int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%lld " #OP " %lld)\n", \
|
||||
(long long) (_verify3_left), \
|
||||
(long long) (_verify3_right)); \
|
||||
"failed (%lld " #OP " %lld)\n", \
|
||||
(long long) (_verify3_left), \
|
||||
(long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||
uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%llu " #OP " %llu)\n", \
|
||||
(unsigned long long) (_verify3_left), \
|
||||
(unsigned long long) (_verify3_right)); \
|
||||
"failed (%llu " #OP " %llu)\n", \
|
||||
(unsigned long long) (_verify3_left), \
|
||||
(unsigned long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||
uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT);\
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%px " #OP " %px)\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right)); \
|
||||
"failed (%px " #OP " %px)\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0(RIGHT) do { \
|
||||
int64_t _verify3_left = (int64_t)(0); \
|
||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (!(_verify3_left == _verify3_right)) \
|
||||
#define VERIFY0(RIGHT) do { \
|
||||
const int64_t _verify3_left = (int64_t)(0); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld)\n", \
|
||||
(long long) (_verify3_right)); \
|
||||
"VERIFY3(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld)\n", \
|
||||
(long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
#define CTASSERT_GLOBAL(x) CTASSERT(x)
|
||||
#define CTASSERT_GLOBAL(x) CTASSERT(x)
|
||||
|
||||
/*
|
||||
* Debugging disabled (--disable-debug)
|
||||
@ -154,11 +154,11 @@ void spl_dumpstack(void);
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(((!(A)) || (B)) || \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") implies (" #B ")")))
|
||||
#define EQUIV(A, B) \
|
||||
((void)((!!(A) == !!(B)) || \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") is equivalent to (" #B ")")))
|
||||
/* END CSTYLED */
|
||||
|
@ -27,7 +27,7 @@
|
||||
#ifndef _SYS_FS_ZFS_VFSOPS_H
|
||||
#define _SYS_FS_ZFS_VFSOPS_H
|
||||
|
||||
#if __FreeBSD_version >= 1300109
|
||||
#if __FreeBSD_version >= 1300125
|
||||
#define TEARDOWN_RMS
|
||||
#endif
|
||||
|
||||
|
@ -62,63 +62,63 @@ void spl_dumpstack(void);
|
||||
#define PANIC(fmt, a...) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
|
||||
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
#define VERIFY(cond) \
|
||||
(void) (unlikely(!(cond)) && \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s", "VERIFY(" #cond ") failed\n"))
|
||||
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
boolean_t _verify3_right = (boolean_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3B(LEFT, OP, RIGHT) do { \
|
||||
const boolean_t _verify3_left = (boolean_t)(LEFT); \
|
||||
const boolean_t _verify3_right = (boolean_t)(RIGHT);\
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%d " #OP " %d)\n", \
|
||||
(boolean_t) (_verify3_left), \
|
||||
(boolean_t) (_verify3_right)); \
|
||||
"failed (%d " #OP " %d)\n", \
|
||||
(boolean_t) (_verify3_left), \
|
||||
(boolean_t) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||
int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3S(LEFT, OP, RIGHT) do { \
|
||||
const int64_t _verify3_left = (int64_t)(LEFT); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%lld " #OP " %lld)\n", \
|
||||
(long long) (_verify3_left), \
|
||||
(long long) (_verify3_right)); \
|
||||
"failed (%lld " #OP " %lld)\n", \
|
||||
(long long) (_verify3_left), \
|
||||
(long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||
uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3U(LEFT, OP, RIGHT) do { \
|
||||
const uint64_t _verify3_left = (uint64_t)(LEFT); \
|
||||
const uint64_t _verify3_right = (uint64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%llu " #OP " %llu)\n", \
|
||||
(unsigned long long) (_verify3_left), \
|
||||
(unsigned long long) (_verify3_right)); \
|
||||
"failed (%llu " #OP " %llu)\n", \
|
||||
(unsigned long long) (_verify3_left), \
|
||||
(unsigned long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||
uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
uintptr_t _verify3_right = (uintptr_t)(RIGHT); \
|
||||
if (!(_verify3_left OP _verify3_right)) \
|
||||
#define VERIFY3P(LEFT, OP, RIGHT) do { \
|
||||
const uintptr_t _verify3_left = (uintptr_t)(LEFT); \
|
||||
const uintptr_t _verify3_right = (uintptr_t)(RIGHT);\
|
||||
if (unlikely(!(_verify3_left OP _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(" #LEFT " " #OP " " #RIGHT ") " \
|
||||
"failed (%px " #OP " %px)\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right)); \
|
||||
"failed (%px " #OP " %px)\n", \
|
||||
(void *) (_verify3_left), \
|
||||
(void *) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define VERIFY0(RIGHT) do { \
|
||||
int64_t _verify3_left = (int64_t)(0); \
|
||||
int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (!(_verify3_left == _verify3_right)) \
|
||||
#define VERIFY0(RIGHT) do { \
|
||||
const int64_t _verify3_left = (int64_t)(0); \
|
||||
const int64_t _verify3_right = (int64_t)(RIGHT); \
|
||||
if (unlikely(!(_verify3_left == _verify3_right))) \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"VERIFY3(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld)\n", \
|
||||
(long long) (_verify3_right)); \
|
||||
"VERIFY3(0 == " #RIGHT ") " \
|
||||
"failed (0 == %lld)\n", \
|
||||
(long long) (_verify3_right)); \
|
||||
} while (0)
|
||||
|
||||
#define CTASSERT_GLOBAL(x) _CTASSERT(x, __LINE__)
|
||||
@ -154,11 +154,11 @@ void spl_dumpstack(void);
|
||||
#define ASSERT0 VERIFY0
|
||||
#define ASSERT VERIFY
|
||||
#define IMPLY(A, B) \
|
||||
((void)(((!(A)) || (B)) || \
|
||||
((void)(likely((!(A)) || (B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") implies (" #B ")")))
|
||||
#define EQUIV(A, B) \
|
||||
((void)((!!(A) == !!(B)) || \
|
||||
((void)(likely(!!(A) == !!(B)) || \
|
||||
spl_panic(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"(" #A ") is equivalent to (" #B ")")))
|
||||
/* END CSTYLED */
|
||||
|
@ -138,6 +138,39 @@ struct zfsvfs {
|
||||
taskqid_t z_drain_task; /* task id for the unlink drain task */
|
||||
};
|
||||
|
||||
#define ZFS_TEARDOWN_INIT(zfsvfs) \
|
||||
rrm_init(&(zfsvfs)->z_teardown_lock, B_FALSE)
|
||||
|
||||
#define ZFS_TEARDOWN_DESTROY(zfsvfs) \
|
||||
rrm_destroy(&(zfsvfs)->z_teardown_lock)
|
||||
|
||||
#define ZFS_TEARDOWN_TRY_ENTER_READ(zfsvfs) \
|
||||
rw_tryenter(&(zfsvfs)->z_teardown_lock, RW_READER)
|
||||
|
||||
#define ZFS_TEARDOWN_ENTER_READ(zfsvfs, tag) \
|
||||
rrm_enter_read(&(zfsvfs)->z_teardown_lock, tag);
|
||||
|
||||
#define ZFS_TEARDOWN_EXIT_READ(zfsvfs, tag) \
|
||||
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||
|
||||
#define ZFS_TEARDOWN_ENTER_WRITE(zfsvfs, tag) \
|
||||
rrm_enter(&(zfsvfs)->z_teardown_lock, RW_WRITER, tag)
|
||||
|
||||
#define ZFS_TEARDOWN_EXIT_WRITE(zfsvfs) \
|
||||
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||
|
||||
#define ZFS_TEARDOWN_EXIT(zfsvfs, tag) \
|
||||
rrm_exit(&(zfsvfs)->z_teardown_lock, tag)
|
||||
|
||||
#define ZFS_TEARDOWN_READ_HELD(zfsvfs) \
|
||||
RRM_READ_HELD(&(zfsvfs)->z_teardown_lock)
|
||||
|
||||
#define ZFS_TEARDOWN_WRITE_HELD(zfsvfs) \
|
||||
RRM_WRITE_HELD(&(zfsvfs)->z_teardown_lock)
|
||||
|
||||
#define ZFS_TEARDOWN_HELD(zfsvfs) \
|
||||
RRM_LOCK_HELD(&(zfsvfs)->z_teardown_lock)
|
||||
|
||||
#define ZSB_XATTR 0x0001 /* Enable user xattrs */
|
||||
|
||||
/*
|
||||
|
@ -81,7 +81,7 @@ extern "C" {
|
||||
do { \
|
||||
ZFS_TEARDOWN_ENTER_READ(zfsvfs, FTAG); \
|
||||
if (unlikely((zfsvfs)->z_unmounted)) { \
|
||||
ZFS_EXIT_READ(zfsvfs, FTAG); \
|
||||
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
||||
return (error); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -92,7 +92,7 @@ do { \
|
||||
#define ZFS_EXIT(zfsvfs) \
|
||||
do { \
|
||||
zfs_exit_fs(zfsvfs); \
|
||||
ZFS_EXIT_READ(zfsvfs, FTAG); \
|
||||
ZFS_TEARDOWN_EXIT_READ(zfsvfs, FTAG); \
|
||||
} while (0)
|
||||
|
||||
#define ZPL_EXIT(zfsvfs) \
|
||||
|
@ -39,6 +39,7 @@ redact_block_get_size(redact_block_phys_t *rbp)
|
||||
static inline void
|
||||
redact_block_set_size(redact_block_phys_t *rbp, uint64_t size)
|
||||
{
|
||||
/* cppcheck-suppress syntaxError */
|
||||
BF64_SET_SB((rbp)->rbp_size_count, 48, 16, SPA_MINBLOCKSHIFT, 0, size);
|
||||
}
|
||||
|
||||
@ -51,6 +52,7 @@ redact_block_get_count(redact_block_phys_t *rbp)
|
||||
static inline void
|
||||
redact_block_set_count(redact_block_phys_t *rbp, uint64_t count)
|
||||
{
|
||||
/* cppcheck-suppress syntaxError */
|
||||
BF64_SET_SB((rbp)->rbp_size_count, 0, 48, 0, 1, count);
|
||||
}
|
||||
|
||||
|
@ -525,7 +525,6 @@ typedef struct zfs_useracct {
|
||||
} zfs_useracct_t;
|
||||
|
||||
#define ZFSDEV_MAX_MINOR (1 << 16)
|
||||
#define ZFS_MIN_MINOR (ZFSDEV_MAX_MINOR + 1)
|
||||
|
||||
#define ZPOOL_EXPORT_AFTER_SPLIT 0x1
|
||||
|
||||
|
@ -532,6 +532,8 @@ get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey,
|
||||
|
||||
break;
|
||||
case ZFS_KEYLOCATION_URI:
|
||||
ret = ENOTSUP;
|
||||
|
||||
for (handler = uri_handlers; handler->zuh_scheme != NULL;
|
||||
handler++) {
|
||||
if (strcmp(handler->zuh_scheme, uri_scheme) != 0)
|
||||
@ -544,9 +546,11 @@ get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey,
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ENOTSUP;
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"URI scheme is not supported"));
|
||||
if (ret == ENOTSUP) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"URI scheme is not supported"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014, 2021 by Delphix. All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright 2017 RackTop Systems.
|
||||
* Copyright (c) 2018 Datto Inc.
|
||||
@ -553,7 +553,28 @@ unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
|
||||
|
||||
error = do_unmount(mountpoint, flags);
|
||||
if (error != 0) {
|
||||
return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED,
|
||||
int libzfs_err;
|
||||
|
||||
switch (error) {
|
||||
case EBUSY:
|
||||
libzfs_err = EZFS_BUSY;
|
||||
break;
|
||||
case EIO:
|
||||
libzfs_err = EZFS_IO;
|
||||
break;
|
||||
case ENOENT:
|
||||
libzfs_err = EZFS_NOENT;
|
||||
break;
|
||||
case ENOMEM:
|
||||
libzfs_err = EZFS_NOMEM;
|
||||
break;
|
||||
case EPERM:
|
||||
libzfs_err = EZFS_PERM;
|
||||
break;
|
||||
default:
|
||||
libzfs_err = EZFS_UMOUNTFAILED;
|
||||
}
|
||||
return (zfs_error_fmt(hdl, libzfs_err,
|
||||
dgettext(TEXT_DOMAIN, "cannot unmount '%s'"),
|
||||
mountpoint));
|
||||
}
|
||||
|
@ -128,8 +128,9 @@ do_mount(zfs_handle_t *zhp, const char *mntpt, char *opts, int flags)
|
||||
int
|
||||
do_unmount(const char *mntpt, int flags)
|
||||
{
|
||||
|
||||
return (unmount(mntpt, flags));
|
||||
if (unmount(mntpt, flags) < 0)
|
||||
return (errno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2014, 2021 by Delphix. All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
|
||||
* Copyright 2017 RackTop Systems.
|
||||
* Copyright (c) 2018 Datto Inc.
|
||||
@ -377,7 +377,9 @@ int
|
||||
do_unmount(const char *mntpt, int flags)
|
||||
{
|
||||
if (!libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) {
|
||||
return (umount2(mntpt, flags));
|
||||
int rv = umount2(mntpt, flags);
|
||||
|
||||
return (rv < 0 ? errno : 0);
|
||||
}
|
||||
|
||||
char force_opt[] = "-f";
|
||||
|
@ -1269,7 +1269,8 @@ zpool_find_import_scan(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||
* to import a specific pool.
|
||||
*/
|
||||
static nvlist_t *
|
||||
zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg,
|
||||
pthread_mutex_t *lock, avl_tree_t *cache)
|
||||
{
|
||||
nvlist_t *ret = NULL;
|
||||
pool_list_t pools = { 0 };
|
||||
@ -1277,34 +1278,11 @@ zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
vdev_entry_t *ve, *venext;
|
||||
config_entry_t *ce, *cenext;
|
||||
name_entry_t *ne, *nenext;
|
||||
pthread_mutex_t lock;
|
||||
avl_tree_t *cache;
|
||||
rdsk_node_t *slice;
|
||||
void *cookie;
|
||||
tpool_t *t;
|
||||
|
||||
verify(iarg->poolname == NULL || iarg->guid == 0);
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
/*
|
||||
* Locate pool member vdevs by blkid or by directory scanning.
|
||||
* On success a newly allocated AVL tree which is populated with an
|
||||
* entry for each discovered vdev will be returned in the cache.
|
||||
* It's the caller's responsibility to consume and destroy this tree.
|
||||
*/
|
||||
if (iarg->scan || iarg->paths != 0) {
|
||||
size_t dirs = iarg->paths;
|
||||
const char * const *dir = (const char * const *)iarg->path;
|
||||
|
||||
if (dirs == 0)
|
||||
dir = zpool_default_search_paths(&dirs);
|
||||
|
||||
if (zpool_find_import_scan(hdl, &lock, &cache, dir, dirs) != 0)
|
||||
return (NULL);
|
||||
} else {
|
||||
if (zpool_find_import_blkid(hdl, &lock, &cache) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a thread pool to parallelize the process of reading and
|
||||
@ -1384,7 +1362,6 @@ zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
}
|
||||
avl_destroy(cache);
|
||||
free(cache);
|
||||
pthread_mutex_destroy(&lock);
|
||||
|
||||
ret = get_configs(hdl, &pools, iarg->can_be_active, iarg->policy);
|
||||
|
||||
@ -1411,14 +1388,43 @@ zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a config, discover the paths for the devices which
|
||||
* exist in the config.
|
||||
*/
|
||||
static int
|
||||
discover_cached_paths(libpc_handle_t *hdl, nvlist_t *nv,
|
||||
avl_tree_t *cache, pthread_mutex_t *lock)
|
||||
{
|
||||
char *path = NULL;
|
||||
uint_t children;
|
||||
nvlist_t **child;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) == 0) {
|
||||
for (int c = 0; c < children; c++) {
|
||||
discover_cached_paths(hdl, child[c], cache, lock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Once we have the path, we need to add the directory to
|
||||
* our directoy cache.
|
||||
*/
|
||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
|
||||
return (zpool_find_import_scan_dir(hdl, lock, cache,
|
||||
dirname(path), 0));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a cache file, return the contents as a list of importable pools.
|
||||
* poolname or guid (but not both) are provided by the caller when trying
|
||||
* to import a specific pool.
|
||||
*/
|
||||
static nvlist_t *
|
||||
zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile,
|
||||
const char *poolname, uint64_t guid)
|
||||
zpool_find_import_cached(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
{
|
||||
char *buf;
|
||||
int fd;
|
||||
@ -1430,9 +1436,9 @@ zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile,
|
||||
uint64_t this_guid;
|
||||
boolean_t active;
|
||||
|
||||
verify(poolname == NULL || guid == 0);
|
||||
verify(iarg->poolname == NULL || iarg->guid == 0);
|
||||
|
||||
if ((fd = open(cachefile, O_RDONLY)) < 0) {
|
||||
if ((fd = open(iarg->cachefile, O_RDONLY)) < 0) {
|
||||
zutil_error_aux(hdl, "%s", strerror(errno));
|
||||
(void) zutil_error(hdl, EZFS_BADCACHE,
|
||||
dgettext(TEXT_DOMAIN, "failed to open cache file"));
|
||||
@ -1488,11 +1494,11 @@ zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile,
|
||||
src = fnvpair_value_nvlist(elem);
|
||||
|
||||
name = fnvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME);
|
||||
if (poolname != NULL && strcmp(poolname, name) != 0)
|
||||
if (iarg->poolname != NULL && strcmp(iarg->poolname, name) != 0)
|
||||
continue;
|
||||
|
||||
this_guid = fnvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID);
|
||||
if (guid != 0 && guid != this_guid)
|
||||
if (iarg->guid != 0 && iarg->guid != this_guid)
|
||||
continue;
|
||||
|
||||
if (zutil_pool_active(hdl, name, this_guid, &active) != 0) {
|
||||
@ -1504,8 +1510,68 @@ zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile,
|
||||
if (active)
|
||||
continue;
|
||||
|
||||
if (iarg->scan) {
|
||||
uint64_t saved_guid = iarg->guid;
|
||||
const char *saved_poolname = iarg->poolname;
|
||||
pthread_mutex_t lock;
|
||||
|
||||
/*
|
||||
* Create the device cache that will hold the
|
||||
* devices we will scan based on the cachefile.
|
||||
* This will get destroyed and freed by
|
||||
* zpool_find_import_impl.
|
||||
*/
|
||||
avl_tree_t *cache = zutil_alloc(hdl,
|
||||
sizeof (avl_tree_t));
|
||||
avl_create(cache, slice_cache_compare,
|
||||
sizeof (rdsk_node_t),
|
||||
offsetof(rdsk_node_t, rn_node));
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(src,
|
||||
ZPOOL_CONFIG_VDEV_TREE);
|
||||
|
||||
/*
|
||||
* We only want to find the pool with this_guid.
|
||||
* We will reset these values back later.
|
||||
*/
|
||||
iarg->guid = this_guid;
|
||||
iarg->poolname = NULL;
|
||||
|
||||
/*
|
||||
* We need to build up a cache of devices that exists
|
||||
* in the paths pointed to by the cachefile. This allows
|
||||
* us to preserve the device namespace that was
|
||||
* originally specified by the user but also lets us
|
||||
* scan devices in those directories in case they had
|
||||
* been renamed.
|
||||
*/
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
discover_cached_paths(hdl, nvroot, cache, &lock);
|
||||
nvlist_t *nv = zpool_find_import_impl(hdl, iarg,
|
||||
&lock, cache);
|
||||
pthread_mutex_destroy(&lock);
|
||||
|
||||
/*
|
||||
* zpool_find_import_impl will return back
|
||||
* a list of pools that it found based on the
|
||||
* device cache. There should only be one pool
|
||||
* since we're looking for a specific guid.
|
||||
* We will use that pool to build up the final
|
||||
* pool nvlist which is returned back to the
|
||||
* caller.
|
||||
*/
|
||||
nvpair_t *pair = nvlist_next_nvpair(nv, NULL);
|
||||
fnvlist_add_nvlist(pools, nvpair_name(pair),
|
||||
fnvpair_value_nvlist(pair));
|
||||
|
||||
VERIFY3P(nvlist_next_nvpair(nv, pair), ==, NULL);
|
||||
|
||||
iarg->guid = saved_guid;
|
||||
iarg->poolname = saved_poolname;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nvlist_add_string(src, ZPOOL_CONFIG_CACHEFILE,
|
||||
cachefile) != 0) {
|
||||
iarg->cachefile) != 0) {
|
||||
(void) zutil_no_memory(hdl);
|
||||
nvlist_free(raw);
|
||||
nvlist_free(pools);
|
||||
@ -1527,11 +1593,51 @@ zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile,
|
||||
}
|
||||
nvlist_free(dst);
|
||||
}
|
||||
|
||||
nvlist_free(raw);
|
||||
return (pools);
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
zpool_find_import(libpc_handle_t *hdl, importargs_t *iarg)
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
avl_tree_t *cache;
|
||||
nvlist_t *pools = NULL;
|
||||
|
||||
verify(iarg->poolname == NULL || iarg->guid == 0);
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
/*
|
||||
* Locate pool member vdevs by blkid or by directory scanning.
|
||||
* On success a newly allocated AVL tree which is populated with an
|
||||
* entry for each discovered vdev will be returned in the cache.
|
||||
* It's the caller's responsibility to consume and destroy this tree.
|
||||
*/
|
||||
if (iarg->scan || iarg->paths != 0) {
|
||||
size_t dirs = iarg->paths;
|
||||
const char * const *dir = (const char * const *)iarg->path;
|
||||
|
||||
if (dirs == 0)
|
||||
dir = zpool_default_search_paths(&dirs);
|
||||
|
||||
if (zpool_find_import_scan(hdl, &lock, &cache,
|
||||
dir, dirs) != 0) {
|
||||
pthread_mutex_destroy(&lock);
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
if (zpool_find_import_blkid(hdl, &lock, &cache) != 0) {
|
||||
pthread_mutex_destroy(&lock);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
pools = zpool_find_import_impl(hdl, iarg, &lock, cache);
|
||||
pthread_mutex_destroy(&lock);
|
||||
return (pools);
|
||||
}
|
||||
|
||||
|
||||
nvlist_t *
|
||||
zpool_search_import(void *hdl, importargs_t *import,
|
||||
const pool_config_ops_t *pco)
|
||||
@ -1546,10 +1652,9 @@ zpool_search_import(void *hdl, importargs_t *import,
|
||||
verify(import->poolname == NULL || import->guid == 0);
|
||||
|
||||
if (import->cachefile != NULL)
|
||||
pools = zpool_find_import_cached(&handle, import->cachefile,
|
||||
import->poolname, import->guid);
|
||||
pools = zpool_find_import_cached(&handle, import);
|
||||
else
|
||||
pools = zpool_find_import_impl(&handle, import);
|
||||
pools = zpool_find_import(&handle, import);
|
||||
|
||||
if ((pools == NULL || nvlist_empty(pools)) &&
|
||||
handle.lpc_open_access_error && geteuid() != 0) {
|
||||
|
@ -261,6 +261,16 @@ causes the property to be inherited by all descendant datasets, as through
|
||||
was run on any descendant datasets that have this property set on the
|
||||
sending system.
|
||||
.Pp
|
||||
If the send stream was sent with
|
||||
.Fl c
|
||||
then overriding the
|
||||
.Sy compression
|
||||
property will have no affect on received data but the
|
||||
.Sy compression
|
||||
property will be set. To have the data recompressed on receive remove the
|
||||
.Fl c
|
||||
flag from the send stream.
|
||||
.Pp
|
||||
Any editable property can be set at receive time. Set-once properties bound
|
||||
to the received data, such as
|
||||
.Sy normalization
|
||||
|
@ -189,7 +189,12 @@ feature is enabled on the sending system but the
|
||||
option is not supplied in conjunction with
|
||||
.Fl c ,
|
||||
then the data will be decompressed before sending so it can be split into
|
||||
smaller block sizes.
|
||||
smaller block sizes. Streams sent with
|
||||
.Fl c
|
||||
will not have their data recompressed on the receiver side using
|
||||
.Fl o compress=value.
|
||||
The data will stay compressed as it was from the sender. The new compression
|
||||
property will be set for future data.
|
||||
.It Fl w, -raw
|
||||
For encrypted datasets, send data exactly as it exists on disk. This allows
|
||||
backups to be taken even if encryption keys are not currently loaded. The
|
||||
|
@ -17,6 +17,10 @@ check:
|
||||
modules_uninstall modules_uninstall-Linux modules_uninstall-FreeBSD \
|
||||
cppcheck cppcheck-Linux cppcheck-FreeBSD
|
||||
|
||||
# For FreeBSD, use debug options from ./configure if not overridden.
|
||||
export WITH_DEBUG ?= @WITH_DEBUG@
|
||||
export WITH_INVARIANTS ?= @WITH_INVARIANTS@
|
||||
|
||||
# Filter out options that FreeBSD make doesn't understand
|
||||
getflags = ( \
|
||||
set -- \
|
||||
@ -42,6 +46,7 @@ FMAKEFLAGS = -C @abs_srcdir@ -f Makefile.bsd $(shell $(getflags))
|
||||
ifneq (@abs_srcdir@,@abs_builddir@)
|
||||
FMAKEFLAGS += MAKEOBJDIR=@abs_builddir@
|
||||
endif
|
||||
|
||||
FMAKE = env -u MAKEFLAGS make $(FMAKEFLAGS)
|
||||
|
||||
modules-Linux:
|
||||
|
@ -182,23 +182,21 @@ zfsdev_ioctl(struct cdev *dev, ulong_t zcmd, caddr_t arg, int flag,
|
||||
static void
|
||||
zfsdev_close(void *data)
|
||||
{
|
||||
zfsdev_state_t *zs, *zsp = data;
|
||||
zfsdev_state_t *zs = data;
|
||||
|
||||
ASSERT(zs != NULL);
|
||||
|
||||
mutex_enter(&zfsdev_state_lock);
|
||||
for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
|
||||
if (zs == zsp)
|
||||
break;
|
||||
}
|
||||
if (zs == NULL || zs->zs_minor <= 0) {
|
||||
mutex_exit(&zfsdev_state_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(zs->zs_minor != 0);
|
||||
|
||||
zs->zs_minor = -1;
|
||||
zfs_onexit_destroy(zs->zs_onexit);
|
||||
zfs_zevent_destroy(zs->zs_zevent);
|
||||
mutex_exit(&zfsdev_state_lock);
|
||||
zs->zs_onexit = NULL;
|
||||
zs->zs_zevent = NULL;
|
||||
|
||||
mutex_exit(&zfsdev_state_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -209,7 +209,6 @@ zfs_dd_lookup(znode_t *dzp, znode_t **zpp)
|
||||
#ifdef ZFS_DEBUG
|
||||
if (zfsvfs->z_replay == B_FALSE)
|
||||
ASSERT_VOP_LOCKED(ZTOV(dzp), __func__);
|
||||
ASSERT(ZFS_TEARDOWN_READ_HELD(zfsvfs));
|
||||
#endif
|
||||
if (dzp->z_unlinked)
|
||||
return (ENOENT);
|
||||
@ -234,7 +233,6 @@ zfs_dirlook(znode_t *dzp, const char *name, znode_t **zpp)
|
||||
#ifdef ZFS_DEBUG
|
||||
if (zfsvfs->z_replay == B_FALSE)
|
||||
ASSERT_VOP_LOCKED(ZTOV(dzp), __func__);
|
||||
ASSERT(ZFS_TEARDOWN_READ_HELD(zfsvfs));
|
||||
#endif
|
||||
if (dzp->z_unlinked)
|
||||
return (SET_ERROR(ENOENT));
|
||||
|
@ -1163,6 +1163,9 @@ zvol_ensure_zilog(zvol_state_t *zv)
|
||||
zv->zv_zilog = zil_open(zv->zv_objset,
|
||||
zvol_get_data);
|
||||
zv->zv_flags |= ZVOL_WRITTEN_TO;
|
||||
/* replay / destroy done in zvol_create_minor_impl() */
|
||||
VERIFY0((zv->zv_zilog->zl_header->zh_flags &
|
||||
ZIL_REPLAY_NEEDED));
|
||||
}
|
||||
rw_downgrade(&zv->zv_suspend_lock);
|
||||
}
|
||||
@ -1387,12 +1390,16 @@ zvol_create_minor_impl(const char *name)
|
||||
zv->zv_volsize = volsize;
|
||||
zv->zv_objset = os;
|
||||
|
||||
ASSERT3P(zv->zv_zilog, ==, NULL);
|
||||
zv->zv_zilog = zil_open(os, zvol_get_data);
|
||||
if (spa_writeable(dmu_objset_spa(os))) {
|
||||
if (zil_replay_disable)
|
||||
zil_destroy(dmu_objset_zil(os), B_FALSE);
|
||||
zil_destroy(zv->zv_zilog, B_FALSE);
|
||||
else
|
||||
zil_replay(os, zv, zvol_replay_vector);
|
||||
}
|
||||
zil_close(zv->zv_zilog);
|
||||
zv->zv_zilog = NULL;
|
||||
ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL);
|
||||
dataset_kstats_create(&zv->zv_kstat, zv->zv_objset);
|
||||
|
||||
|
@ -2214,13 +2214,11 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
|
||||
}
|
||||
|
||||
/*
|
||||
* Only check for READONLY on non-directories.
|
||||
* Intentionally allow ZFS_READONLY through here.
|
||||
* See zfs_zaccess_common().
|
||||
*/
|
||||
if ((v4_mode & WRITE_MASK_DATA) &&
|
||||
((!S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
|
||||
(S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & ZFS_IMMUTABLE)))) {
|
||||
(zp->z_pflags & ZFS_IMMUTABLE)) {
|
||||
return (SET_ERROR(EPERM));
|
||||
}
|
||||
|
||||
@ -2434,6 +2432,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: ZFS_READONLY represents the "DOS R/O" attribute.
|
||||
* When that flag is set, we should behave as if write access
|
||||
* were not granted by anything in the ACL. In particular:
|
||||
* We _must_ allow writes after opening the file r/w, then
|
||||
* setting the DOS R/O attribute, and writing some more.
|
||||
* (Similar to how you can write after fchmod(fd, 0444).)
|
||||
*
|
||||
* Therefore ZFS_READONLY is ignored in the dataset check
|
||||
* above, and checked here as if part of the ACL check.
|
||||
* Also note: DOS R/O is ignored for directories.
|
||||
*/
|
||||
if ((v4_mode & WRITE_MASK_DATA) &&
|
||||
S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & ZFS_READONLY)) {
|
||||
return (SET_ERROR(EPERM));
|
||||
}
|
||||
|
||||
return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
|
||||
}
|
||||
|
||||
|
@ -1412,6 +1412,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
|
||||
nr_src = 1;
|
||||
nr_dst = 0;
|
||||
}
|
||||
bzero(dst, datalen);
|
||||
|
||||
/* find the start and end record of the log block */
|
||||
zilc = (zil_chain_t *)src;
|
||||
|
@ -56,12 +56,32 @@ struct zvol_state_os {
|
||||
taskq_t *zvol_taskq;
|
||||
static struct ida zvol_ida;
|
||||
|
||||
typedef struct zv_request {
|
||||
typedef struct zv_request_stack {
|
||||
zvol_state_t *zv;
|
||||
struct bio *bio;
|
||||
taskq_ent_t ent;
|
||||
} zv_request_t;
|
||||
|
||||
typedef struct zv_request_task {
|
||||
zv_request_t zvr;
|
||||
taskq_ent_t ent;
|
||||
} zv_request_task_t;
|
||||
|
||||
static zv_request_task_t *
|
||||
zv_request_task_create(zv_request_t zvr)
|
||||
{
|
||||
zv_request_task_t *task;
|
||||
task = kmem_alloc(sizeof (zv_request_task_t), KM_SLEEP);
|
||||
taskq_init_ent(&task->ent);
|
||||
task->zvr = zvr;
|
||||
return (task);
|
||||
}
|
||||
|
||||
static void
|
||||
zv_request_task_free(zv_request_task_t *task)
|
||||
{
|
||||
kmem_free(task, sizeof (*task));
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a path, return TRUE if path is a ZVOL.
|
||||
*/
|
||||
@ -80,9 +100,8 @@ zvol_is_zvol_impl(const char *path)
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_write(void *arg)
|
||||
zvol_write(zv_request_t *zvr)
|
||||
{
|
||||
zv_request_t *zvr = arg;
|
||||
struct bio *bio = zvr->bio;
|
||||
int error = 0;
|
||||
zfs_uio_t uio;
|
||||
@ -102,7 +121,6 @@ zvol_write(void *arg)
|
||||
if (uio.uio_resid == 0) {
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
BIO_END_IO(bio, 0);
|
||||
kmem_free(zvr, sizeof (zv_request_t));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -162,13 +180,19 @@ zvol_write(void *arg)
|
||||
blk_generic_end_io_acct(q, disk, WRITE, bio, start_time);
|
||||
|
||||
BIO_END_IO(bio, -error);
|
||||
kmem_free(zvr, sizeof (zv_request_t));
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_discard(void *arg)
|
||||
zvol_write_task(void *arg)
|
||||
{
|
||||
zv_request_task_t *task = arg;
|
||||
zvol_write(&task->zvr);
|
||||
zv_request_task_free(task);
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_discard(zv_request_t *zvr)
|
||||
{
|
||||
zv_request_t *zvr = arg;
|
||||
struct bio *bio = zvr->bio;
|
||||
zvol_state_t *zv = zvr->zv;
|
||||
uint64_t start = BIO_BI_SECTOR(bio) << 9;
|
||||
@ -238,13 +262,19 @@ zvol_discard(void *arg)
|
||||
blk_generic_end_io_acct(q, disk, WRITE, bio, start_time);
|
||||
|
||||
BIO_END_IO(bio, -error);
|
||||
kmem_free(zvr, sizeof (zv_request_t));
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_read(void *arg)
|
||||
zvol_discard_task(void *arg)
|
||||
{
|
||||
zv_request_task_t *task = arg;
|
||||
zvol_discard(&task->zvr);
|
||||
zv_request_task_free(task);
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_read(zv_request_t *zvr)
|
||||
{
|
||||
zv_request_t *zvr = arg;
|
||||
struct bio *bio = zvr->bio;
|
||||
int error = 0;
|
||||
zfs_uio_t uio;
|
||||
@ -295,7 +325,14 @@ zvol_read(void *arg)
|
||||
blk_generic_end_io_acct(q, disk, READ, bio, start_time);
|
||||
|
||||
BIO_END_IO(bio, -error);
|
||||
kmem_free(zvr, sizeof (zv_request_t));
|
||||
}
|
||||
|
||||
static void
|
||||
zvol_read_task(void *arg)
|
||||
{
|
||||
zv_request_task_t *task = arg;
|
||||
zvol_read(&task->zvr);
|
||||
zv_request_task_free(task);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
|
||||
@ -318,7 +355,6 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||
uint64_t offset = BIO_BI_SECTOR(bio) << 9;
|
||||
uint64_t size = BIO_BI_SIZE(bio);
|
||||
int rw = bio_data_dir(bio);
|
||||
zv_request_t *zvr;
|
||||
|
||||
if (bio_has_data(bio) && offset + size > zv->zv_volsize) {
|
||||
printk(KERN_INFO
|
||||
@ -331,6 +367,12 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||
goto out;
|
||||
}
|
||||
|
||||
zv_request_t zvr = {
|
||||
.zv = zv,
|
||||
.bio = bio,
|
||||
};
|
||||
zv_request_task_t *task;
|
||||
|
||||
if (rw == WRITE) {
|
||||
if (unlikely(zv->zv_flags & ZVOL_RDONLY)) {
|
||||
BIO_END_IO(bio, -SET_ERROR(EROFS));
|
||||
@ -357,15 +399,13 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||
zv->zv_zilog = zil_open(zv->zv_objset,
|
||||
zvol_get_data);
|
||||
zv->zv_flags |= ZVOL_WRITTEN_TO;
|
||||
/* replay / destroy done in zvol_create_minor */
|
||||
VERIFY0((zv->zv_zilog->zl_header->zh_flags &
|
||||
ZIL_REPLAY_NEEDED));
|
||||
}
|
||||
rw_downgrade(&zv->zv_suspend_lock);
|
||||
}
|
||||
|
||||
zvr = kmem_alloc(sizeof (zv_request_t), KM_SLEEP);
|
||||
zvr->zv = zv;
|
||||
zvr->bio = bio;
|
||||
taskq_init_ent(&zvr->ent);
|
||||
|
||||
/*
|
||||
* We don't want this thread to be blocked waiting for i/o to
|
||||
* complete, so we instead wait from a taskq callback. The
|
||||
@ -398,17 +438,19 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||
*/
|
||||
if (bio_is_discard(bio) || bio_is_secure_erase(bio)) {
|
||||
if (zvol_request_sync) {
|
||||
zvol_discard(zvr);
|
||||
zvol_discard(&zvr);
|
||||
} else {
|
||||
task = zv_request_task_create(zvr);
|
||||
taskq_dispatch_ent(zvol_taskq,
|
||||
zvol_discard, zvr, 0, &zvr->ent);
|
||||
zvol_discard_task, task, 0, &task->ent);
|
||||
}
|
||||
} else {
|
||||
if (zvol_request_sync) {
|
||||
zvol_write(zvr);
|
||||
zvol_write(&zvr);
|
||||
} else {
|
||||
task = zv_request_task_create(zvr);
|
||||
taskq_dispatch_ent(zvol_taskq,
|
||||
zvol_write, zvr, 0, &zvr->ent);
|
||||
zvol_write_task, task, 0, &task->ent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -422,19 +464,15 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||
goto out;
|
||||
}
|
||||
|
||||
zvr = kmem_alloc(sizeof (zv_request_t), KM_SLEEP);
|
||||
zvr->zv = zv;
|
||||
zvr->bio = bio;
|
||||
taskq_init_ent(&zvr->ent);
|
||||
|
||||
rw_enter(&zv->zv_suspend_lock, RW_READER);
|
||||
|
||||
/* See comment in WRITE case above. */
|
||||
if (zvol_request_sync) {
|
||||
zvol_read(zvr);
|
||||
zvol_read(&zvr);
|
||||
} else {
|
||||
task = zv_request_task_create(zvr);
|
||||
taskq_dispatch_ent(zvol_taskq,
|
||||
zvol_read, zvr, 0, &zvr->ent);
|
||||
zvol_read_task, task, 0, &task->ent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -947,12 +985,16 @@ zvol_os_create_minor(const char *name)
|
||||
blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, zv->zv_zso->zvo_queue);
|
||||
#endif
|
||||
|
||||
ASSERT3P(zv->zv_zilog, ==, NULL);
|
||||
zv->zv_zilog = zil_open(os, zvol_get_data);
|
||||
if (spa_writeable(dmu_objset_spa(os))) {
|
||||
if (zil_replay_disable)
|
||||
zil_destroy(dmu_objset_zil(os), B_FALSE);
|
||||
zil_destroy(zv->zv_zilog, B_FALSE);
|
||||
else
|
||||
zil_replay(os, zv, zvol_replay_vector);
|
||||
}
|
||||
zil_close(zv->zv_zilog);
|
||||
zv->zv_zilog = NULL;
|
||||
ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL);
|
||||
dataset_kstats_create(&zv->zv_kstat, zv->zv_objset);
|
||||
|
||||
|
@ -417,7 +417,7 @@ zfs_prop_init(void)
|
||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
||||
"on | off | lzjb | gzip | gzip-[1-9] | zle | lz4 | "
|
||||
"zstd | zstd-[1-19] | "
|
||||
"zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]",
|
||||
"zstd-fast | zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]",
|
||||
"COMPRESS", compress_table);
|
||||
zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
|
||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||
|
@ -555,8 +555,12 @@ abd_get_offset_impl(abd_t *abd, abd_t *sabd, size_t off, size_t size)
|
||||
abd_t *
|
||||
abd_get_offset_struct(abd_t *abd, abd_t *sabd, size_t off, size_t size)
|
||||
{
|
||||
abd_t *result;
|
||||
abd_init_struct(abd);
|
||||
return (abd_get_offset_impl(abd, sabd, off, size));
|
||||
result = abd_get_offset_impl(abd, sabd, off, size);
|
||||
if (result != abd)
|
||||
abd_fini_struct(abd);
|
||||
return (result);
|
||||
}
|
||||
|
||||
abd_t *
|
||||
|
@ -2923,10 +2923,10 @@ ZFS_MODULE_PARAM(zfs, zfs_, recover, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, free_leak_on_eio, INT, ZMOD_RW,
|
||||
"Set to ignore IO errors during free and permanently leak the space");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, deadman_checktime_ms, ULONG, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, ULONG, ZMOD_RW,
|
||||
"Dead I/O check interval in milliseconds");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, deadman_enabled, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, enabled, INT, ZMOD_RW,
|
||||
"Enable deadman timer");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs_spa, spa_, asize_inflation, INT, ZMOD_RW,
|
||||
|
@ -350,9 +350,11 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
|
||||
}
|
||||
|
||||
/*
|
||||
* If immutable or not appending then return EPERM
|
||||
* If immutable or not appending then return EPERM.
|
||||
* Intentionally allow ZFS_READONLY through here.
|
||||
* See zfs_zaccess_common()
|
||||
*/
|
||||
if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) ||
|
||||
if ((zp->z_pflags & ZFS_IMMUTABLE) ||
|
||||
((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & O_APPEND) &&
|
||||
(zfs_uio_offset(uio) < zp->z_size))) {
|
||||
ZFS_EXIT(zfsvfs);
|
||||
|
@ -473,7 +473,19 @@ zvol_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
|
||||
offset = lr->lr_offset;
|
||||
length = lr->lr_length;
|
||||
|
||||
return (dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, length));
|
||||
dmu_tx_t *tx = dmu_tx_create(zv->zv_objset);
|
||||
dmu_tx_mark_netfree(tx);
|
||||
int error = dmu_tx_assign(tx, TXG_WAIT);
|
||||
if (error != 0) {
|
||||
dmu_tx_abort(tx);
|
||||
} else {
|
||||
zil_replaying(zv->zv_zilog, tx);
|
||||
dmu_tx_commit(tx);
|
||||
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset,
|
||||
length);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -513,6 +525,7 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||
dmu_tx_abort(tx);
|
||||
} else {
|
||||
dmu_write(os, ZVOL_OBJ, offset, length, data, tx);
|
||||
zil_replaying(zv->zv_zilog, tx);
|
||||
dmu_tx_commit(tx);
|
||||
}
|
||||
|
||||
|
@ -398,6 +398,7 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
|
||||
'import_cachefile_device_replaced',
|
||||
'import_cachefile_mirror_attached',
|
||||
'import_cachefile_mirror_detached',
|
||||
'import_cachefile_paths_changed',
|
||||
'import_cachefile_shared_device',
|
||||
'import_devices_missing',
|
||||
'import_paths_changed',
|
||||
|
@ -33,6 +33,7 @@ export SYSTEM_FILES_COMMON='arp
|
||||
du
|
||||
echo
|
||||
egrep
|
||||
env
|
||||
expr
|
||||
false
|
||||
file
|
||||
@ -117,7 +118,6 @@ export SYSTEM_FILES_FREEBSD='chflags
|
||||
compress
|
||||
diskinfo
|
||||
dumpon
|
||||
env
|
||||
fsck
|
||||
getextattr
|
||||
gpart
|
||||
|
@ -41,7 +41,7 @@
|
||||
# PATH may have been modified by sudo's secure_path behavior.
|
||||
#
|
||||
if [ -n "$STF_PATH" ]; then
|
||||
PATH="$STF_PATH"
|
||||
export PATH="$STF_PATH"
|
||||
fi
|
||||
|
||||
#
|
||||
@ -2766,10 +2766,6 @@ function add_user #<group_name> <user_name> <basedir>
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "export PATH=\"$STF_PATH\"" >>$basedir/$user/.profile
|
||||
echo "export PATH=\"$STF_PATH\"" >>$basedir/$user/.bash_profile
|
||||
echo "export PATH=\"$STF_PATH\"" >>$basedir/$user/.login
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -3393,8 +3389,17 @@ function user_run
|
||||
typeset user=$1
|
||||
shift
|
||||
|
||||
log_note "user:$user $@"
|
||||
eval su - \$user -c \"$@\" > $TEST_BASE_DIR/out 2>$TEST_BASE_DIR/err
|
||||
log_note "user: $user"
|
||||
log_note "cmd: $*"
|
||||
|
||||
typeset out=$TEST_BASE_DIR/out
|
||||
typeset err=$TEST_BASE_DIR/err
|
||||
|
||||
sudo -Eu $user env PATH="$PATH" ksh <<<"$*" >$out 2>$err
|
||||
typeset res=$?
|
||||
log_note "out: $(<$out)"
|
||||
log_note "err: $(<$err)"
|
||||
return $res
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -27,10 +27,10 @@ COMPRESSED_ARC_ENABLED compressed_arc_enabled zfs_compressed_arc_enabled
|
||||
CONDENSE_INDIRECT_COMMIT_ENTRY_DELAY_MS condense.indirect_commit_entry_delay_ms zfs_condense_indirect_commit_entry_delay_ms
|
||||
CONDENSE_MIN_MAPPING_BYTES condense.min_mapping_bytes zfs_condense_min_mapping_bytes
|
||||
DBUF_CACHE_MAX_BYTES dbuf_cache.max_bytes dbuf_cache_max_bytes
|
||||
DEADMAN_CHECKTIME_MS deadman_checktime_ms zfs_deadman_checktime_ms
|
||||
DEADMAN_FAILMODE deadman_failmode zfs_deadman_failmode
|
||||
DEADMAN_SYNCTIME_MS deadman_synctime_ms zfs_deadman_synctime_ms
|
||||
DEADMAN_ZIOTIME_MS deadman_ziotime_ms zfs_deadman_ziotime_ms
|
||||
DEADMAN_CHECKTIME_MS deadman.checktime_ms zfs_deadman_checktime_ms
|
||||
DEADMAN_FAILMODE deadman.failmode zfs_deadman_failmode
|
||||
DEADMAN_SYNCTIME_MS deadman.synctime_ms zfs_deadman_synctime_ms
|
||||
DEADMAN_ZIOTIME_MS deadman.ziotime_ms zfs_deadman_ziotime_ms
|
||||
DISABLE_IVSET_GUID_CHECK disable_ivset_guid_check zfs_disable_ivset_guid_check
|
||||
INITIALIZE_CHUNK_SIZE initialize_chunk_size zfs_initialize_chunk_size
|
||||
INITIALIZE_VALUE initialize_value zfs_initialize_value
|
||||
|
@ -47,31 +47,32 @@ function cleanup
|
||||
{
|
||||
unset ZFS_ABORT
|
||||
|
||||
if [[ -d $corepath ]]; then
|
||||
rm -rf $corepath
|
||||
if is_freebsd && [ -n "$old_corefile" ]; then
|
||||
sysctl kern.corefile=$old_corefile
|
||||
fi
|
||||
|
||||
if poolexists $pool; then
|
||||
log_must zpool destroy -f $pool
|
||||
fi
|
||||
# Clean up the pool created if we failed to abort.
|
||||
poolexists $pool && destroy_pool $pool
|
||||
|
||||
rm -rf $corepath $vdev1 $vdev2 $vdev3
|
||||
}
|
||||
|
||||
log_assert "With ZFS_ABORT set, all zpool commands can abort and generate a core file."
|
||||
log_onexit cleanup
|
||||
|
||||
#preparation work for testing
|
||||
corepath=$TESTDIR/core
|
||||
corefile=$corepath/zpool.core
|
||||
if [[ -d $corepath ]]; then
|
||||
rm -rf $corepath
|
||||
log_must rm -rf $corepath
|
||||
fi
|
||||
mkdir $corepath
|
||||
log_must mkdir $corepath
|
||||
|
||||
pool=pool.$$
|
||||
vdev1=$TESTDIR/file1
|
||||
vdev2=$TESTDIR/file2
|
||||
vdev3=$TESTDIR/file3
|
||||
for vdev in $vdev1 $vdev2 $vdev3; do
|
||||
mkfile $MINVDEVSIZE $vdev
|
||||
log_must mkfile $MINVDEVSIZE $vdev
|
||||
done
|
||||
|
||||
set -A cmds "create $pool mirror $vdev1 $vdev2" "list $pool" "iostat $pool" \
|
||||
@ -86,27 +87,25 @@ set -A badparams "" "create" "destroy" "add" "remove" "list *" "iostat" "status"
|
||||
"import" "export" "upgrade" "history -?" "get" "set"
|
||||
|
||||
if is_linux; then
|
||||
ulimit -c unlimited
|
||||
echo "$corepath/core.zpool" >/proc/sys/kernel/core_pattern
|
||||
echo $corefile >/proc/sys/kernel/core_pattern
|
||||
echo 0 >/proc/sys/kernel/core_uses_pid
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
elif is_freebsd; then
|
||||
ulimit -c unlimited
|
||||
log_must sysctl kern.corefile=$corepath/core.zpool
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
else
|
||||
coreadm -p ${corepath}/core.%f
|
||||
old_corefile=$(sysctl -n kern.corefile)
|
||||
log_must sysctl kern.corefile=$corefile
|
||||
fi
|
||||
ulimit -c unlimited
|
||||
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
export ZFS_ABORT=yes
|
||||
|
||||
for subcmd in "${cmds[@]}" "${badparams[@]}"; do
|
||||
corefile=${corepath}/core.zpool
|
||||
zpool $subcmd >/dev/null 2>&1
|
||||
if [[ ! -e $corefile ]]; then
|
||||
log_fail "zpool $subcmd cannot generate core file with ZFS_ABORT set."
|
||||
log_fail "zpool $subcmd cannot generate core file with ZFS_ABORT set."
|
||||
fi
|
||||
rm -f $corefile
|
||||
done
|
||||
|
||||
unset ZFS_ABORT
|
||||
|
||||
log_pass "With ZFS_ABORT set, zpool command can abort and generate core file as expected."
|
||||
|
@ -44,9 +44,17 @@
|
||||
|
||||
function cleanup
|
||||
{
|
||||
unset ZFS_ABORT
|
||||
|
||||
if is_freebsd && [ -n "$old_corefile" ]; then
|
||||
sysctl kern.corefile=$old_corefile
|
||||
fi
|
||||
|
||||
rm -rf $corepath
|
||||
|
||||
# Don't leave the pool frozen.
|
||||
destroy_pool $TESTPOOL
|
||||
default_mirror_setup $DISKS
|
||||
}
|
||||
|
||||
verify_runnable "both"
|
||||
@ -54,7 +62,14 @@ verify_runnable "both"
|
||||
log_assert "Debugging features of zpool should succeed."
|
||||
log_onexit cleanup
|
||||
|
||||
log_must zpool -? > /dev/null 2>&1
|
||||
corepath=$TESTDIR/core
|
||||
corefile=$corepath/zpool.core
|
||||
if [[ -d $corepath ]]; then
|
||||
log_must rm -rf $corepath
|
||||
fi
|
||||
log_must mkdir $corepath
|
||||
|
||||
log_must eval "zpool -? >/dev/null 2>&1"
|
||||
|
||||
if is_global_zone ; then
|
||||
log_must zpool freeze $TESTPOOL
|
||||
@ -65,26 +80,22 @@ fi
|
||||
|
||||
log_mustnot zpool freeze fakepool
|
||||
|
||||
# Remove corefile possibly left by previous failing run of this test.
|
||||
[[ -f core ]] && log_must rm -f core
|
||||
|
||||
if is_linux; then
|
||||
ulimit -c unlimited
|
||||
echo "core" >/proc/sys/kernel/core_pattern
|
||||
echo $corefile >/proc/sys/kernel/core_pattern
|
||||
echo 0 >/proc/sys/kernel/core_uses_pid
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
elif is_freebsd; then
|
||||
ulimit -c unlimited
|
||||
old_corefile=$(sysctl -n kern.corefile)
|
||||
log_must sysctl kern.corefile=core
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
log_must sysctl kern.corefile=$corefile
|
||||
fi
|
||||
ulimit -c unlimited
|
||||
|
||||
export ASAN_OPTIONS="abort_on_error=1:disable_coredump=0"
|
||||
export ZFS_ABORT=yes
|
||||
|
||||
zpool >/dev/null 2>&1
|
||||
|
||||
ZFS_ABORT=1; export ZFS_ABORT
|
||||
zpool > /dev/null 2>&1
|
||||
unset ZFS_ABORT
|
||||
|
||||
[[ -f core ]] || log_fail "zpool did not dump core by request."
|
||||
[[ -f core ]] && log_must rm -f core
|
||||
[[ -f $corefile ]] || log_fail "zpool did not dump core by request."
|
||||
|
||||
log_pass "Debugging features of zpool succeed."
|
||||
|
@ -9,6 +9,7 @@ dist_pkgdata_SCRIPTS = \
|
||||
import_cachefile_device_replaced.ksh \
|
||||
import_cachefile_mirror_attached.ksh \
|
||||
import_cachefile_mirror_detached.ksh \
|
||||
import_cachefile_paths_changed.ksh \
|
||||
import_cachefile_shared_device.ksh \
|
||||
import_devices_missing.ksh \
|
||||
import_paths_changed.ksh \
|
||||
|
@ -0,0 +1,117 @@
|
||||
#!/bin/ksh -p
|
||||
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 by Delphix. All rights reserved.
|
||||
#
|
||||
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# A pool should be importable from a cachefile even if device paths
|
||||
# have changed.
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool using a cachefile
|
||||
# 2. Backup cachefile
|
||||
# 3. Export the pool.
|
||||
# 4. Change the paths of some of the devices.
|
||||
# 5. Verify that we can import the pool using the cachefile.
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
function test_new_paths
|
||||
{
|
||||
typeset poolcreate="$1"
|
||||
typeset pathstochange="$2"
|
||||
|
||||
log_note "$0: pool '$poolcreate', changing paths of $pathstochange."
|
||||
|
||||
log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
|
||||
|
||||
log_must cp $CPATH $CPATHBKP
|
||||
|
||||
log_must zpool export $TESTPOOL1
|
||||
|
||||
for dev in $pathstochange; do
|
||||
log_must mv $dev "${dev}_new"
|
||||
done
|
||||
|
||||
log_must zpool import -c $CPATHBKP $TESTPOOL1
|
||||
log_must check_pool_healthy $TESTPOOL1
|
||||
|
||||
# Cleanup
|
||||
log_must zpool destroy $TESTPOOL1
|
||||
log_must rm -f $CPATH $CPATHBKP
|
||||
for dev in $pathstochange; do
|
||||
log_must mv "${dev}_new" $dev
|
||||
done
|
||||
|
||||
log_note ""
|
||||
}
|
||||
|
||||
function test_duplicate_pools
|
||||
{
|
||||
typeset poolcreate="$1"
|
||||
typeset pathstocopy="$2"
|
||||
|
||||
log_note "$0: pool '$poolcreate', creating duplicate pool using $pathstocopy."
|
||||
|
||||
log_must zpool create -o cachefile=$CPATH $TESTPOOL1 $poolcreate
|
||||
log_must zpool export $TESTPOOL1
|
||||
|
||||
for dev in $pathstocopy; do
|
||||
log_must cp $dev "${dev}_orig"
|
||||
|
||||
done
|
||||
|
||||
log_must zpool create -f -o cachefile=$CPATH $TESTPOOL1 $poolcreate
|
||||
log_must cp $CPATH $CPATHBKP
|
||||
log_must zpool export $TESTPOOL1
|
||||
|
||||
for dev in $pathstocopy; do
|
||||
log_must mv $dev "${dev}_new"
|
||||
done
|
||||
|
||||
log_must zpool import -c $CPATHBKP
|
||||
log_must zpool import -c $CPATHBKP $TESTPOOL1
|
||||
log_must check_pool_healthy $TESTPOOL1
|
||||
|
||||
# Cleanup
|
||||
log_must zpool destroy $TESTPOOL1
|
||||
log_must rm -f $CPATH $CPATHBKP
|
||||
for dev in $pathstocopy; do
|
||||
log_must rm "${dev}_orig"
|
||||
log_must mv "${dev}_new" $dev
|
||||
done
|
||||
|
||||
log_note ""
|
||||
}
|
||||
|
||||
test_new_paths "$VDEV0 $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_new_paths "mirror $VDEV0 $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_new_paths "$VDEV0 log $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_new_paths "raidz $VDEV0 $VDEV1 $VDEV2" "$VDEV0 $VDEV1 $VDEV2"
|
||||
test_new_paths "draid $VDEV0 $VDEV1 $VDEV2" "$VDEV0 $VDEV1 $VDEV2"
|
||||
|
||||
test_duplicate_pools "$VDEV0 $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_duplicate_pools "mirror $VDEV0 $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_duplicate_pools "$VDEV0 log $VDEV1" "$VDEV0 $VDEV1"
|
||||
test_duplicate_pools "raidz $VDEV0 $VDEV1 $VDEV2" "$VDEV0 $VDEV1 $VDEV2"
|
||||
test_duplicate_pools "draid $VDEV0 $VDEV1 $VDEV2" "$VDEV0 $VDEV1 $VDEV2"
|
||||
|
||||
log_pass "zpool import with cachefile succeeded after changing device paths."
|
@ -66,7 +66,7 @@ log_must zpool create $MPOOL mirror $VDEV1 $VDEV2
|
||||
|
||||
# 2. Start the ZED and verify it handles missed events.
|
||||
log_must zed_start
|
||||
log_must file_wait $ZED_DEBUG_LOG
|
||||
log_must file_wait_event $ZED_DEBUG_LOG 'sysevent\.fs\.zfs\.config_sync' 150
|
||||
log_must cp $ZED_DEBUG_LOG $TMP_EVENTS_ZED
|
||||
|
||||
awk -v event="sysevent.fs.zfs.pool_create" \
|
||||
@ -92,12 +92,11 @@ done
|
||||
|
||||
# 5. Start the ZED and verify it only handled the new missed events.
|
||||
log_must zed_start
|
||||
log_must file_wait $ZED_DEBUG_LOG 35
|
||||
log_must file_wait_event $ZED_DEBUG_LOG 'sysevent\.fs\.zfs\.resilver_finish' 150
|
||||
log_must cp $ZED_DEBUG_LOG $TMP_EVENTS_ZED
|
||||
|
||||
log_mustnot grep -q "sysevent.fs.zfs.pool_create" $TMP_EVENTS_ZED
|
||||
log_mustnot file_wait_event $ZED_DEBUG_LOG 'sysevent\.fs\.zfs\.pool_create' 30
|
||||
log_must grep -q "sysevent.fs.zfs.vdev_online" $TMP_EVENTS_ZED
|
||||
log_must grep -q "sysevent.fs.zfs.resilver_start" $TMP_EVENTS_ZED
|
||||
log_must grep -q "sysevent.fs.zfs.resilver_finish" $TMP_EVENTS_ZED
|
||||
|
||||
log_pass "Verify ZED handles missed events on when starting"
|
||||
|
@ -43,34 +43,40 @@
|
||||
# 4. Check that we're unable to write an xattr as a non-root user
|
||||
#
|
||||
|
||||
function cleanup {
|
||||
|
||||
log_must rm $TESTDIR/myfile.$$
|
||||
|
||||
function cleanup
|
||||
{
|
||||
rm -f $testfile $tempfile
|
||||
}
|
||||
|
||||
log_assert "read/write xattr on a file with no permissions fails"
|
||||
log_onexit cleanup
|
||||
|
||||
log_must touch $TESTDIR/myfile.$$
|
||||
create_xattr $TESTDIR/myfile.$$ passwd /etc/passwd
|
||||
typeset testfile=$TESTDIR/testfile.$$
|
||||
typeset tempfile=/tmp/tempfile.$$
|
||||
|
||||
log_must chmod 000 $TESTDIR/myfile.$$
|
||||
log_must touch $testfile
|
||||
create_xattr $testfile passwd /etc/passwd
|
||||
|
||||
log_must chmod 000 $testfile
|
||||
if is_illumos; then
|
||||
log_mustnot su $ZFS_USER -c "runat $TESTDIR/myfile.$$ cat passwd"
|
||||
log_mustnot su $ZFS_USER -c "runat $TESTDIR/myfile.$$ cp /etc/passwd ."
|
||||
log_mustnot su $ZFS_USER -c "runat $testfile cat passwd"
|
||||
log_mustnot su $ZFS_USER -c "runat $testfile cp /etc/passwd ."
|
||||
else
|
||||
user_run $ZFS_USER eval \
|
||||
"get_xattr passwd $TESTDIR/myfile.$$ >/tmp/passwd.$$"
|
||||
log_mustnot diff /etc/passwd /tmp/passwd.$$
|
||||
log_must rm /tmp/passwd.$$
|
||||
log_mustnot user_run $ZFS_USER "
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
get_xattr passwd $testfile >$tempfile
|
||||
"
|
||||
log_mustnot diff -q /etc/passwd $tempfile
|
||||
log_must rm $tempfile
|
||||
|
||||
user_run $ZFS_USER eval \
|
||||
"set_xattr_stdin passwd $TESTDIR/myfile.$$ </etc/group"
|
||||
log_must chmod 644 $TESTDIR/myfile.$$
|
||||
get_xattr passwd $TESTDIR/myfile.$$ >/tmp/passwd.$$
|
||||
log_must diff /etc/passwd /tmp/passwd.$$
|
||||
log_must rm /tmp/passwd.$$
|
||||
log_mustnot user_run $ZFS_USER "
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
set_xattr_stdin passwd $testfile </etc/group
|
||||
"
|
||||
log_must chmod 644 $testfile
|
||||
get_xattr passwd $testfile >$tempfile
|
||||
log_must diff -q /etc/passwd $tempfile
|
||||
log_must rm $tempfile
|
||||
fi
|
||||
|
||||
log_pass "read/write xattr on a file with no permissions fails"
|
||||
|
@ -734,7 +734,7 @@
|
||||
/* #undef ZFS_IS_GPL_COMPATIBLE */
|
||||
|
||||
/* Define the project alias string. */
|
||||
#define ZFS_META_ALIAS "zfs-2.0.0-FreeBSD_gbedbc13da"
|
||||
#define ZFS_META_ALIAS "zfs-2.0.0-FreeBSD_g9305ff2ed"
|
||||
|
||||
/* Define the project author. */
|
||||
#define ZFS_META_AUTHOR "OpenZFS"
|
||||
@ -764,7 +764,7 @@
|
||||
#define ZFS_META_NAME "zfs"
|
||||
|
||||
/* Define the project release. */
|
||||
#define ZFS_META_RELEASE "FreeBSD_gbedbc13da"
|
||||
#define ZFS_META_RELEASE "FreeBSD_g9305ff2ed"
|
||||
|
||||
/* Define the project version. */
|
||||
#define ZFS_META_VERSION "2.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user