Update vendor openzfs to fd20a8
This commit is contained in:
parent
93ddd0259d
commit
431004027d
@ -311,7 +311,8 @@ get_usage(zfs_help_t idx)
|
||||
case HELP_RENAME:
|
||||
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
|
||||
"<filesystem|volume|snapshot>\n"
|
||||
"\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
|
||||
"\trename -p [-f] <filesystem|volume> <filesystem|volume>\n"
|
||||
"\trename -u [-f] <filesystem> <filesystem>\n"
|
||||
"\trename -r <snapshot> <snapshot>\n"));
|
||||
case HELP_ROLLBACK:
|
||||
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
||||
@ -401,7 +402,7 @@ get_usage(zfs_help_t idx)
|
||||
"<-a | filesystem|volume>\n"));
|
||||
case HELP_CHANGE_KEY:
|
||||
return (gettext("\tchange-key [-l] [-o keyformat=<value>]\n"
|
||||
"\t [-o keylocation=<value>] [-o pbkfd2iters=<value>]\n"
|
||||
"\t [-o keylocation=<value>] [-o pbkdf2iters=<value>]\n"
|
||||
"\t <filesystem|volume>\n"
|
||||
"\tchange-key -i [-l] <filesystem|volume>\n"));
|
||||
case HELP_VERSION:
|
||||
@ -3603,36 +3604,40 @@ zfs_do_list(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs rename [-f] <fs | snap | vol> <fs | snap | vol>
|
||||
* zfs rename [-fu] <fs | snap | vol> <fs | snap | vol>
|
||||
* zfs rename [-f] -p <fs | vol> <fs | vol>
|
||||
* zfs rename -r <snap> <snap>
|
||||
* zfs rename [-u] -r <snap> <snap>
|
||||
*
|
||||
* Renames the given dataset to another of the same type.
|
||||
*
|
||||
* The '-p' flag creates all the non-existing ancestors of the target first.
|
||||
* The '-u' flag prevents file systems from being remounted during rename.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
zfs_do_rename(int argc, char **argv)
|
||||
{
|
||||
zfs_handle_t *zhp;
|
||||
renameflags_t flags = { 0 };
|
||||
int c;
|
||||
int ret = 0;
|
||||
boolean_t recurse = B_FALSE;
|
||||
int types;
|
||||
boolean_t parents = B_FALSE;
|
||||
boolean_t force_unmount = B_FALSE;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "prf")) != -1) {
|
||||
while ((c = getopt(argc, argv, "pruf")) != -1) {
|
||||
switch (c) {
|
||||
case 'p':
|
||||
parents = B_TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
recurse = B_TRUE;
|
||||
flags.recursive = B_TRUE;
|
||||
break;
|
||||
case 'u':
|
||||
flags.nounmount = B_TRUE;
|
||||
break;
|
||||
case 'f':
|
||||
force_unmount = B_TRUE;
|
||||
flags.forceunmount = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
@ -3661,20 +3666,32 @@ zfs_do_rename(int argc, char **argv)
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (recurse && parents) {
|
||||
if (flags.recursive && parents) {
|
||||
(void) fprintf(stderr, gettext("-p and -r options are mutually "
|
||||
"exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (recurse && strchr(argv[0], '@') == 0) {
|
||||
if (flags.nounmount && parents) {
|
||||
(void) fprintf(stderr, gettext("-u and -p options are mutually "
|
||||
"exclusive\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (flags.recursive && strchr(argv[0], '@') == 0) {
|
||||
(void) fprintf(stderr, gettext("source dataset for recursive "
|
||||
"rename must be a snapshot\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], parents ? ZFS_TYPE_FILESYSTEM |
|
||||
ZFS_TYPE_VOLUME : ZFS_TYPE_DATASET)) == NULL)
|
||||
if (flags.nounmount)
|
||||
types = ZFS_TYPE_FILESYSTEM;
|
||||
else if (parents)
|
||||
types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
|
||||
else
|
||||
types = ZFS_TYPE_DATASET;
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL)
|
||||
return (1);
|
||||
|
||||
/* If we were asked and the name looks good, try to create ancestors. */
|
||||
@ -3684,7 +3701,7 @@ zfs_do_rename(int argc, char **argv)
|
||||
return (1);
|
||||
}
|
||||
|
||||
ret = (zfs_rename(zhp, argv[1], recurse, force_unmount) != 0);
|
||||
ret = (zfs_rename(zhp, argv[1], flags) != 0);
|
||||
|
||||
zfs_close(zhp);
|
||||
return (ret);
|
||||
|
@ -94,9 +94,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY], [
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_FILE_PAGES])
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_ANON])
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_INACTIVE_FILE])
|
||||
AS_IF([test -z "$ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B"],[
|
||||
ZFS_AC_KERNEL_GLOBAL_PAGE_STATE_ENUM_CHECK([NR_SLAB_RECLAIMABLE])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
||||
@ -119,10 +116,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE_B],
|
||||
[node_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_FILE_PAGES],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
@ -130,8 +123,6 @@ AC_DEFUN([ZFS_AC_KERNEL_GLOBAL_PAGE_STATE], [
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_INACTIVE_FILE],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
ZFS_AC_KERNEL_ENUM_MEMBER([NR_SLAB_RECLAIMABLE],
|
||||
[zone_stat_item], [$LINUX/include/linux/mmzone.h])
|
||||
|
||||
ZFS_AC_KERNEL_GLOBAL_ZONE_PAGE_STATE_SANITY
|
||||
])
|
||||
|
@ -418,33 +418,43 @@ dnl # package type for 'make pkg': (rpm | deb | tgz)
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [
|
||||
AC_MSG_CHECKING([os distribution])
|
||||
if test -f /etc/toss-release ; then
|
||||
VENDOR=toss ;
|
||||
elif test -f /etc/fedora-release ; then
|
||||
VENDOR=fedora ;
|
||||
elif test -f /etc/redhat-release ; then
|
||||
VENDOR=redhat ;
|
||||
elif test -f /etc/gentoo-release ; then
|
||||
VENDOR=gentoo ;
|
||||
elif test -f /etc/arch-release ; then
|
||||
VENDOR=arch ;
|
||||
elif test -f /etc/SuSE-release ; then
|
||||
VENDOR=sles ;
|
||||
elif test -f /etc/slackware-version ; then
|
||||
VENDOR=slackware ;
|
||||
elif test -f /etc/lunar.release ; then
|
||||
VENDOR=lunar ;
|
||||
elif test -f /etc/lsb-release ; then
|
||||
VENDOR=ubuntu ;
|
||||
elif test -f /etc/debian_version ; then
|
||||
VENDOR=debian ;
|
||||
elif test -f /etc/alpine-release ; then
|
||||
VENDOR=alpine ;
|
||||
elif test -f /bin/freebsd-version ; then
|
||||
VENDOR=freebsd ;
|
||||
else
|
||||
VENDOR= ;
|
||||
fi
|
||||
AC_ARG_WITH([vendor],
|
||||
[AS_HELP_STRING([--with-vendor],
|
||||
[Distribution vendor @<:@default=check@:>@])],
|
||||
[with_vendor=$withval],
|
||||
[with_vendor=check])
|
||||
AS_IF([test "x$with_vendor" = "xcheck"],[
|
||||
if test -f /etc/toss-release ; then
|
||||
VENDOR=toss ;
|
||||
elif test -f /etc/fedora-release ; then
|
||||
VENDOR=fedora ;
|
||||
elif test -f /etc/redhat-release ; then
|
||||
VENDOR=redhat ;
|
||||
elif test -f /etc/gentoo-release ; then
|
||||
VENDOR=gentoo ;
|
||||
elif test -f /etc/arch-release ; then
|
||||
VENDOR=arch ;
|
||||
elif test -f /etc/SuSE-release ; then
|
||||
VENDOR=sles ;
|
||||
elif test -f /etc/slackware-version ; then
|
||||
VENDOR=slackware ;
|
||||
elif test -f /etc/lunar.release ; then
|
||||
VENDOR=lunar ;
|
||||
elif test -f /etc/lsb-release ; then
|
||||
VENDOR=ubuntu ;
|
||||
elif test -f /etc/debian_version ; then
|
||||
VENDOR=debian ;
|
||||
elif test -f /etc/alpine-release ; then
|
||||
VENDOR=alpine ;
|
||||
elif test -f /bin/freebsd-version ; then
|
||||
VENDOR=freebsd ;
|
||||
else
|
||||
VENDOR= ;
|
||||
fi],
|
||||
[ test "x${with_vendor}" != x],[
|
||||
VENDOR="$with_vendor" ],
|
||||
[ VENDOR= ; ]
|
||||
)
|
||||
AC_MSG_RESULT([$VENDOR])
|
||||
AC_SUBST(VENDOR)
|
||||
|
||||
|
@ -38,8 +38,6 @@ do_fail() {
|
||||
is_known() {
|
||||
query="$1"
|
||||
IFS=' '
|
||||
# protect against special characters
|
||||
set -f
|
||||
for element in $2 ; do
|
||||
if [ "$query" = "$element" ] ; then
|
||||
return 0
|
||||
@ -54,8 +52,7 @@ is_known() {
|
||||
create_dependencies() {
|
||||
unitfile="$1"
|
||||
suffix="$2"
|
||||
# protect against special characters
|
||||
set -f
|
||||
IFS=' '
|
||||
for target in $3 ; do
|
||||
target_dir="${dest_norm}/${target}.${suffix}/"
|
||||
mkdir -p "${target_dir}"
|
||||
@ -72,6 +69,7 @@ else
|
||||
do_fail "zero or three arguments required"
|
||||
fi
|
||||
|
||||
pools=$(zpool list -H -o name || true)
|
||||
|
||||
# All needed information about each ZFS is available from
|
||||
# zfs list -H -t filesystem -o <properties>
|
||||
@ -83,11 +81,11 @@ process_line() {
|
||||
# zfs list -H -o name,...
|
||||
# fields are tab separated
|
||||
IFS="$(printf '\t')"
|
||||
# protect against special characters in, e.g., mountpoints
|
||||
set -f
|
||||
# shellcheck disable=SC2086
|
||||
set -- $1
|
||||
|
||||
dataset="${1}"
|
||||
pool="${dataset%%/*}"
|
||||
p_mountpoint="${2}"
|
||||
p_canmount="${3}"
|
||||
p_atime="${4}"
|
||||
@ -120,6 +118,25 @@ process_line() {
|
||||
requiredby=""
|
||||
noauto="off"
|
||||
|
||||
# If the pool is already imported, zfs-import.target is not needed. This
|
||||
# avoids a dependency loop on root-on-ZFS systems:
|
||||
# systemd-random-seed.service After (via RequiresMountsFor) var-lib.mount
|
||||
# After zfs-import.target After zfs-import-{cache,scan}.service After
|
||||
# cryptsetup.service After systemd-random-seed.service.
|
||||
#
|
||||
# Pools are newline-separated and may contain spaces in their names.
|
||||
# There is no better portable way to set IFS to just a newline. Using
|
||||
# $(printf '\n') doesn't work because $(...) strips trailing newlines.
|
||||
IFS="
|
||||
"
|
||||
for p in $pools ; do
|
||||
if [ "$p" = "$pool" ] ; then
|
||||
after=""
|
||||
wants=""
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "${p_systemd_after}" ] && \
|
||||
[ "${p_systemd_after}" != "-" ] ; then
|
||||
after="${p_systemd_after} ${after}"
|
||||
@ -204,6 +221,10 @@ ${keymountdep}
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
# This avoids a dependency loop involving systemd-journald.socket if this
|
||||
# dataset is a parent of the root filesystem.
|
||||
StandardOutput=null
|
||||
StandardError=null
|
||||
ExecStart=${keyloadcmd}
|
||||
ExecStop=${keyunloadcmd}" > "${dest_norm}/${keyloadunit}"
|
||||
fi
|
||||
@ -438,6 +459,8 @@ Options=defaults${opts},zfsutil" > "${dest_norm}/${mountfile}"
|
||||
}
|
||||
|
||||
for cachefile in "${FSLIST}/"* ; do
|
||||
# Disable glob expansion to protect against special characters when parsing.
|
||||
set -f
|
||||
# Sort cachefile's lines by canmount, "on" before "noauto"
|
||||
# and feed each line into process_line
|
||||
sort -t "$(printf '\t')" -k 3 -r "${cachefile}" | \
|
||||
|
@ -6,7 +6,6 @@ After=systemd-udev-settle.service
|
||||
After=zfs-import.target
|
||||
After=systemd-remount-fs.service
|
||||
Before=local-fs.target
|
||||
Before=systemd-random-seed.service
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
|
@ -642,7 +642,19 @@ extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
|
||||
extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps,
|
||||
nvlist_t *props);
|
||||
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
|
||||
extern int zfs_rename(zfs_handle_t *, const char *, boolean_t, boolean_t);
|
||||
|
||||
typedef struct renameflags {
|
||||
/* recursive rename */
|
||||
int recursive : 1;
|
||||
|
||||
/* don't unmount file systems */
|
||||
int nounmount : 1;
|
||||
|
||||
/* force unmount file systems */
|
||||
int forceunmount : 1;
|
||||
} renameflags_t;
|
||||
|
||||
extern int zfs_rename(zfs_handle_t *, const char *, renameflags_t);
|
||||
|
||||
typedef struct sendflags {
|
||||
/* Amount of extra information to print. */
|
||||
|
@ -166,6 +166,10 @@ int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
|
||||
* changelist_gather() flag to force it to iterate on mounted datasets only
|
||||
*/
|
||||
#define CL_GATHER_ITER_MOUNTED 2
|
||||
/*
|
||||
* Use this changelist_gather() flag to prevent unmounting of file systems.
|
||||
*/
|
||||
#define CL_GATHER_DONT_UNMOUNT 4
|
||||
|
||||
typedef struct prop_changelist prop_changelist_t;
|
||||
|
||||
|
@ -93,7 +93,7 @@ extern cred_t *zone_kcred(void);
|
||||
extern gid_t crgetrgid(const cred_t *);
|
||||
extern gid_t crgetsgid(const cred_t *);
|
||||
|
||||
#define crgetzoneid(x) (0)
|
||||
#define crgetzoneid(cr) ((cr)->cr_prison->pr_id)
|
||||
extern projid_t crgetprojid(const cred_t *);
|
||||
|
||||
extern cred_t *crgetmapped(const cred_t *);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#ifndef _OPENSOLARIS_SYS_ZONE_H_
|
||||
#define _OPENSOLARIS_SYS_ZONE_H_
|
||||
|
||||
#include <sys/jail.h>
|
||||
|
||||
/*
|
||||
* Macros to help with zone visibility restrictions.
|
||||
*/
|
||||
@ -36,12 +38,9 @@
|
||||
#define GLOBAL_ZONEID 0
|
||||
|
||||
/*
|
||||
* Is thread in the global zone?
|
||||
* Is proc in the global zone?
|
||||
*/
|
||||
#define INGLOBALZONE(p) in_globalzone((p))
|
||||
|
||||
|
||||
extern boolean_t in_globalzone(struct proc *);
|
||||
#define INGLOBALZONE(proc) (!jailed((proc)->p_ucred))
|
||||
|
||||
/*
|
||||
* Attach the given dataset to the given jail.
|
||||
|
@ -6,7 +6,7 @@ KERNEL_H = \
|
||||
zfs_ctldir.h \
|
||||
zfs_dir.h \
|
||||
zfs_ioctl_compat.h \
|
||||
zfs_vfsops.h \
|
||||
zfs_vfsops_os.h \
|
||||
zfs_vnops.h \
|
||||
zfs_znode_impl.h \
|
||||
zpl.h
|
||||
|
@ -168,7 +168,6 @@ extern boolean_t zfs_is_readonly(zfsvfs_t *zfsvfs);
|
||||
extern int zfs_get_temporary_prop(struct dsl_dataset *ds, zfs_prop_t zfs_prop,
|
||||
uint64_t *val, char *setpoint);
|
||||
extern int zfs_busy(void);
|
||||
extern void zfsvfs_update_fromname(const char *oldname, const char *newname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -35,16 +35,6 @@
|
||||
#else
|
||||
#define nr_inactive_file_pages() global_zone_page_state(NR_INACTIVE_FILE)
|
||||
#endif
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B)
|
||||
#define nr_slab_reclaimable_pages() \
|
||||
global_node_page_state(NR_SLAB_RECLAIMABLE_B)
|
||||
#else
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
|
||||
#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#else
|
||||
#define nr_slab_reclaimable_pages() global_zone_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(ZFS_GLOBAL_NODE_PAGE_STATE)
|
||||
|
||||
@ -64,16 +54,6 @@
|
||||
#else
|
||||
#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE)
|
||||
#endif
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B)
|
||||
#define nr_slab_reclaimable_pages() \
|
||||
global_node_page_state(NR_SLAB_RECLAIMABLE_B)
|
||||
#else
|
||||
#if defined(ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE)
|
||||
#define nr_slab_reclaimable_pages() global_node_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#else
|
||||
#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@ -81,11 +61,6 @@
|
||||
#define nr_file_pages() global_page_state(NR_FILE_PAGES)
|
||||
#define nr_inactive_anon_pages() global_page_state(NR_INACTIVE_ANON)
|
||||
#define nr_inactive_file_pages() global_page_state(NR_INACTIVE_FILE)
|
||||
#ifdef ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B
|
||||
#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE_B)
|
||||
#else
|
||||
#define nr_slab_reclaimable_pages() global_page_state(NR_SLAB_RECLAIMABLE)
|
||||
#endif /* ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B */
|
||||
|
||||
#endif /* ZFS_GLOBAL_ZONE_PAGE_STATE */
|
||||
|
||||
|
@ -47,17 +47,6 @@
|
||||
|
||||
#define membar_producer() smp_wmb()
|
||||
#define physmem zfs_totalram_pages
|
||||
#ifdef ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B
|
||||
#define freemem (nr_free_pages() + \
|
||||
global_page_state(NR_INACTIVE_FILE) + \
|
||||
global_page_state(NR_INACTIVE_ANON) + \
|
||||
global_page_state(NR_SLAB_RECLAIMABLE_B))
|
||||
#else
|
||||
#define freemem (nr_free_pages() + \
|
||||
global_page_state(NR_INACTIVE_FILE) + \
|
||||
global_page_state(NR_INACTIVE_ANON) + \
|
||||
global_page_state(NR_SLAB_RECLAIMABLE))
|
||||
#endif /* ZFS_ENUM_NODE_STAT_ITEM_NR_SLAB_RECLAIMABLE_B */
|
||||
|
||||
#define xcopyin(from, to, size) copy_from_user(to, from, size)
|
||||
#define xcopyout(from, to, size) copy_to_user(to, from, size)
|
||||
|
@ -19,7 +19,7 @@ KERNEL_H = \
|
||||
zfs_context_os.h \
|
||||
zfs_ctldir.h \
|
||||
zfs_dir.h \
|
||||
zfs_vfsops.h \
|
||||
zfs_vfsops_os.h \
|
||||
zfs_vnops.h \
|
||||
zfs_znode_impl.h \
|
||||
zpl.h
|
||||
|
@ -115,6 +115,7 @@ COMMON_H = \
|
||||
zfs_sa.h \
|
||||
zfs_stat.h \
|
||||
zfs_sysfs.h \
|
||||
zfs_vfsops.h \
|
||||
zfs_znode.h \
|
||||
zil.h \
|
||||
zil_impl.h \
|
||||
|
35
include/sys/zfs_vfsops.h
Normal file
35
include/sys/zfs_vfsops.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright 2020 iXsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_VFSOPS_H
|
||||
#define _SYS_ZFS_VFSOPS_H
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/zfs_vfsops_os.h>
|
||||
#endif
|
||||
|
||||
extern void zfsvfs_update_fromname(const char *, const char *);
|
||||
|
||||
#endif /* _SYS_ZFS_VFSOPS_H */
|
@ -27,7 +27,6 @@ USER_C = \
|
||||
strlcat.c \
|
||||
strlcpy.c \
|
||||
timestamp.c \
|
||||
zone.c \
|
||||
include/sys/list.h \
|
||||
include/sys/list_impl.h
|
||||
|
||||
@ -35,7 +34,8 @@ if BUILD_LINUX
|
||||
USER_C += \
|
||||
os/linux/getexecname.c \
|
||||
os/linux/gethostid.c \
|
||||
os/linux/getmntany.c
|
||||
os/linux/getmntany.c \
|
||||
os/linux/zone.c
|
||||
endif
|
||||
|
||||
if BUILD_FREEBSD
|
||||
@ -43,7 +43,8 @@ USER_C += \
|
||||
os/freebsd/getexecname.c \
|
||||
os/freebsd/gethostid.c \
|
||||
os/freebsd/getmntany.c \
|
||||
os/freebsd/mnttab.c
|
||||
os/freebsd/mnttab.c \
|
||||
os/freebsd/zone.c
|
||||
endif
|
||||
|
||||
libspl_la_SOURCES = \
|
||||
|
@ -25,16 +25,21 @@
|
||||
*/
|
||||
|
||||
#include_next <limits.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifndef _LIBSPL_LIMITS_H
|
||||
#define _LIBSPL_LIMITS_H
|
||||
|
||||
#ifndef DBL_DIG
|
||||
#define DBL_DIG 15
|
||||
#define DBL_MAX 1.7976931348623157081452E+308
|
||||
#define DBL_MIN 2.2250738585072013830903E-308
|
||||
#endif
|
||||
|
||||
#ifndef FLT_DIG
|
||||
#define FLT_DIG 6
|
||||
#define FLT_MAX 3.4028234663852885981170E+38F
|
||||
#define FLT_MIN 1.1754943508222875079688E-38F
|
||||
#endif
|
||||
|
||||
#endif /* _LIBSPL_LIMITS_H */
|
||||
|
@ -26,25 +26,16 @@
|
||||
#ifndef _LIBSPL_ZONE_H
|
||||
#define _LIBSPL_ZONE_H
|
||||
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/zone.h>
|
||||
#include <sys/priv.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GLOBAL_ZONEID 0
|
||||
#define GLOBAL_ZONEID_NAME "global"
|
||||
|
||||
/*
|
||||
* Functions for mapping between id and name for active zones.
|
||||
*/
|
||||
extern zoneid_t getzoneid(void);
|
||||
extern zoneid_t getzoneidbyname(const char *);
|
||||
extern ssize_t getzonenamebyid(zoneid_t, char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
46
lib/libspl/os/freebsd/zone.c
Normal file
46
lib/libspl/os/freebsd/zone.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <zone.h>
|
||||
|
||||
zoneid_t
|
||||
getzoneid(void)
|
||||
{
|
||||
size_t size;
|
||||
int jailid;
|
||||
|
||||
/* Information that we are in jail or not is enough for our needs. */
|
||||
size = sizeof (jailid);
|
||||
if (sysctlbyname("security.jail.jailed", &jailid, &size, NULL, 0) == -1)
|
||||
assert(!"No security.jail.jailed sysctl!");
|
||||
return ((zoneid_t)jailid);
|
||||
}
|
@ -24,40 +24,9 @@
|
||||
*/
|
||||
|
||||
#include <zone.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
zoneid_t
|
||||
getzoneid()
|
||||
{
|
||||
return (GLOBAL_ZONEID);
|
||||
}
|
||||
|
||||
zoneid_t
|
||||
getzoneidbyname(const char *name)
|
||||
{
|
||||
if (name == NULL)
|
||||
return (GLOBAL_ZONEID);
|
||||
|
||||
if (strcmp(name, GLOBAL_ZONEID_NAME) == 0)
|
||||
return (GLOBAL_ZONEID);
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
getzonenamebyid(zoneid_t id, char *buf, size_t buflen)
|
||||
{
|
||||
if (id != GLOBAL_ZONEID)
|
||||
return (EINVAL);
|
||||
|
||||
ssize_t ret = strlen(GLOBAL_ZONEID_NAME) + 1;
|
||||
|
||||
if (buf == NULL || buflen == 0)
|
||||
return (ret);
|
||||
|
||||
strncpy(buf, GLOBAL_ZONEID_NAME, buflen);
|
||||
buf[buflen - 1] = '\0';
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -128,6 +128,8 @@ changelist_prefix(prop_changelist_t *clp)
|
||||
*/
|
||||
switch (clp->cl_prop) {
|
||||
case ZFS_PROP_MOUNTPOINT:
|
||||
if (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT)
|
||||
break;
|
||||
if (zfs_unmount(cn->cn_handle, NULL,
|
||||
clp->cl_mflags) != 0) {
|
||||
ret = -1;
|
||||
@ -184,7 +186,8 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
if ((cn = uu_avl_last(clp->cl_tree)) == NULL)
|
||||
return (0);
|
||||
|
||||
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT)
|
||||
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT &&
|
||||
!(clp->cl_gflags & CL_GATHER_DONT_UNMOUNT))
|
||||
remove_mountpoint(cn->cn_handle);
|
||||
|
||||
/*
|
||||
@ -235,7 +238,8 @@ changelist_postfix(prop_changelist_t *clp)
|
||||
needs_key = (zfs_prop_get_int(cn->cn_handle,
|
||||
ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE);
|
||||
|
||||
mounted = zfs_is_mounted(cn->cn_handle, NULL);
|
||||
mounted = (clp->cl_gflags & CL_GATHER_DONT_UNMOUNT) ||
|
||||
zfs_is_mounted(cn->cn_handle, NULL);
|
||||
|
||||
if (!mounted && !needs_key && (cn->cn_mounted ||
|
||||
((sharenfs || sharesmb || clp->cl_waslegacy) &&
|
||||
|
@ -4370,14 +4370,14 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
||||
* Renames the given dataset.
|
||||
*/
|
||||
int
|
||||
zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
boolean_t force_unmount)
|
||||
zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
|
||||
{
|
||||
int ret = 0;
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
char *delim;
|
||||
prop_changelist_t *cl = NULL;
|
||||
char parent[ZFS_MAX_DATASET_NAME_LEN];
|
||||
char property[ZFS_MAXPROPLEN];
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
char errbuf[1024];
|
||||
|
||||
@ -4429,7 +4429,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
|
||||
return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
|
||||
} else {
|
||||
if (recursive) {
|
||||
if (flags.recursive) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"recursive rename must be a snapshot"));
|
||||
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
|
||||
@ -4470,8 +4470,19 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
return (zfs_error(hdl, EZFS_ZONED, errbuf));
|
||||
}
|
||||
|
||||
if (recursive) {
|
||||
zfs_handle_t *zhrp;
|
||||
/*
|
||||
* Avoid unmounting file systems with mountpoint property set to
|
||||
* 'legacy' or 'none' even if -u option is not given.
|
||||
*/
|
||||
if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
|
||||
!flags.recursive && !flags.nounmount &&
|
||||
zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
|
||||
sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
|
||||
(strcmp(property, "legacy") == 0 ||
|
||||
strcmp(property, "none") == 0)) {
|
||||
flags.nounmount = B_TRUE;
|
||||
}
|
||||
if (flags.recursive) {
|
||||
char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
||||
if (parentname == NULL) {
|
||||
ret = -1;
|
||||
@ -4479,7 +4490,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
}
|
||||
delim = strchr(parentname, '@');
|
||||
*delim = '\0';
|
||||
zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
|
||||
zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname,
|
||||
ZFS_TYPE_DATASET);
|
||||
free(parentname);
|
||||
if (zhrp == NULL) {
|
||||
ret = -1;
|
||||
@ -4488,8 +4500,9 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
zfs_close(zhrp);
|
||||
} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
|
||||
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
|
||||
flags.nounmount ? CL_GATHER_DONT_UNMOUNT :
|
||||
CL_GATHER_ITER_MOUNTED,
|
||||
force_unmount ? MS_FORCE : 0)) == NULL)
|
||||
flags.forceunmount ? MS_FORCE : 0)) == NULL)
|
||||
return (-1);
|
||||
|
||||
if (changelist_haszonedchild(cl)) {
|
||||
@ -4513,7 +4526,8 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
(void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
|
||||
|
||||
zc.zc_cookie = recursive;
|
||||
zc.zc_cookie = !!flags.recursive;
|
||||
zc.zc_cookie |= (!!flags.nounmount) << 1;
|
||||
|
||||
if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
|
||||
/*
|
||||
@ -4523,7 +4537,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"cannot rename '%s'"), zc.zc_name);
|
||||
|
||||
if (recursive && errno == EEXIST) {
|
||||
if (flags.recursive && errno == EEXIST) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"a child dataset already has a snapshot "
|
||||
"with the new name"));
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/zfs_onexit.h>
|
||||
#include <sys/zfs_vfsops.h>
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include <sys/zvol.h>
|
||||
#include <zfs_fletcher.h>
|
||||
@ -1408,3 +1409,8 @@ zfs_file_put(int fd)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
zfsvfs_update_fromname(const char *oldname, const char *newname)
|
||||
{
|
||||
}
|
||||
|
@ -44,9 +44,16 @@
|
||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||
.Nm
|
||||
.Cm rename
|
||||
.Op Fl fp
|
||||
.Fl p
|
||||
.Op Fl f
|
||||
.Ar filesystem Ns | Ns Ar volume
|
||||
.Ar filesystem Ns | Ns Ar volume
|
||||
.Nm
|
||||
.Cm rename
|
||||
.Fl u
|
||||
.Op Fl f
|
||||
.Ar filesystem
|
||||
.Ar filesystem
|
||||
.Sh DESCRIPTION
|
||||
.Bl -tag -width ""
|
||||
.It Xo
|
||||
@ -59,10 +66,19 @@
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm rename
|
||||
.Op Fl fp
|
||||
.Fl p
|
||||
.Op Fl f
|
||||
.Ar filesystem Ns | Ns Ar volume
|
||||
.Ar filesystem Ns | Ns Ar volume
|
||||
.Xc
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm rename
|
||||
.Fl u
|
||||
.Op Fl f
|
||||
.Ar filesystem
|
||||
.Ar filesystem
|
||||
.Xc
|
||||
Renames the given dataset.
|
||||
The new target can be located anywhere in the ZFS hierarchy, with the exception
|
||||
of snapshots.
|
||||
@ -73,12 +89,24 @@ Renamed file systems can inherit new mount points, in which case they are
|
||||
unmounted and remounted at the new mount point.
|
||||
.Bl -tag -width "-a"
|
||||
.It Fl f
|
||||
Force unmount any filesystems that need to be unmounted in the process.
|
||||
Force unmount any file systems that need to be unmounted in the process.
|
||||
This flag has no effect if used together with the
|
||||
.Fl u
|
||||
flag.
|
||||
.It Fl p
|
||||
Creates all the nonexistent parent datasets.
|
||||
Datasets created in this manner are automatically mounted according to the
|
||||
.Sy mountpoint
|
||||
property inherited from their parent.
|
||||
.It Fl u
|
||||
Do not remount file systems during rename.
|
||||
If a file system's
|
||||
.Sy mountpoint
|
||||
property is set to
|
||||
.Sy legacy
|
||||
or
|
||||
.Sy none ,
|
||||
the file system is not unmounted even if this option is not given.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
|
@ -96,6 +96,9 @@
|
||||
* which each have their own compilation environments and subsequent
|
||||
* requirements. Each of these environments must be considered when adding
|
||||
* dependencies from avl.c.
|
||||
*
|
||||
* Link to Illumos.org for more information on avl function:
|
||||
* [1] https://illumos.org/man/9f/avl
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -25,6 +25,15 @@
|
||||
* Copyright 2018 RackTop Systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Links to Illumos.org for more information on Interface Libraries:
|
||||
* [1] https://illumos.org/man/3lib/libnvpair
|
||||
* [2] https://illumos.org/man/3nvpair/nvlist_alloc
|
||||
* [3] https://illumos.org/man/9f/nvlist_alloc
|
||||
* [4] https://illumos.org/man/9f/nvlist_next_nvpair
|
||||
* [5] https://illumos.org/man/9f/nvpair_value_byte
|
||||
*/
|
||||
|
||||
#include <sys/debug.h>
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/nvpair.h>
|
||||
|
@ -22,6 +22,10 @@
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Links to Illumos.org for more information on kstat function:
|
||||
* [1] https://illumos.org/man/1M/kstat
|
||||
* [2] https://illumos.org/man/9f/kstat_create
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -34,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/kstat.h>
|
||||
#include <sys/sbuf.h>
|
||||
|
||||
static MALLOC_DEFINE(M_KSTAT, "kstat_data", "Kernel statistics");
|
||||
|
||||
@ -61,6 +66,156 @@ kstat_default_update(kstat_t *ksp, int rw)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_resize_raw(kstat_t *ksp)
|
||||
{
|
||||
if (ksp->ks_raw_bufsize == KSTAT_RAW_MAX)
|
||||
return (ENOMEM);
|
||||
|
||||
free(ksp->ks_raw_buf, M_TEMP);
|
||||
ksp->ks_raw_bufsize = MIN(ksp->ks_raw_bufsize * 2, KSTAT_RAW_MAX);
|
||||
ksp->ks_raw_buf = malloc(ksp->ks_raw_bufsize, M_TEMP, M_WAITOK);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void *
|
||||
kstat_raw_default_addr(kstat_t *ksp, loff_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
return (ksp->ks_data);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
kstat_t *ksp = arg1;
|
||||
kstat_named_t *ksent;
|
||||
uint64_t val;
|
||||
|
||||
ksent = ksp->ks_data;
|
||||
/* Select the correct element */
|
||||
ksent += arg2;
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
val = ksent->value.ui64;
|
||||
|
||||
return (sysctl_handle_64(oidp, &val, 0, req));
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl_string(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
kstat_t *ksp = arg1;
|
||||
kstat_named_t *ksent = ksp->ks_data;
|
||||
char *val;
|
||||
uint32_t len = 0;
|
||||
|
||||
/* Select the correct element */
|
||||
ksent += arg2;
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
val = KSTAT_NAMED_STR_PTR(ksent);
|
||||
len = KSTAT_NAMED_STR_BUFLEN(ksent);
|
||||
val[len-1] = '\0';
|
||||
|
||||
return (sysctl_handle_string(oidp, val, len, req));
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl_io(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf *sb;
|
||||
kstat_t *ksp = arg1;
|
||||
kstat_io_t *kip = ksp->ks_data;
|
||||
int rc;
|
||||
|
||||
sb = sbuf_new_auto();
|
||||
if (sb == NULL)
|
||||
return (ENOMEM);
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
|
||||
/* though wlentime & friends are signed, they will never be negative */
|
||||
sbuf_printf(sb,
|
||||
"%-8llu %-8llu %-8u %-8u %-8llu %-8llu "
|
||||
"%-8llu %-8llu %-8llu %-8llu %-8u %-8u\n",
|
||||
kip->nread, kip->nwritten,
|
||||
kip->reads, kip->writes,
|
||||
kip->wtime, kip->wlentime, kip->wlastupdate,
|
||||
kip->rtime, kip->rlentime, kip->rlastupdate,
|
||||
kip->wcnt, kip->rcnt);
|
||||
rc = sbuf_finish(sb);
|
||||
if (rc == 0)
|
||||
rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
|
||||
sbuf_delete(sb);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct sbuf *sb;
|
||||
void *data;
|
||||
kstat_t *ksp = arg1;
|
||||
void *(*addr_op)(kstat_t *ksp, loff_t index);
|
||||
int n, rc = 0;
|
||||
|
||||
sb = sbuf_new_auto();
|
||||
if (sb == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if (ksp->ks_raw_ops.addr)
|
||||
addr_op = ksp->ks_raw_ops.addr;
|
||||
else
|
||||
addr_op = kstat_raw_default_addr;
|
||||
|
||||
mutex_enter(ksp->ks_lock);
|
||||
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
|
||||
ksp->ks_raw_bufsize = PAGE_SIZE;
|
||||
ksp->ks_raw_buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
|
||||
|
||||
n = 0;
|
||||
restart_headers:
|
||||
if (ksp->ks_raw_ops.headers) {
|
||||
rc = ksp->ks_raw_ops.headers(
|
||||
ksp->ks_raw_buf, ksp->ks_raw_bufsize);
|
||||
if (rc == ENOMEM && !kstat_resize_raw(ksp))
|
||||
goto restart_headers;
|
||||
if (rc == 0)
|
||||
sbuf_printf(sb, "%s", ksp->ks_raw_buf);
|
||||
}
|
||||
|
||||
while ((data = addr_op(ksp, n)) != NULL) {
|
||||
restart:
|
||||
if (ksp->ks_raw_ops.data) {
|
||||
rc = ksp->ks_raw_ops.data(ksp->ks_raw_buf,
|
||||
ksp->ks_raw_bufsize, data);
|
||||
if (rc == ENOMEM && !kstat_resize_raw(ksp))
|
||||
goto restart;
|
||||
if (rc == 0)
|
||||
sbuf_printf(sb, "%s", ksp->ks_raw_buf);
|
||||
|
||||
} else {
|
||||
ASSERT(ksp->ks_ndata == 1);
|
||||
sbuf_hexdump(sb, ksp->ks_data,
|
||||
ksp->ks_data_size, NULL, 0);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
free(ksp->ks_raw_buf, M_TEMP);
|
||||
mutex_exit(ksp->ks_lock);
|
||||
rc = sbuf_finish(sb);
|
||||
if (rc == 0)
|
||||
rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
|
||||
sbuf_delete(sb);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
kstat_t *
|
||||
__kstat_create(const char *module, int instance, const char *name,
|
||||
const char *class, uchar_t ks_type, uint_t ks_ndata, uchar_t flags)
|
||||
@ -88,6 +243,9 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
ksp->ks_flags = flags;
|
||||
ksp->ks_update = kstat_default_update;
|
||||
|
||||
mutex_init(&ksp->ks_private_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
ksp->ks_lock = &ksp->ks_private_lock;
|
||||
|
||||
switch (ksp->ks_type) {
|
||||
case KSTAT_TYPE_RAW:
|
||||
ksp->ks_ndata = 1;
|
||||
@ -146,75 +304,38 @@ __kstat_create(const char *module, int instance, const char *name,
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, name, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n", __func__,
|
||||
module, class, name);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
if (ksp->ks_type == KSTAT_TYPE_NAMED) {
|
||||
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(root),
|
||||
OID_AUTO, name, CTLFLAG_RW, 0, "");
|
||||
if (root == NULL) {
|
||||
printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
|
||||
__func__, module, class, name);
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
free(ksp, M_KSTAT);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
}
|
||||
ksp->ks_sysctl_root = root;
|
||||
|
||||
return (ksp);
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
kstat_t *ksp = arg1;
|
||||
kstat_named_t *ksent = ksp->ks_data;
|
||||
uint64_t val;
|
||||
|
||||
/* Select the correct element */
|
||||
ksent += arg2;
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
val = ksent->value.ui64;
|
||||
|
||||
return (sysctl_handle_64(oidp, &val, 0, req));
|
||||
}
|
||||
|
||||
static int
|
||||
kstat_sysctl_string(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
kstat_t *ksp = arg1;
|
||||
kstat_named_t *ksent = ksp->ks_data;
|
||||
char *val;
|
||||
uint32_t len = 0;
|
||||
|
||||
/* Select the correct element */
|
||||
ksent += arg2;
|
||||
/* Update the aggsums before reading */
|
||||
(void) ksp->ks_update(ksp, KSTAT_READ);
|
||||
val = KSTAT_NAMED_STR_PTR(ksent);
|
||||
len = KSTAT_NAMED_STR_BUFLEN(ksent);
|
||||
val[len-1] = '\0';
|
||||
|
||||
return (sysctl_handle_string(oidp, val, len, req));
|
||||
}
|
||||
|
||||
void
|
||||
kstat_install(kstat_t *ksp)
|
||||
static void
|
||||
kstat_install_named(kstat_t *ksp)
|
||||
{
|
||||
kstat_named_t *ksent;
|
||||
char *namelast;
|
||||
int typelast;
|
||||
|
||||
ksent = ksp->ks_data;
|
||||
if (ksp->ks_ndata == UINT32_MAX) {
|
||||
#ifdef INVARIANTS
|
||||
printf("can't handle raw ops yet!!!\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (ksent == NULL) {
|
||||
printf("%s ksp->ks_data == NULL!!!!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
VERIFY((ksp->ks_flags & KSTAT_FLAG_VIRTUAL) || ksent != NULL);
|
||||
|
||||
typelast = 0;
|
||||
namelast = NULL;
|
||||
|
||||
for (int i = 0; i < ksp->ks_ndata; i++, ksent++) {
|
||||
if (ksent->data_type != 0) {
|
||||
typelast = ksent->data_type;
|
||||
@ -278,6 +399,51 @@ kstat_install(kstat_t *ksp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
kstat_install(kstat_t *ksp)
|
||||
{
|
||||
struct sysctl_oid *root;
|
||||
|
||||
if (ksp->ks_ndata == UINT32_MAX)
|
||||
VERIFY(ksp->ks_type == KSTAT_TYPE_RAW);
|
||||
|
||||
switch (ksp->ks_type) {
|
||||
case KSTAT_TYPE_NAMED:
|
||||
return (kstat_install_named(ksp));
|
||||
break;
|
||||
case KSTAT_TYPE_RAW:
|
||||
if (ksp->ks_raw_ops.data) {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_raw, "A", ksp->ks_name);
|
||||
} else {
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_OPAQUE | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_raw, "", ksp->ks_name);
|
||||
}
|
||||
VERIFY(root != NULL);
|
||||
break;
|
||||
case KSTAT_TYPE_IO:
|
||||
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
|
||||
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
|
||||
OID_AUTO, ksp->ks_name,
|
||||
CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
|
||||
kstat_sysctl_io, "A", ksp->ks_name);
|
||||
break;
|
||||
case KSTAT_TYPE_TIMER:
|
||||
case KSTAT_TYPE_INTR:
|
||||
default:
|
||||
panic("unsupported kstat type %d\n", ksp->ks_type);
|
||||
}
|
||||
ksp->ks_sysctl_root = root;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -285,6 +451,8 @@ kstat_delete(kstat_t *ksp)
|
||||
{
|
||||
|
||||
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
|
||||
ksp->ks_lock = NULL;
|
||||
mutex_destroy(&ksp->ks_private_lock);
|
||||
free(ksp, M_KSTAT);
|
||||
}
|
||||
|
||||
|
@ -242,12 +242,6 @@ zone_get_hostid(void *ptr)
|
||||
return ((uint32_t)curthread->td_ucred->cr_prison->pr_hostid);
|
||||
}
|
||||
|
||||
boolean_t
|
||||
in_globalzone(struct proc *p)
|
||||
{
|
||||
return (!jailed(FIRST_THREAD_IN_PROC((p))->td_ucred));
|
||||
}
|
||||
|
||||
static void
|
||||
zone_sysinit(void *arg __unused)
|
||||
{
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 iXsystems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/spa_impl.h>
|
||||
#include <sys/vdev_impl.h>
|
||||
#include <sys/spa.h>
|
||||
#include <zfs_comutil.h>
|
||||
|
||||
void
|
||||
spa_stats_init(spa_t *spa)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
spa_stats_destroy(spa_t *spa)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
spa_iostats_trim_add(spa_t *spa, trim_type_t type,
|
||||
uint64_t extents_written, uint64_t bytes_written,
|
||||
uint64_t extents_skipped, uint64_t bytes_skipped,
|
||||
uint64_t extents_failed, uint64_t bytes_failed)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
spa_read_history_add(spa_t *spa, const zbookmark_phys_t *zb, uint32_t aflags)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
spa_txg_history_add(spa_t *spa, uint64_t txg, hrtime_t birth_time)
|
||||
{
|
||||
|
||||
}
|
||||
/*
|
||||
* Set txg state completion time and increment current state.
|
||||
*/
|
||||
int
|
||||
spa_txg_history_set(spa_t *spa, uint64_t txg, txg_state_t completed_state,
|
||||
hrtime_t completed_time)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
txg_stat_t *
|
||||
spa_txg_history_init_io(spa_t *spa, uint64_t txg, dsl_pool_t *dp)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
spa_txg_history_fini_io(spa_t *spa, txg_stat_t *ts)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
spa_tx_assign_add_nsecs(spa_t *spa, uint64_t nsecs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
spa_mmp_history_add(spa_t *spa, uint64_t txg, uint64_t timestamp,
|
||||
uint64_t mmp_delay, vdev_t *vd, int label, uint64_t mmp_node_id,
|
||||
int error)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
spa_mmp_history_set(spa_t *spa, uint64_t mmp_node_id, int io_error,
|
||||
hrtime_t duration)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
spa_mmp_history_set_skip(spa_t *spa, uint64_t mmp_node_id)
|
||||
{
|
||||
return (0);
|
||||
}
|
@ -1267,193 +1267,6 @@ zfs_unregister_callbacks(zfsvfs_t *zfsvfs)
|
||||
dsl_prop_unregister_all(dmu_objset_ds(os), zfsvfs);
|
||||
}
|
||||
|
||||
#ifdef SECLABEL
|
||||
/*
|
||||
* Convert a decimal digit string to a uint64_t integer.
|
||||
*/
|
||||
static int
|
||||
str_to_uint64(char *str, uint64_t *objnum)
|
||||
{
|
||||
uint64_t num = 0;
|
||||
|
||||
while (*str) {
|
||||
if (*str < '0' || *str > '9')
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
num = num*10 + *str++ - '0';
|
||||
}
|
||||
|
||||
*objnum = num;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The boot path passed from the boot loader is in the form of
|
||||
* "rootpool-name/root-filesystem-object-number'. Convert this
|
||||
* string to a dataset name: "rootpool-name/root-filesystem-name".
|
||||
*/
|
||||
static int
|
||||
zfs_parse_bootfs(char *bpath, char *outpath)
|
||||
{
|
||||
char *slashp;
|
||||
uint64_t objnum;
|
||||
int error;
|
||||
|
||||
if (*bpath == 0 || *bpath == '/')
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
(void) strcpy(outpath, bpath);
|
||||
|
||||
slashp = strchr(bpath, '/');
|
||||
|
||||
/* if no '/', just return the pool name */
|
||||
if (slashp == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* if not a number, just return the root dataset name */
|
||||
if (str_to_uint64(slashp+1, &objnum)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
*slashp = '\0';
|
||||
error = dsl_dsobj_to_dsname(bpath, objnum, outpath);
|
||||
*slashp = '/';
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the hex label string is appropriate for the dataset being
|
||||
* mounted into the global_zone proper.
|
||||
*
|
||||
* Return an error if the hex label string is not default or
|
||||
* admin_low/admin_high. For admin_low labels, the corresponding
|
||||
* dataset must be readonly.
|
||||
*/
|
||||
int
|
||||
zfs_check_global_label(const char *dsname, const char *hexsl)
|
||||
{
|
||||
if (strcasecmp(hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
|
||||
return (0);
|
||||
if (strcasecmp(hexsl, ADMIN_HIGH) == 0)
|
||||
return (0);
|
||||
if (strcasecmp(hexsl, ADMIN_LOW) == 0) {
|
||||
/* must be readonly */
|
||||
uint64_t rdonly;
|
||||
|
||||
if (dsl_prop_get_integer(dsname,
|
||||
zfs_prop_to_name(ZFS_PROP_READONLY), &rdonly, NULL))
|
||||
return (SET_ERROR(EACCES));
|
||||
return (rdonly ? 0 : EACCES);
|
||||
}
|
||||
return (SET_ERROR(EACCES));
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the mount is allowed according to MAC check.
|
||||
* by comparing (where appropriate) label of the dataset against
|
||||
* the label of the zone being mounted into. If the dataset has
|
||||
* no label, create one.
|
||||
*
|
||||
* Returns 0 if access allowed, error otherwise (e.g. EACCES)
|
||||
*/
|
||||
static int
|
||||
zfs_mount_label_policy(vfs_t *vfsp, char *osname)
|
||||
{
|
||||
int error, retv;
|
||||
zone_t *mntzone = NULL;
|
||||
ts_label_t *mnt_tsl;
|
||||
bslabel_t *mnt_sl;
|
||||
bslabel_t ds_sl;
|
||||
char ds_hexsl[MAXNAMELEN];
|
||||
|
||||
retv = EACCES; /* assume the worst */
|
||||
|
||||
/*
|
||||
* Start by getting the dataset label if it exists.
|
||||
*/
|
||||
error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
|
||||
1, sizeof (ds_hexsl), &ds_hexsl, NULL);
|
||||
if (error)
|
||||
return (SET_ERROR(EACCES));
|
||||
|
||||
/*
|
||||
* If labeling is NOT enabled, then disallow the mount of datasets
|
||||
* which have a non-default label already. No other label checks
|
||||
* are needed.
|
||||
*/
|
||||
if (!is_system_labeled()) {
|
||||
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
|
||||
return (0);
|
||||
return (SET_ERROR(EACCES));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the label of the mountpoint. If mounting into the global
|
||||
* zone (i.e. mountpoint is not within an active zone and the
|
||||
* zoned property is off), the label must be default or
|
||||
* admin_low/admin_high only; no other checks are needed.
|
||||
*/
|
||||
mntzone = zone_find_by_any_path(vfsp->vfs_mntpt, B_FALSE);
|
||||
if (mntzone->zone_id == GLOBAL_ZONEID) {
|
||||
uint64_t zoned;
|
||||
|
||||
zone_rele(mntzone);
|
||||
|
||||
if (dsl_prop_get_integer(osname,
|
||||
zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
|
||||
return (SET_ERROR(EACCES));
|
||||
if (!zoned)
|
||||
return (zfs_check_global_label(osname, ds_hexsl));
|
||||
else
|
||||
/*
|
||||
* This is the case of a zone dataset being mounted
|
||||
* initially, before the zone has been fully created;
|
||||
* allow this mount into global zone.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
mnt_tsl = mntzone->zone_slabel;
|
||||
ASSERT(mnt_tsl != NULL);
|
||||
label_hold(mnt_tsl);
|
||||
mnt_sl = label2bslabel(mnt_tsl);
|
||||
|
||||
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0) {
|
||||
/*
|
||||
* The dataset doesn't have a real label, so fabricate one.
|
||||
*/
|
||||
char *str = NULL;
|
||||
|
||||
if (l_to_str_internal(mnt_sl, &str) == 0 &&
|
||||
dsl_prop_set_string(osname,
|
||||
zfs_prop_to_name(ZFS_PROP_MLSLABEL),
|
||||
ZPROP_SRC_LOCAL, str) == 0)
|
||||
retv = 0;
|
||||
if (str != NULL)
|
||||
kmem_free(str, strlen(str) + 1);
|
||||
} else if (hexstr_to_label(ds_hexsl, &ds_sl) == 0) {
|
||||
/*
|
||||
* Now compare labels to complete the MAC check. If the
|
||||
* labels are equal then allow access. If the mountpoint
|
||||
* label dominates the dataset label, allow readonly access.
|
||||
* Otherwise, access is denied.
|
||||
*/
|
||||
if (blequal(mnt_sl, &ds_sl))
|
||||
retv = 0;
|
||||
else if (bldominates(mnt_sl, &ds_sl)) {
|
||||
vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
|
||||
retv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
label_rele(mnt_tsl);
|
||||
zone_rele(mntzone);
|
||||
return (retv);
|
||||
}
|
||||
#endif /* SECLABEL */
|
||||
|
||||
static int
|
||||
getpoolname(const char *osname, char *poolname)
|
||||
{
|
||||
@ -1544,12 +1357,6 @@ zfs_mount(vfs_t *vfsp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef SECLABEL
|
||||
error = zfs_mount_label_policy(vfsp, osname);
|
||||
if (error)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
vfsp->vfs_flag |= MNT_NFS4ACLS;
|
||||
|
||||
/*
|
||||
|
@ -210,6 +210,7 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
|
||||
zvol_state_t *zv;
|
||||
int err = 0;
|
||||
boolean_t drop_suspend = B_TRUE;
|
||||
boolean_t drop_namespace = B_FALSE;
|
||||
|
||||
if (!zpool_on_zvol && tsd_get(zfs_geom_probe_vdev_key) != NULL) {
|
||||
/*
|
||||
@ -223,13 +224,28 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
|
||||
return (SET_ERROR(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
retry:
|
||||
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
||||
zv = pp->private;
|
||||
if (zv == NULL) {
|
||||
if (drop_namespace)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
rw_exit(&zvol_state_lock);
|
||||
return (SET_ERROR(ENXIO));
|
||||
}
|
||||
|
||||
if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
|
||||
/*
|
||||
* We need to guarantee that the namespace lock is held
|
||||
* to avoid spurious failures in zvol_first_open
|
||||
*/
|
||||
drop_namespace = B_TRUE;
|
||||
if (!mutex_tryenter(&spa_namespace_lock)) {
|
||||
rw_exit(&zvol_state_lock);
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
mutex_enter(&zv->zv_state_lock);
|
||||
|
||||
ASSERT(zv->zv_zso->zso_volmode == ZFS_VOLMODE_GEOM);
|
||||
@ -291,6 +307,8 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
|
||||
#endif
|
||||
|
||||
zv->zv_open_count += count;
|
||||
if (drop_namespace)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
mutex_exit(&zv->zv_state_lock);
|
||||
if (drop_suspend)
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
@ -300,6 +318,8 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
|
||||
if (zv->zv_open_count == 0)
|
||||
zvol_last_close(zv);
|
||||
out_mutex:
|
||||
if (drop_namespace)
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
mutex_exit(&zv->zv_state_lock);
|
||||
if (drop_suspend)
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
@ -606,7 +626,7 @@ zvol_geom_bio_strategy(struct bio *bp)
|
||||
addr = bp->bio_data;
|
||||
resid = bp->bio_length;
|
||||
|
||||
if (resid > 0 && (off < 0 || off >= volsize)) {
|
||||
if (resid > 0 && off >= volsize) {
|
||||
error = SET_ERROR(EIO);
|
||||
goto resume;
|
||||
}
|
||||
|
@ -22,6 +22,10 @@
|
||||
* with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Solaris Porting Layer (SPL) Kstat Implementation.
|
||||
*
|
||||
* Links to Illumos.org for more information on kstat function:
|
||||
* [1] https://illumos.org/man/1M/kstat
|
||||
* [2] https://illumos.org/man/9f/kstat_create
|
||||
*/
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
|
@ -14,7 +14,6 @@ $(MODULE)-objs += ../os/linux/zfs/qat.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/qat_compress.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/qat_crypt.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/spa_misc_os.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/spa_stats.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/vdev_disk.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/vdev_file.o
|
||||
$(MODULE)-objs += ../os/linux/zfs/zfs_acl.o
|
||||
|
@ -113,8 +113,7 @@ arc_free_memory(void)
|
||||
return (ptob(si.freeram - si.freehigh));
|
||||
#else
|
||||
return (ptob(nr_free_pages() +
|
||||
nr_inactive_file_pages() +
|
||||
nr_slab_reclaimable_pages()));
|
||||
nr_inactive_file_pages()));
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
}
|
||||
|
||||
|
@ -835,7 +835,9 @@ spa_mmp_history_add(spa_t *spa, uint64_t txg, uint64_t timestamp,
|
||||
static void *
|
||||
spa_state_addr(kstat_t *ksp, loff_t n)
|
||||
{
|
||||
return (ksp->ks_private); /* return the spa_t */
|
||||
if (n == 0)
|
||||
return (ksp->ks_private); /* return the spa_t */
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1026,22 +1028,16 @@ spa_stats_destroy(spa_t *spa)
|
||||
spa_mmp_history_destroy(spa);
|
||||
}
|
||||
|
||||
#if defined(_KERNEL)
|
||||
/* CSTYLED */
|
||||
module_param(zfs_read_history, int, 0644);
|
||||
MODULE_PARM_DESC(zfs_read_history,
|
||||
"Historical statistics for the last N reads");
|
||||
/* BEGIN CSTYLED */
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, read_history, INT, ZMOD_RW,
|
||||
"Historical statistics for the last N reads");
|
||||
|
||||
module_param(zfs_read_history_hits, int, 0644);
|
||||
MODULE_PARM_DESC(zfs_read_history_hits,
|
||||
"Include cache hits in read history");
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, read_history_hits, INT, ZMOD_RW,
|
||||
"Include cache hits in read history");
|
||||
|
||||
module_param(zfs_txg_history, int, 0644);
|
||||
MODULE_PARM_DESC(zfs_txg_history,
|
||||
"Historical statistics for the last N txgs");
|
||||
ZFS_MODULE_PARAM(zfs_txg, zfs_txg_, history, INT, ZMOD_RW,
|
||||
"Historical statistics for the last N txgs");
|
||||
|
||||
module_param(zfs_multihost_history, int, 0644);
|
||||
MODULE_PARM_DESC(zfs_multihost_history,
|
||||
"Historical statistics for last N multihost writes");
|
||||
ZFS_MODULE_PARAM(zfs_multihost, zfs_multihost_, history, INT, ZMOD_RW,
|
||||
"Historical statistics for last N multihost writes");
|
||||
/* END CSTYLED */
|
||||
#endif
|
||||
|
@ -2126,6 +2126,16 @@ zfs_get_vfs_flag_unmounted(objset_t *os)
|
||||
return (unmounted);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
zfsvfs_update_fromname(const char *oldname, const char *newname)
|
||||
{
|
||||
/*
|
||||
* We don't need to do anything here, the devname is always current by
|
||||
* virtue of zfsvfs->z_sb->s_op->show_devname.
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
zfs_init(void)
|
||||
{
|
||||
|
@ -182,6 +182,25 @@ zpl_remount_fs(struct super_block *sb, int *flags, char *data)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
__zpl_show_devname(struct seq_file *seq, zfsvfs_t *zfsvfs)
|
||||
{
|
||||
char *fsname;
|
||||
|
||||
fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
|
||||
dmu_objset_name(zfsvfs->z_os, fsname);
|
||||
seq_puts(seq, fsname);
|
||||
kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
zpl_show_devname(struct seq_file *seq, struct dentry *root)
|
||||
{
|
||||
return (__zpl_show_devname(seq, root->d_sb->s_fs_info));
|
||||
}
|
||||
|
||||
static int
|
||||
__zpl_show_options(struct seq_file *seq, zfsvfs_t *zfsvfs)
|
||||
{
|
||||
@ -314,6 +333,7 @@ const struct super_operations zpl_super_operations = {
|
||||
.sync_fs = zpl_sync_fs,
|
||||
.statfs = zpl_statfs,
|
||||
.remount_fs = zpl_remount_fs,
|
||||
.show_devname = zpl_show_devname,
|
||||
.show_options = zpl_show_options,
|
||||
.show_stats = NULL,
|
||||
};
|
||||
|
@ -76,6 +76,7 @@ $(MODULE)-objs += spa_errlog.o
|
||||
$(MODULE)-objs += spa_history.o
|
||||
$(MODULE)-objs += spa_log_spacemap.o
|
||||
$(MODULE)-objs += spa_misc.o
|
||||
$(MODULE)-objs += spa_stats.o
|
||||
$(MODULE)-objs += space_map.o
|
||||
$(MODULE)-objs += space_reftree.o
|
||||
$(MODULE)-objs += txg.o
|
||||
|
@ -2187,7 +2187,7 @@ arc_untransform(arc_buf_t *buf, spa_t *spa, const zbookmark_phys_t *zb,
|
||||
*/
|
||||
ret = SET_ERROR(EIO);
|
||||
spa_log_error(spa, zb);
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
spa, NULL, zb, NULL, 0, 0);
|
||||
}
|
||||
|
||||
@ -5652,7 +5652,8 @@ arc_read_done(zio_t *zio)
|
||||
error = SET_ERROR(EIO);
|
||||
if ((zio->io_flags & ZIO_FLAG_SPECULATIVE) == 0) {
|
||||
spa_log_error(zio->io_spa, &acb->acb_zb);
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
(void) zfs_ereport_post(
|
||||
FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
zio->io_spa, NULL, &acb->acb_zb, zio, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -5928,7 +5929,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
|
||||
rc = SET_ERROR(EIO);
|
||||
if ((zio_flags & ZIO_FLAG_SPECULATIVE) == 0) {
|
||||
spa_log_error(spa, zb);
|
||||
zfs_ereport_post(
|
||||
(void) zfs_ereport_post(
|
||||
FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
spa, NULL, zb, NULL, 0, 0);
|
||||
}
|
||||
|
@ -46,14 +46,12 @@
|
||||
#include <sys/sunddi.h>
|
||||
#include <sys/zfeature.h>
|
||||
#include <sys/policy.h>
|
||||
#include <sys/zfs_vfsops.h>
|
||||
#include <sys/zfs_znode.h>
|
||||
#include <sys/zvol.h>
|
||||
#include <sys/zthr.h>
|
||||
#include "zfs_namecheck.h"
|
||||
#include "zfs_prop.h"
|
||||
#ifdef _KERNEL
|
||||
#include <sys/zfs_vfsops.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Filesystem and Snapshot Limits
|
||||
@ -2124,6 +2122,8 @@ dsl_dir_rename_sync(void *arg, dmu_tx_t *tx)
|
||||
VERIFY0(zap_add(mos, dsl_dir_phys(newparent)->dd_child_dir_zapobj,
|
||||
dd->dd_myname, 8, 1, &dd->dd_object, tx));
|
||||
|
||||
/* TODO: A rename callback to avoid these layering violations. */
|
||||
zfsvfs_update_fromname(ddra->ddra_oldname, ddra->ddra_newname);
|
||||
zvol_rename_minors(dp->dp_spa, ddra->ddra_oldname,
|
||||
ddra->ddra_newname, B_TRUE);
|
||||
|
||||
|
@ -2868,7 +2868,8 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type)
|
||||
spa->spa_loaded_ts.tv_nsec = 0;
|
||||
}
|
||||
if (error != EBADF) {
|
||||
zfs_ereport_post(ereport, spa, NULL, NULL, NULL, 0, 0);
|
||||
(void) zfs_ereport_post(ereport, spa,
|
||||
NULL, NULL, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
spa->spa_load_state = error ? SPA_LOAD_ERROR : SPA_LOAD_NONE;
|
||||
|
@ -314,7 +314,8 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
|
||||
* resource issues are resolved.
|
||||
*/
|
||||
if (target->spa_ccw_fail_time == 0) {
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
|
||||
(void) zfs_ereport_post(
|
||||
FM_EREPORT_ZFS_CONFIG_CACHE_WRITE,
|
||||
target, NULL, NULL, NULL, 0, 0);
|
||||
}
|
||||
target->spa_ccw_fail_time = gethrtime();
|
||||
|
@ -1480,7 +1480,7 @@ vdev_probe_done(zio_t *zio)
|
||||
} else {
|
||||
ASSERT(zio->io_error != 0);
|
||||
vdev_dbgmsg(vd, "failed probe");
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE,
|
||||
spa, vd, NULL, NULL, 0, 0);
|
||||
zio->io_error = SET_ERROR(ENXIO);
|
||||
}
|
||||
@ -1860,7 +1860,8 @@ vdev_open(vdev_t *vd)
|
||||
*/
|
||||
if (vd->vdev_ashift > vd->vdev_top->vdev_ashift &&
|
||||
vd->vdev_ops->vdev_op_leaf) {
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
|
||||
(void) zfs_ereport_post(
|
||||
FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT,
|
||||
spa, vd, NULL, NULL, 0, 0);
|
||||
vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
||||
VDEV_AUX_BAD_LABEL);
|
||||
@ -4757,7 +4758,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux)
|
||||
class = FM_EREPORT_ZFS_DEVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
zfs_ereport_post(class, spa, vd, NULL, NULL,
|
||||
(void) zfs_ereport_post(class, spa, vd, NULL, NULL,
|
||||
save_state, 0);
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1403,7 @@ vdev_indirect_checksum_error(zio_t *zio,
|
||||
zio_bad_cksum_t zbc = {{{ 0 }}};
|
||||
abd_t *bad_abd = ic->ic_data;
|
||||
abd_t *good_abd = is->is_good_child->ic_data;
|
||||
zfs_ereport_post_checksum(zio->io_spa, vd, NULL, zio,
|
||||
(void) zfs_ereport_post_checksum(zio->io_spa, vd, NULL, zio,
|
||||
is->is_target_offset, is->is_size, good_abd, bad_abd, &zbc);
|
||||
}
|
||||
|
||||
@ -1478,8 +1478,8 @@ vdev_indirect_all_checksum_errors(zio_t *zio)
|
||||
vd->vdev_stat.vs_checksum_errors++;
|
||||
mutex_exit(&vd->vdev_stat_lock);
|
||||
|
||||
zfs_ereport_post_checksum(zio->io_spa, vd, NULL, zio,
|
||||
is->is_target_offset, is->is_size,
|
||||
(void) zfs_ereport_post_checksum(zio->io_spa, vd,
|
||||
NULL, zio, is->is_target_offset, is->is_size,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -1797,7 +1797,7 @@ raidz_checksum_error(zio_t *zio, raidz_col_t *rc, abd_t *bad_data)
|
||||
zbc.zbc_has_cksum = 0;
|
||||
zbc.zbc_injected = rm->rm_ecksuminjected;
|
||||
|
||||
zfs_ereport_post_checksum(zio->io_spa, vd,
|
||||
(void) zfs_ereport_post_checksum(zio->io_spa, vd,
|
||||
&zio->io_bookmark, zio, rc->rc_offset, rc->rc_size,
|
||||
rc->rc_abd, bad_data, &zbc);
|
||||
}
|
||||
|
@ -846,7 +846,7 @@ zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, const zbookmark_phys_t *zb,
|
||||
report->zcr_length = length;
|
||||
|
||||
#ifdef _KERNEL
|
||||
zfs_ereport_start(&report->zcr_ereport, &report->zcr_detector,
|
||||
(void) zfs_ereport_start(&report->zcr_ereport, &report->zcr_detector,
|
||||
FM_EREPORT_ZFS_CHECKSUM, spa, vd, zb, zio, offset, length);
|
||||
|
||||
if (report->zcr_ereport == NULL) {
|
||||
|
@ -4316,6 +4316,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
|
||||
objset_t *os;
|
||||
dmu_objset_type_t ost;
|
||||
boolean_t recursive = zc->zc_cookie & 1;
|
||||
boolean_t nounmount = !!(zc->zc_cookie & 2);
|
||||
char *at;
|
||||
int err;
|
||||
|
||||
@ -4341,7 +4342,7 @@ zfs_ioc_rename(zfs_cmd_t *zc)
|
||||
if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
|
||||
return (SET_ERROR(EXDEV));
|
||||
*at = '\0';
|
||||
if (ost == DMU_OST_ZFS) {
|
||||
if (ost == DMU_OST_ZFS && !nounmount) {
|
||||
error = dmu_objset_find(zc->zc_name,
|
||||
recursive_unmount, at + 1,
|
||||
recursive ? DS_FIND_CHILDREN : 0);
|
||||
|
@ -546,7 +546,7 @@ zio_decrypt(zio_t *zio, abd_t *data, uint64_t size)
|
||||
zio->io_error = SET_ERROR(EIO);
|
||||
if ((zio->io_flags & ZIO_FLAG_SPECULATIVE) == 0) {
|
||||
spa_log_error(spa, &zio->io_bookmark);
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION,
|
||||
spa, NULL, &zio->io_bookmark, zio, 0, 0);
|
||||
}
|
||||
} else {
|
||||
@ -2003,7 +2003,7 @@ zio_deadman_impl(zio_t *pio, int ziodepth)
|
||||
pio->io_stage, pio->io_pipeline, pio->io_pipeline_trace,
|
||||
zb->zb_objset, zb->zb_object, zb->zb_level, zb->zb_blkid,
|
||||
pio->io_offset, pio->io_size, pio->io_error);
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_DEADMAN,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_DEADMAN,
|
||||
pio->io_spa, vd, zb, pio, 0, 0);
|
||||
|
||||
if (failmode == ZIO_FAILURE_MODE_CONTINUE &&
|
||||
@ -2330,7 +2330,7 @@ zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason)
|
||||
cmn_err(CE_WARN, "Pool '%s' has encountered an uncorrectable I/O "
|
||||
"failure and has been suspended.\n", spa_name(spa));
|
||||
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL,
|
||||
NULL, NULL, 0, 0);
|
||||
|
||||
mutex_enter(&spa->spa_suspend_lock);
|
||||
@ -4541,7 +4541,7 @@ zio_done(zio_t *zio)
|
||||
zio->io_vd->vdev_stat.vs_slow_ios++;
|
||||
mutex_exit(&zio->io_vd->vdev_stat_lock);
|
||||
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_DELAY,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_DELAY,
|
||||
zio->io_spa, zio->io_vd, &zio->io_bookmark,
|
||||
zio, 0, 0);
|
||||
}
|
||||
@ -4565,7 +4565,7 @@ zio_done(zio_t *zio)
|
||||
}
|
||||
mutex_exit(&zio->io_vd->vdev_stat_lock);
|
||||
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_IO, zio->io_spa,
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_IO, zio->io_spa,
|
||||
zio->io_vd, &zio->io_bookmark, zio, 0, 0);
|
||||
}
|
||||
|
||||
@ -4577,8 +4577,8 @@ zio_done(zio_t *zio)
|
||||
* error and generate a logical data ereport.
|
||||
*/
|
||||
spa_log_error(zio->io_spa, &zio->io_bookmark);
|
||||
zfs_ereport_post(FM_EREPORT_ZFS_DATA, zio->io_spa,
|
||||
NULL, &zio->io_bookmark, zio, 0, 0);
|
||||
(void) zfs_ereport_post(FM_EREPORT_ZFS_DATA,
|
||||
zio->io_spa, NULL, &zio->io_bookmark, zio, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ tests = ['zfs_rename_001_pos', 'zfs_rename_002_pos', 'zfs_rename_003_pos',
|
||||
'zfs_rename_007_pos', 'zfs_rename_008_pos', 'zfs_rename_009_neg',
|
||||
'zfs_rename_010_neg', 'zfs_rename_011_pos', 'zfs_rename_012_neg',
|
||||
'zfs_rename_013_pos', 'zfs_rename_014_neg', 'zfs_rename_encrypted_child',
|
||||
'zfs_rename_to_encrypted', 'zfs_rename_mountpoint']
|
||||
'zfs_rename_to_encrypted', 'zfs_rename_mountpoint', 'zfs_rename_nounmount']
|
||||
tags = ['functional', 'cli_root', 'zfs_rename']
|
||||
|
||||
[tests/functional/cli_root/zfs_reservation]
|
||||
|
@ -54,7 +54,7 @@ MAX_MISSING_TVDS max_missing_tvds zfs_max_missing_tvds
|
||||
METASLAB_DEBUG_LOAD metaslab.debug_load metaslab_debug_load
|
||||
METASLAB_FORCE_GANGING metaslab.force_ganging metaslab_force_ganging
|
||||
MULTIHOST_FAIL_INTERVALS multihost.fail_intervals zfs_multihost_fail_intervals
|
||||
MULTIHOST_HISTORY UNSUPPORTED zfs_multihost_history
|
||||
MULTIHOST_HISTORY multihost.history zfs_multihost_history
|
||||
MULTIHOST_IMPORT_INTERVALS multihost.import_intervals zfs_multihost_import_intervals
|
||||
MULTIHOST_INTERVAL multihost.interval zfs_multihost_interval
|
||||
OVERRIDE_ESTIMATE_RECORDSIZE send.override_estimate_recordsize zfs_override_estimate_recordsize
|
||||
@ -73,7 +73,7 @@ SPA_LOAD_VERIFY_METADATA spa.load_verify_metadata spa_load_verify_metadata
|
||||
TRIM_EXTENT_BYTES_MIN trim.extent_bytes_min zfs_trim_extent_bytes_min
|
||||
TRIM_METASLAB_SKIP trim.metaslab_skip zfs_trim_metaslab_skip
|
||||
TRIM_TXG_BATCH trim.txg_batch zfs_trim_txg_batch
|
||||
TXG_HISTORY UNSUPPORTED zfs_txg_history
|
||||
TXG_HISTORY txg.history zfs_txg_history
|
||||
TXG_TIMEOUT txg.timeout zfs_txg_timeout
|
||||
UNLINK_SUSPEND_PROGRESS UNSUPPORTED zfs_unlink_suspend_progress
|
||||
VDEV_MIN_MS_COUNT vdev.min_ms_count zfs_vdev_min_ms_count
|
||||
|
@ -18,7 +18,8 @@ dist_pkgdata_SCRIPTS = \
|
||||
zfs_rename_014_neg.ksh \
|
||||
zfs_rename_encrypted_child.ksh \
|
||||
zfs_rename_to_encrypted.ksh \
|
||||
zfs_rename_mountpoint.ksh
|
||||
zfs_rename_mountpoint.ksh \
|
||||
zfs_rename_nounmount.ksh
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
zfs_rename.cfg \
|
||||
|
@ -34,8 +34,8 @@ verify_runnable "both"
|
||||
|
||||
function rename_cleanup
|
||||
{
|
||||
log_note zfs destroy -fR $TESTPOOL/rename_test
|
||||
log_note zfs destroy -fR $TESTPOOL/renamed
|
||||
zfs destroy -fR $TESTPOOL/rename_test
|
||||
zfs destroy -fR $TESTPOOL/renamed
|
||||
}
|
||||
|
||||
log_onexit rename_cleanup
|
||||
|
@ -0,0 +1,93 @@
|
||||
#!/bin/ksh -p
|
||||
#
|
||||
# CDDL HEADER START
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy is of the CDDL is also available via the Internet
|
||||
# at http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
# CDDL HEADER END
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2019 iXsystems, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# zfs rename -u should rename datasets without unmounting them
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a set of nested datasets.
|
||||
# 2. Verify datasets are mounted.
|
||||
# 3. Rename with -u and verify all datasets stayed mounted.
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
function rename_cleanup
|
||||
{
|
||||
cd $back
|
||||
zfs destroy -fR $TESTPOOL/rename_test
|
||||
zfs destroy -fR $TESTPOOL/renamed
|
||||
}
|
||||
|
||||
back=$(pwd)
|
||||
log_onexit rename_cleanup
|
||||
|
||||
log_must zfs create $TESTPOOL/rename_test
|
||||
log_must zfs create $TESTPOOL/rename_test/child
|
||||
log_must zfs create $TESTPOOL/rename_test/child/grandchild
|
||||
|
||||
if ! ismounted $TESTPOOL/rename_test; then
|
||||
log_fail "$TESTPOOL/rename_test is not mounted"
|
||||
fi
|
||||
if ! ismounted $TESTPOOL/rename_test/child; then
|
||||
log_fail "$TESTPOOL/rename_test/child is not mounted"
|
||||
fi
|
||||
if ! ismounted $TESTPOOL/rename_test/child/grandchild; then
|
||||
log_fail "$TESTPOOL/rename_test/child/grandchild is not mounted"
|
||||
fi
|
||||
|
||||
mntp_p=$(get_prop mountpoint $TESTPOOL/rename_test)
|
||||
mntp_c=$(get_prop mountpoint $TESTPOOL/rename_test/child)
|
||||
mntp_g=$(get_prop mountpoint $TESTPOOL/rename_test/child/grandchild)
|
||||
|
||||
log_must cd $mntp_g
|
||||
log_mustnot zfs rename $TESTPOOL/rename_test $TESTPOOL/renamed
|
||||
log_must zfs rename -u $TESTPOOL/rename_test $TESTPOOL/renamed
|
||||
|
||||
log_mustnot zfs list $TESTPOOL/rename_test
|
||||
log_mustnot zfs list $TESTPOOL/rename_test/child
|
||||
log_mustnot zfs list $TESTPOOL/rename_test/child/grandchild
|
||||
|
||||
log_must zfs list $TESTPOOL/renamed
|
||||
log_must zfs list $TESTPOOL/renamed/child
|
||||
log_must zfs list $TESTPOOL/renamed/child/grandchild
|
||||
|
||||
missing=$(zfs mount | awk -v pat=$TESTPOOL/renamed '$1 ~ pat' | awk \
|
||||
-v mntp_p=$mntp_p \
|
||||
-v mntp_c=$mntp_c \
|
||||
-v mntp_g=$mntp_g '
|
||||
BEGIN { p = c = g = 0 }
|
||||
$2 == mntp_p { p = 1 }
|
||||
$2 == mntp_c { c = 1 }
|
||||
$2 == mntp_g { g = 1 }
|
||||
END {
|
||||
if (p != 1)
|
||||
print mntp_p
|
||||
if (c != 1)
|
||||
print mntp_c
|
||||
if (g != 1)
|
||||
print mntp_g
|
||||
}')
|
||||
[[ -z "$missing" ]] || log_fail "Mountpoints no longer mounted: $missing"
|
||||
|
||||
log_pass "Verified rename -u does not unmount datasets"
|
Loading…
Reference in New Issue
Block a user