zfs: merge openzfs/zfs@c3b60eded (zfs-2.1-release) into stable/13

Notable upstream pull request merges:
  #12015 Replace zstreamdump with zstream link
  #12046 Improve scrub maxinflight_bytes math.
  #12052 FreeBSD: incorporate changes to the VFS_QUOTACTL(9) KPI
  #12072 Let zfs diff be more permissive
  #12091 libzfs: On FreeBSD, use MNT_NOWAIT with getfsstat
  #12104 Reminder to update boot code after zpool upgrade
  #12114 Introduce write-mostly sums
  #12125 Modernise all (most) remaining .TH manpages
  #12145 More aggsum optimizations
  #12149 Multiple man-pages: Move to appropriate section
  #12158 Re-embed multilist_t storage
  #12177 Livelist logic should handle dedup blkptrs
  #12196 Unify manpage makefiles, move pages to better sexions, revisit some
  #12212 Remove pool io kstats

Obtained from:	OpenZFS
OpenZFS commit:	c3b60ededa
OpenZFS tag:	zfs-2.1.0-rc7
This commit is contained in:
Martin Matuska 2021-06-13 04:47:27 +02:00
commit b0c251b0de
250 changed files with 11644 additions and 13939 deletions

View file

@ -36,6 +36,16 @@
# xargs -n1 | sort | uniq -d;
# done
# 20210613: Rename OpenZFS manual pages
OLD_FILES+=usr/share/man/man5/spl-module-parameters.5.gz
OLD_FILES+=usr/share/man/man5/zfs-events.5.gz
OLD_FILES+=usr/share/man/man5/zfs-module-parameters.5.gz
OLD_FILES+=usr/share/man/man8/zfsconcepts.8.gz
OLD_FILES+=usr/share/man/man8/zfsprops.8.gz
OLD_FILES+=usr/share/man/man5/zpool-features.5.gz
OLD_FILES+=usr/share/man/man8/zpoolconcepts.8.gz
OLD_FILES+=usr/share/man/man8/zpoolprops.8.gz
# 20210413: Remove pfctlinput2
OLD_FILES+=usr/share/man/man9/pfctlinput2.9.gz

View file

@ -3,6 +3,7 @@
ZFSTOP= ${SRCTOP}/sys/contrib/openzfs
.PATH: ${ZFSTOP}/cmd/zfs
.PATH: ${ZFSTOP}/man/man7
.PATH: ${ZFSTOP}/man/man8
.PATH: ${ZFSTOP}/module/os/freebsd/spl
@ -34,8 +35,8 @@ MAN= \
zfs-upgrade.8 \
zfs-userspace.8 \
zfs-wait.8 \
zfsconcepts.8 \
zfsprops.8
zfsconcepts.7 \
zfsprops.7
MLINKS= \
zfs-allow.8 zfs-unallow.8 \
zfs-hold.8 zfs-release.8 \

View file

@ -2,7 +2,9 @@
ZFSTOP= ${SRCTOP}/sys/contrib/openzfs
.PATH: ${ZFSTOP}/man/man4
.PATH: ${ZFSTOP}/man/man5
.PATH: ${ZFSTOP}/man/man7
.PATH: ${ZFSTOP}/man/man8
.PATH: ${ZFSTOP}/cmd/zpool
.PATH: ${ZFSTOP}/cmd/zpool/os/freebsd
@ -11,9 +13,8 @@ ZFSTOP= ${SRCTOP}/sys/contrib/openzfs
PACKAGE= runtime
PROG= zpool
MAN= \
spl-module-parameters.5 \
zfs-events.5 \
zfs-module-parameters.5 \
spl.4 \
zfs.4 \
zpool.8 \
zpool-add.8 \
zpool-attach.8 \
@ -24,7 +25,7 @@ MAN= \
zpool-detach.8 \
zpool-events.8 \
zpool-export.8 \
zpool-features.5 \
zpool-features.7 \
zpool-get.8 \
zpool-history.8 \
zpool-import.8 \
@ -45,8 +46,8 @@ MAN= \
zpool-trim.8 \
zpool-upgrade.8 \
zpool-wait.8 \
zpoolconcepts.8 \
zpoolprops.8
zpoolconcepts.7 \
zpoolprops.7
MLINKS= \
zpool-offline.8 zpool-online.8 \
zpool-get.8 zpool-set.8

View file

@ -8,7 +8,6 @@ SUBDIR= \
ctfmerge \
${_zinject} \
${_zstream} \
${_zstreamdump} \
${_ztest}
SUBDIR.${MK_TESTS}+= tests
@ -17,7 +16,6 @@ SUBDIR.${MK_TESTS}+= tests
_zinject= zinject
_ztest= ztest
_zstream = zstream
_zstreamdump = zstreamdump
.endif
SUBDIR_PARALLEL=

View file

@ -7,6 +7,7 @@ ZFSTOP= ${SRCTOP}/sys/contrib/openzfs
PROG= zstream
MAN= zstream.8
MLINKS= zstream.8 zstreamdump.8
INCS= zstream.h
SRCS= \
zstream.c \
@ -14,6 +15,8 @@ SRCS= \
zstream_redup.c \
zstream_token.c
SYMLINKS= ${BINDIR}/zstream ${BINDIR}/zstreamdump
WARNS?= 2
CFLAGS+= \
-DIN_BASE \

View file

@ -1,11 +0,0 @@
# $FreeBSD$
ZFSTOP= ${SRCTOP}/sys/contrib/openzfs
.PATH: ${ZFSTOP}/cmd/zstreamdump
.PATH: ${ZFSTOP}/man/man8
SCRIPTS= zstreamdump
MAN= zstreamdump.8
.include <bsd.prog.mk>

View file

@ -1,25 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
cddl/lib/libavl \
cddl/lib/libnvpair \
cddl/lib/libumem \
cddl/lib/libzpool \
gnu/lib/csu \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
lib/libmd \
lib/libthr \
lib/libz \
lib/msun \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View file

@ -10,5 +10,5 @@ contact_links:
url: https://lists.freebsd.org/mailman/listinfo/freebsd-fs
about: Get community support for OpenZFS on FreeBSD
- name: OpenZFS on IRC
url: https://webchat.freenode.net/#openzfs
url: https://kiwiirc.com/nextclient/irc.libera.chat/openzfs
about: Use IRC to get community support for OpenZFS

View file

@ -2,7 +2,7 @@ Meta: 1
Name: zfs
Branch: 1.0
Version: 2.1.0
Release: rc6
Release: rc7
Release-Tags: relext
License: CDDL
Author: OpenZFS

View file

@ -1,3 +1,5 @@
include $(top_srcdir)/config/Shellcheck.am
ACLOCAL_AMFLAGS = -I config
SUBDIRS = include
@ -6,7 +8,7 @@ SUBDIRS += rpm
endif
if CONFIG_USER
SUBDIRS += etc man scripts lib tests cmd contrib
SUBDIRS += man scripts lib tests cmd etc contrib
if BUILD_LINUX
SUBDIRS += udev
endif
@ -123,17 +125,8 @@ cstyle:
filter_executable = -exec test -x '{}' \; -print
PHONY += shellcheck
shellcheck:
@if type shellcheck > /dev/null 2>&1; then \
shellcheck --exclude=SC1090 --exclude=SC1117 --format=gcc \
$$(find ${top_srcdir}/scripts/*.sh -type f) \
$$(find ${top_srcdir}/cmd/zed/zed.d/*.sh -type f) \
$$(find ${top_srcdir}/cmd/zpool/zpool.d/* \
-type f ${filter_executable}); \
else \
echo "skipping shellcheck because shellcheck is not installed"; \
fi
SHELLCHECKDIRS = cmd contrib etc scripts tests
SHELLCHECKSCRIPTS = autogen.sh
PHONY += checkabi storeabi
checkabi: lib
@ -142,38 +135,9 @@ checkabi: lib
storeabi: lib
$(MAKE) -C lib storeabi
PHONY += checkbashisms
checkbashisms:
@if type checkbashisms > /dev/null 2>&1; then \
checkbashisms -n -p -x \
$$(find ${top_srcdir} \
-name '.git' -prune \
-o -name 'build' -prune \
-o -name 'tests' -prune \
-o -name 'config' -prune \
-o -name 'zed-functions.sh*' -prune \
-o -name 'zfs-import*' -prune \
-o -name 'zfs-mount*' -prune \
-o -name 'zfs-zed*' -prune \
-o -name 'smart' -prune \
-o -name 'paxcheck.sh' -prune \
-o -name 'make_gitrev.sh' -prune \
-o -name '90zfs' -prune \
-o -type f ! -name 'config*' \
! -name 'libtool' \
-exec sh -c 'awk "NR==1 && /#!.*bin\/sh.*/ {print FILENAME;}" "{}"' \;); \
else \
echo "skipping checkbashisms because checkbashisms is not installed"; \
fi
PHONY += mancheck
mancheck:
@if type mandoc > /dev/null 2>&1; then \
find ${top_srcdir}/man/man8 -type f -name '*[1-9]*' \
-exec mandoc -Tlint -Werror {} \+; \
else \
echo "skipping mancheck because mandoc is not installed"; \
fi
${top_srcdir}/scripts/mancheck.sh ${top_srcdir}/man ${top_srcdir}/tests/test-runner/man
if BUILD_LINUX
stat_fmt = -c '%A %n'

View file

@ -1,10 +1,15 @@
SUBDIRS = zfs zpool zdb zhack zinject zstream zstreamdump ztest
include $(top_srcdir)/config/Shellcheck.am
SUBDIRS = zfs zpool zdb zhack zinject zstream ztest
SUBDIRS += fsck_zfs vdev_id raidz_test zfs_ids_to_path
SUBDIRS += zpool_influxdb
CPPCHECKDIRS = zfs zpool zdb zhack zinject zstream ztest
CPPCHECKDIRS += raidz_test zfs_ids_to_path zpool_influxdb
# TODO: #12084: SHELLCHECKDIRS = fsck_zfs vdev_id zpool
SHELLCHECKDIRS = fsck_zfs zpool
if USING_PYTHON
SUBDIRS += arcstat arc_summary dbufstat
endif
@ -12,6 +17,7 @@ endif
if BUILD_LINUX
SUBDIRS += mount_zfs zed zgenhostid zvol_id zvol_wait
CPPCHECKDIRS += mount_zfs zed zgenhostid zvol_id
SHELLCHECKDIRS += zed
endif
PHONY = cppcheck

View file

@ -42,6 +42,7 @@ import os
import subprocess
import sys
import time
import errno
# We can't use env -S portably, and we need python3 -u to handle pipes in
# the shell abruptly closing the way we want to, so...
@ -239,6 +240,11 @@ def handle_Exception(ex_cls, ex, tb):
# It turns out that while sys.exit() triggers an exception
# not handled message on Python 3.8+, os._exit() does not.
os._exit(0)
if ex_cls is OSError:
if ex.errno == errno.ENOTCONN:
sys.exit()
raise ex
if hasattr(sys,'unraisablehook'): # Python 3.8+

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
dist_sbin_SCRIPTS = fsck.zfs

View file

@ -26,15 +26,15 @@ for dataset in "$@"; do
case "$(@sbindir@/zpool list -Ho health "$pool")" in
DEGRADED)
ret=$(( $ret | 4 ))
ret=$(( ret | 4 ))
;;
FAULTED)
awk '!/^([[:space:]]*#.*)?$/ && $1 == "'"$dataset"'" && $3 == "zfs" {exit 1}' /etc/fstab || \
ret=$(( $ret | 8 ))
ret=$(( ret | 8 ))
;;
"")
# Pool not found, error printed by zpool(8)
ret=$(( $ret | 8 ))
ret=$(( ret | 8 ))
;;
*)
;;

View file

@ -1 +1,3 @@
include $(top_srcdir)/config/Shellcheck.am
dist_udev_SCRIPTS = vdev_id

View file

@ -162,12 +162,6 @@ static int dump_bpobj_cb(void *arg, const blkptr_t *bp, boolean_t free,
dmu_tx_t *tx);
typedef struct sublivelist_verify {
/* all ALLOC'd blkptr_t in one sub-livelist */
zfs_btree_t sv_all_allocs;
/* all FREE'd blkptr_t in one sub-livelist */
zfs_btree_t sv_all_frees;
/* FREE's that haven't yet matched to an ALLOC, in one sub-livelist */
zfs_btree_t sv_pair;
@ -226,29 +220,68 @@ typedef struct sublivelist_verify_block {
static void zdb_print_blkptr(const blkptr_t *bp, int flags);
typedef struct sublivelist_verify_block_refcnt {
/* block pointer entry in livelist being verified */
blkptr_t svbr_blk;
/*
* Refcount gets incremented to 1 when we encounter the first
* FREE entry for the svfbr block pointer and a node for it
* is created in our ZDB verification/tracking metadata.
*
* As we encounter more FREE entries we increment this counter
* and similarly decrement it whenever we find the respective
* ALLOC entries for this block.
*
* When the refcount gets to 0 it means that all the FREE and
* ALLOC entries of this block have paired up and we no longer
* need to track it in our verification logic (e.g. the node
* containing this struct in our verification data structure
* should be freed).
*
* [refer to sublivelist_verify_blkptr() for the actual code]
*/
uint32_t svbr_refcnt;
} sublivelist_verify_block_refcnt_t;
static int
sublivelist_block_refcnt_compare(const void *larg, const void *rarg)
{
const sublivelist_verify_block_refcnt_t *l = larg;
const sublivelist_verify_block_refcnt_t *r = rarg;
return (livelist_compare(&l->svbr_blk, &r->svbr_blk));
}
static int
sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
dmu_tx_t *tx)
{
ASSERT3P(tx, ==, NULL);
struct sublivelist_verify *sv = arg;
char blkbuf[BP_SPRINTF_LEN];
sublivelist_verify_block_refcnt_t current = {
.svbr_blk = *bp,
/*
* Start with 1 in case this is the first free entry.
* This field is not used for our B-Tree comparisons
* anyway.
*/
.svbr_refcnt = 1,
};
zfs_btree_index_t where;
sublivelist_verify_block_refcnt_t *pair =
zfs_btree_find(&sv->sv_pair, &current, &where);
if (free) {
zfs_btree_add(&sv->sv_pair, bp);
/* Check if the FREE is a duplicate */
if (zfs_btree_find(&sv->sv_all_frees, bp, &where) != NULL) {
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
free);
(void) printf("\tERROR: Duplicate FREE: %s\n", blkbuf);
if (pair == NULL) {
/* first free entry for this block pointer */
zfs_btree_add(&sv->sv_pair, &current);
} else {
zfs_btree_add_idx(&sv->sv_all_frees, bp, &where);
pair->svbr_refcnt++;
}
} else {
/* Check if the ALLOC has been freed */
if (zfs_btree_find(&sv->sv_pair, bp, &where) != NULL) {
zfs_btree_remove_idx(&sv->sv_pair, &where);
} else {
if (pair == NULL) {
/* block that is currently marked as allocated */
for (int i = 0; i < SPA_DVAS_PER_BP; i++) {
if (DVA_IS_EMPTY(&bp->blk_dva[i]))
break;
@ -263,16 +296,16 @@ sublivelist_verify_blkptr(void *arg, const blkptr_t *bp, boolean_t free,
&svb, &where);
}
}
}
/* Check if the ALLOC is a duplicate */
if (zfs_btree_find(&sv->sv_all_allocs, bp, &where) != NULL) {
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp,
free);
(void) printf("\tERROR: Duplicate ALLOC: %s\n", blkbuf);
} else {
zfs_btree_add_idx(&sv->sv_all_allocs, bp, &where);
/* alloc matches a free entry */
pair->svbr_refcnt--;
if (pair->svbr_refcnt == 0) {
/* all allocs and frees have been matched */
zfs_btree_remove_idx(&sv->sv_pair, &where);
}
}
}
return (0);
}
@ -280,32 +313,22 @@ static int
sublivelist_verify_func(void *args, dsl_deadlist_entry_t *dle)
{
int err;
char blkbuf[BP_SPRINTF_LEN];
struct sublivelist_verify *sv = args;
zfs_btree_create(&sv->sv_all_allocs, livelist_compare,
sizeof (blkptr_t));
zfs_btree_create(&sv->sv_all_frees, livelist_compare,
sizeof (blkptr_t));
zfs_btree_create(&sv->sv_pair, livelist_compare,
sizeof (blkptr_t));
zfs_btree_create(&sv->sv_pair, sublivelist_block_refcnt_compare,
sizeof (sublivelist_verify_block_refcnt_t));
err = bpobj_iterate_nofree(&dle->dle_bpobj, sublivelist_verify_blkptr,
sv, NULL);
zfs_btree_clear(&sv->sv_all_allocs);
zfs_btree_destroy(&sv->sv_all_allocs);
zfs_btree_clear(&sv->sv_all_frees);
zfs_btree_destroy(&sv->sv_all_frees);
blkptr_t *e;
sublivelist_verify_block_refcnt_t *e;
zfs_btree_index_t *cookie = NULL;
while ((e = zfs_btree_destroy_nodes(&sv->sv_pair, &cookie)) != NULL) {
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), e, B_TRUE);
(void) printf("\tERROR: Unmatched FREE: %s\n", blkbuf);
char blkbuf[BP_SPRINTF_LEN];
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf),
&e->svbr_blk, B_TRUE);
(void) printf("\tERROR: %d unmatched FREE(s): %s\n",
e->svbr_refcnt, blkbuf);
}
zfs_btree_destroy(&sv->sv_pair);
@ -614,10 +637,14 @@ mv_populate_livelist_allocs(metaslab_verify_t *mv, sublivelist_verify_t *sv)
/*
* [Livelist Check]
* Iterate through all the sublivelists and:
* - report leftover frees
* - report double ALLOCs/FREEs
* - report leftover frees (**)
* - record leftover ALLOCs together with their TXG [see Cross Check]
*
* (**) Note: Double ALLOCs are valid in datasets that have dedup
* enabled. Similarly double FREEs are allowed as well but
* only if they pair up with a corresponding ALLOC entry once
* we our done with our sublivelist iteration.
*
* [Spacemap Check]
* for each metaslab:
* - iterate over spacemap and then the metaslab's entries in the

View file

@ -1,8 +1,10 @@
include $(top_srcdir)/config/Rules.am
include $(top_srcdir)/config/Shellcheck.am
AM_CFLAGS += $(LIBUDEV_CFLAGS) $(LIBUUID_CFLAGS)
SUBDIRS = zed.d
SHELLCHECKDIRS = $(SUBDIRS)
sbin_PROGRAMS = zed

View file

@ -1,5 +1,6 @@
include $(top_srcdir)/config/Rules.am
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
EXTRA_DIST += README
@ -51,3 +52,6 @@ install-data-hook:
ln -s "$(zedexecdir)/$${f}" "$(DESTDIR)$(zedconfdir)"; \
done
chmod 0600 "$(DESTDIR)$(zedconfdir)/zed.rc"
# False positive: 1>&"${ZED_FLOCK_FD}" looks suspiciously similar to a >&filename bash extension
CHECKBASHISMS_IGNORE = -e 'should be >word 2>&1' -e '&"$${ZED_FLOCK_FD}"'

View file

@ -12,15 +12,11 @@
zed_exit_if_ignoring_this_event
lockfile="$(basename -- "${ZED_DEBUG_LOG}").lock"
zed_lock "${ZED_DEBUG_LOG}"
{
printenv | sort
echo
} 1>&"${ZED_FLOCK_FD}"
zed_unlock "${ZED_DEBUG_LOG}"
umask 077
zed_lock "${lockfile}"
exec >> "${ZED_DEBUG_LOG}"
printenv | sort
echo
exec >&-
zed_unlock "${lockfile}"
exit 0

View file

@ -42,6 +42,7 @@ fi
msg="${msg} delay=$((ZEVENT_ZIO_DELAY / 1000000))ms"
# list the bookmark data together
# shellcheck disable=SC2153
[ -n "${ZEVENT_ZIO_OBJSET}" ] && \
msg="${msg} bookmark=${ZEVENT_ZIO_OBJSET}:${ZEVENT_ZIO_OBJECT}:${ZEVENT_ZIO_LEVEL}:${ZEVENT_ZIO_BLKID}"

View file

@ -3,9 +3,8 @@
# Track changes to enumerated pools for use in early-boot
set -ef
FSLIST_DIR="@sysconfdir@/zfs/zfs-list.cache"
FSLIST_TMP="@runstatedir@/zfs-list.cache.new"
FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}"
FSLIST="@sysconfdir@/zfs/zfs-list.cache/${ZEVENT_POOL}"
FSLIST_TMP="@runstatedir@/zfs-list.cache@${ZEVENT_POOL}"
# If the pool specific cache file is not writeable, abort
[ -w "${FSLIST}" ] || exit 0
@ -19,15 +18,15 @@ zed_check_cmd "${ZFS}" sort diff
# If we are acting on a snapshot, we have nothing to do
[ "${ZEVENT_HISTORY_DSNAME%@*}" = "${ZEVENT_HISTORY_DSNAME}" ] || exit 0
# We obtain a lock on zfs-list to avoid any simultaneous writes.
# We lock the output file to avoid simultaneous writes.
# If we run into trouble, log and drop the lock
abort_alter() {
zed_log_msg "Error updating zfs-list.cache!"
zed_unlock zfs-list
zed_log_msg "Error updating zfs-list.cache for ${ZEVENT_POOL}!"
zed_unlock "${FSLIST}"
}
finished() {
zed_unlock zfs-list
zed_unlock "${FSLIST}"
trap - EXIT
exit 0
}
@ -37,7 +36,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
;;
export)
zed_lock zfs-list
zed_lock "${FSLIST}"
trap abort_alter EXIT
echo > "${FSLIST}"
finished
@ -63,7 +62,7 @@ case "${ZEVENT_HISTORY_INTERNAL_NAME}" in
;;
esac
zed_lock zfs-list
zed_lock "${FSLIST}"
trap abort_alter EXIT
PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
@ -79,7 +78,7 @@ PROPS="name,mountpoint,canmount,atime,relatime,devices,exec\
sort "${FSLIST_TMP}" -o "${FSLIST_TMP}"
# Don't modify the file if it hasn't changed
diff -q "${FSLIST_TMP}" "${FSLIST}" || mv "${FSLIST_TMP}" "${FSLIST}"
diff -q "${FSLIST_TMP}" "${FSLIST}" || cat "${FSLIST_TMP}" > "${FSLIST}"
rm -f "${FSLIST_TMP}"
finished

View file

@ -126,10 +126,8 @@ zed_lock()
# Obtain a lock on the file bound to the given file descriptor.
#
eval "exec ${fd}> '${lockfile}'"
err="$(flock --exclusive "${fd}" 2>&1)"
# shellcheck disable=SC2181
if [ $? -ne 0 ]; then
eval "exec ${fd}>> '${lockfile}'"
if ! err="$(flock --exclusive "${fd}" 2>&1)"; then
zed_log_err "failed to lock \"${lockfile}\": ${err}"
fi
@ -165,9 +163,7 @@ zed_unlock()
fi
# Release the lock and close the file descriptor.
err="$(flock --unlock "${fd}" 2>&1)"
# shellcheck disable=SC2181
if [ $? -ne 0 ]; then
if ! err="$(flock --unlock "${fd}" 2>&1)"; then
zed_log_err "failed to unlock \"${lockfile}\": ${err}"
fi
eval "exec ${fd}>&-"
@ -267,7 +263,7 @@ zed_notify_email()
-e "s/@SUBJECT@/${subject}/g")"
# shellcheck disable=SC2086
eval "${ZED_EMAIL_PROG}" ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
${ZED_EMAIL_PROG} ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
rv=$?
if [ "${rv}" -ne 0 ]; then
zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}"

View file

@ -728,6 +728,32 @@ finish_progress(char *done)
pt_header = NULL;
}
/* This function checks if the passed fd refers to /dev/null or /dev/zero */
#ifdef __linux__
static boolean_t
is_dev_nullzero(int fd)
{
struct stat st;
fstat(fd, &st);
return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ ||
minor(st.st_rdev) == 5 /* zero */));
}
#endif
static void
note_dev_error(int err, int fd)
{
#ifdef __linux__
if (err == EINVAL && is_dev_nullzero(fd)) {
(void) fprintf(stderr,
gettext("Error: Writing directly to /dev/{null,zero} files"
" on certain kernels is not currently implemented.\n"
"(As a workaround, "
"try \"zfs send [...] | cat > /dev/null\")\n"));
}
#endif
}
static int
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
{
@ -4572,11 +4598,16 @@ zfs_do_send(int argc, char **argv)
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
resume_token);
if (err != 0)
note_dev_error(errno, STDOUT_FILENO);
zfs_close(zhp);
return (err != 0);
} else if (resume_token != NULL) {
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
resume_token));
err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
resume_token);
if (err != 0)
note_dev_error(errno, STDOUT_FILENO);
return (err);
}
if (flags.skipmissing && !flags.replicate) {
@ -4627,6 +4658,8 @@ zfs_do_send(int argc, char **argv)
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
redactbook);
zfs_close(zhp);
if (err != 0)
note_dev_error(errno, STDOUT_FILENO);
return (err != 0);
}
@ -4703,6 +4736,7 @@ zfs_do_send(int argc, char **argv)
nvlist_free(dbgnv);
}
zfs_close(zhp);
note_dev_error(errno, STDOUT_FILENO);
return (err != 0);
}

View file

@ -36,8 +36,6 @@
#include <time.h>
#include <unistd.h>
static void usage(void);
static void
usage(void)
{
@ -60,12 +58,11 @@ int
main(int argc, char **argv)
{
/* default file path, can be optionally set by user */
char path[PATH_MAX] = "/etc/hostid";
const char *path = "/etc/hostid";
/* holds converted user input or lrand48() generated value */
unsigned long input_i = 0;
int opt;
int pathlen;
int force_fwrite = 0;
while ((opt = getopt_long(argc, argv, "fo:h?", 0, 0)) != -1) {
switch (opt) {
@ -73,14 +70,7 @@ main(int argc, char **argv)
force_fwrite = 1;
break;
case 'o':
pathlen = snprintf(path, sizeof (path), "%s", optarg);
if (pathlen >= sizeof (path)) {
fprintf(stderr, "%s\n", strerror(EOVERFLOW));
exit(EXIT_FAILURE);
} else if (pathlen < 1) {
fprintf(stderr, "%s\n", strerror(EINVAL));
exit(EXIT_FAILURE);
}
path = optarg;
break;
case 'h':
case '?':
@ -118,7 +108,7 @@ main(int argc, char **argv)
if (force_fwrite == 0 && stat(path, &fstat) == 0 &&
S_ISREG(fstat.st_mode)) {
fprintf(stderr, "%s: %s\n", path, strerror(EEXIST));
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
/*

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Rules.am
include $(top_srcdir)/config/Shellcheck.am
AM_CFLAGS += $(LIBBLKID_CFLAGS) $(LIBUUID_CFLAGS)

View file

@ -101,3 +101,18 @@ check_sector_size_database(char *path, int *sector_size)
{
return (0);
}
void
after_zpool_upgrade(zpool_handle_t *zhp)
{
char bootfs[ZPOOL_MAXPROPLEN];
if (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
sizeof (bootfs), NULL, B_FALSE) == 0 &&
strcmp(bootfs, "-") != 0) {
(void) printf(gettext("Pool '%s' has the bootfs "
"property set, you might need to update\nthe boot "
"code. See gptzfsboot(8) and loader.efi(8) for "
"details.\n"), zpool_get_name(zhp));
}
}

View file

@ -405,3 +405,8 @@ check_device(const char *path, boolean_t force,
return (error);
}
void
after_zpool_upgrade(zpool_handle_t *zhp)
{
}

View file

@ -53,7 +53,7 @@ get_filename_from_dir()
num_files=$(find "$dir" -maxdepth 1 -type f | wc -l)
mod=$((pid % num_files))
i=0
find "$dir" -type f -printf "%f\n" | while read -r file ; do
find "$dir" -type f -printf '%f\n' | while read -r file ; do
if [ "$mod" = "$i" ] ; then
echo "$file"
break
@ -62,17 +62,14 @@ get_filename_from_dir()
done
}
script=$(basename "$0")
script="${0##*/}"
if [ "$1" = "-h" ] ; then
echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
exit
fi
smartctl_path=$(command -v smartctl)
# shellcheck disable=SC2015
if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then
if [ -b "$VDEV_UPATH" ] && PATH="/usr/sbin:$PATH" command -v smartctl > /dev/null || [ -n "$samples" ] ; then
if [ -n "$samples" ] ; then
# cat a smartctl output text file instead of running smartctl
# on a vdev (only used for developer testing).
@ -80,7 +77,7 @@ if [ -b "$VDEV_UPATH" ] && [ -x "$smartctl_path" ] || [ -n "$samples" ] ; then
echo "file=$file"
raw_out=$(cat "$samples/$file")
else
raw_out=$(eval "sudo $smartctl_path -a $VDEV_UPATH")
raw_out=$(sudo smartctl -a "$VDEV_UPATH")
fi
# What kind of drive are we? Look for the right line in smartctl:
@ -231,11 +228,11 @@ esac
with_vals=$(echo "$out" | grep -E "$scripts")
if [ -n "$with_vals" ]; then
echo "$with_vals"
without_vals=$(echo "$scripts" | tr "|" "\n" |
without_vals=$(echo "$scripts" | tr '|' '\n' |
grep -v -E "$(echo "$with_vals" |
awk -F "=" '{print $1}')" | awk '{print $0"="}')
else
without_vals=$(echo "$scripts" | tr "|" "\n" | awk '{print $0"="}')
without_vals=$(echo "$scripts" | tr '|' '\n' | awk '{print $0"="}')
fi
if [ -n "$without_vals" ]; then

View file

@ -533,7 +533,7 @@ usage(boolean_t requested)
(void) fprintf(fp, "YES disabled | enabled | active\n");
(void) fprintf(fp, gettext("\nThe feature@ properties must be "
"appended with a feature name.\nSee zpool-features(5).\n"));
"appended with a feature name.\nSee zpool-features(7).\n"));
}
/*
@ -8269,7 +8269,7 @@ status_callback(zpool_handle_t *zhp, void *data)
printf_color(ANSI_YELLOW, gettext("Enable all features using "
"'zpool upgrade'. Once this is done,\n\tthe pool may no "
"longer be accessible by software that does not support\n\t"
"the features. See zpool-features(5) for details.\n"));
"the features. See zpool-features(7) for details.\n"));
break;
case ZPOOL_STATUS_COMPATIBILITY_ERR:
@ -8858,7 +8858,7 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
upgrade_cbdata_t *cbp = arg;
nvlist_t *config;
uint64_t version;
boolean_t printnl = B_FALSE;
boolean_t modified_pool = B_FALSE;
int ret;
config = zpool_get_config(zhp, NULL);
@ -8872,7 +8872,7 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
ret = upgrade_version(zhp, cbp->cb_version);
if (ret != 0)
return (ret);
printnl = B_TRUE;
modified_pool = B_TRUE;
/*
* If they did "zpool upgrade -a", then we could
@ -8892,12 +8892,13 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
if (count > 0) {
cbp->cb_first = B_FALSE;
printnl = B_TRUE;
modified_pool = B_TRUE;
}
}
if (printnl) {
(void) printf(gettext("\n"));
if (modified_pool) {
(void) printf("\n");
(void) after_zpool_upgrade(zhp);
}
return (0);
@ -8971,7 +8972,7 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
"pool may become incompatible with "
"software\nthat does not support "
"the feature. See "
"zpool-features(5) for "
"zpool-features(7) for "
"details.\n\n"
"Note that the pool "
"'compatibility' feature can be "
@ -9010,7 +9011,7 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
static int
upgrade_one(zpool_handle_t *zhp, void *data)
{
boolean_t printnl = B_FALSE;
boolean_t modified_pool = B_FALSE;
upgrade_cbdata_t *cbp = data;
uint64_t cur_version;
int ret;
@ -9038,7 +9039,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
}
if (cur_version != cbp->cb_version) {
printnl = B_TRUE;
modified_pool = B_TRUE;
ret = upgrade_version(zhp, cbp->cb_version);
if (ret != 0)
return (ret);
@ -9051,7 +9052,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
return (ret);
if (count != 0) {
printnl = B_TRUE;
modified_pool = B_TRUE;
} else if (cur_version == SPA_VERSION) {
(void) printf(gettext("Pool '%s' already has all "
"supported and requested features enabled.\n"),
@ -9059,8 +9060,9 @@ upgrade_one(zpool_handle_t *zhp, void *data)
}
}
if (printnl) {
(void) printf(gettext("\n"));
if (modified_pool) {
(void) printf("\n");
(void) after_zpool_upgrade(zhp);
}
return (0);

View file

@ -129,6 +129,7 @@ int check_device(const char *path, boolean_t force,
boolean_t check_sector_size_database(char *path, int *sector_size);
void vdev_error(const char *fmt, ...);
int check_file(const char *file, boolean_t force, boolean_t isspare);
void after_zpool_upgrade(zpool_handle_t *zhp);
#ifdef __cplusplus
}

View file

@ -1360,7 +1360,7 @@
"type": "row"
},
{
"content": "I/O requests that are satisfied by accessing pool devices are managed by the ZIO scheduler.\nThe total latency is measured from the start of the I/O to completion by the disk.\nLatency through each queue is shown prior to its submission to the disk queue.\n\nThis view is useful for observing the effects of tuning the ZIO scheduler min and max values\n(see zfs-module-parameters(5) and [ZFS on Linux Module Parameters](https://openzfs.github.io/openzfs-docs/Performance%20and%20tuning/ZFS%20on%20Linux%20Module%20Parameters.html)):\n+ *zfs_vdev_max_active* controls the ZIO scheduler's disk queue depth (do not confuse with the block device's nr_requests)\n+ *zfs_vdev_sync_read_min_active* and *zfs_vdev_sync_read_max_active* control the synchronous queue for reads: most reads are sync\n+ *zfs_vdev_sync_write_min_active* and *zfs_vdev_sync_write_max_active* control the synchronous queue for writes: \nusually metadata or user data depending on the \"sync\" property setting or I/Os that are requested to be flushed\n+ *zfs_vdev_async_read_min_active* and *zfs_vdev_async_read_max_active* control the asynchronous queue for reads: usually prefetches\n+ *zfs_vdev_async_write_min_active* and *zfs_vdev_async_write_max_active* control the asynchronous queue for writes: \nusually the bulk of all writes at transaction group (txg) commit\n+ *zfs_vdev_scrub_min_active* and *zfs_vdev_scrub_max_active* controls the scan reads: usually scrub or resilver\n\n",
"content": "I/O requests that are satisfied by accessing pool devices are managed by the ZIO scheduler.\nThe total latency is measured from the start of the I/O to completion by the disk.\nLatency through each queue is shown prior to its submission to the disk queue.\n\nThis view is useful for observing the effects of tuning the ZIO scheduler min and max values\n(see zfs(4) and [ZFS on Linux Module Parameters](https://openzfs.github.io/openzfs-docs/Performance%20and%20tuning/ZFS%20on%20Linux%20Module%20Parameters.html)):\n+ *zfs_vdev_max_active* controls the ZIO scheduler's disk queue depth (do not confuse with the block device's nr_requests)\n+ *zfs_vdev_sync_read_min_active* and *zfs_vdev_sync_read_max_active* control the synchronous queue for reads: most reads are sync\n+ *zfs_vdev_sync_write_min_active* and *zfs_vdev_sync_write_max_active* control the synchronous queue for writes: \nusually metadata or user data depending on the \"sync\" property setting or I/Os that are requested to be flushed\n+ *zfs_vdev_async_read_min_active* and *zfs_vdev_async_read_max_active* control the asynchronous queue for reads: usually prefetches\n+ *zfs_vdev_async_write_min_active* and *zfs_vdev_async_write_max_active* control the asynchronous queue for writes: \nusually the bulk of all writes at transaction group (txg) commit\n+ *zfs_vdev_scrub_min_active* and *zfs_vdev_scrub_max_active* controls the scan reads: usually scrub or resilver\n\n",
"datasource": "${DS_MACBOOK-INFLUX}",
"fieldConfig": {
"defaults": {
@ -1664,4 +1664,4 @@
"list": []
},
"version": 2
}
}

View file

@ -15,3 +15,6 @@ zstream_LDADD = \
$(abs_top_builddir)/lib/libnvpair/libnvpair.la
include $(top_srcdir)/config/CppCheck.am
install-exec-hook:
cd $(DESTDIR)$(sbindir) && $(LN_S) -f zstream zstreamdump

View file

@ -49,6 +49,11 @@ zstream_usage(void)
int
main(int argc, char *argv[])
{
char *basename = strrchr(argv[0], '/');
basename = basename ? (basename + 1) : argv[0];
if (argc >= 1 && strcmp(basename, "zstreamdump") == 0)
return (zstream_do_dump(argc, argv));
if (argc < 2)
zstream_usage();

View file

@ -1 +0,0 @@
dist_sbin_SCRIPTS = zstreamdump

View file

@ -1,3 +0,0 @@
#!/bin/sh
exec zstream dump "$@"

View file

@ -124,6 +124,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <umem.h>
#include <ctype.h>
@ -192,30 +193,58 @@ typedef struct ztest_shared_opts {
char zo_gvars[ZO_GVARS_MAX_COUNT][ZO_GVARS_MAX_ARGLEN];
} ztest_shared_opts_t;
/* Default values for command line options. */
#define DEFAULT_POOL "ztest"
#define DEFAULT_VDEV_DIR "/tmp"
#define DEFAULT_VDEV_COUNT 5
#define DEFAULT_VDEV_SIZE (SPA_MINDEVSIZE * 4) /* 256m default size */
#define DEFAULT_VDEV_SIZE_STR "256M"
#define DEFAULT_ASHIFT SPA_MINBLOCKSHIFT
#define DEFAULT_MIRRORS 2
#define DEFAULT_RAID_CHILDREN 4
#define DEFAULT_RAID_PARITY 1
#define DEFAULT_DRAID_DATA 4
#define DEFAULT_DRAID_SPARES 1
#define DEFAULT_DATASETS_COUNT 7
#define DEFAULT_THREADS 23
#define DEFAULT_RUN_TIME 300 /* 300 seconds */
#define DEFAULT_RUN_TIME_STR "300 sec"
#define DEFAULT_PASS_TIME 60 /* 60 seconds */
#define DEFAULT_PASS_TIME_STR "60 sec"
#define DEFAULT_KILL_RATE 70 /* 70% kill rate */
#define DEFAULT_KILLRATE_STR "70%"
#define DEFAULT_INITS 1
#define DEFAULT_MAX_LOOPS 50 /* 5 minutes */
#define DEFAULT_FORCE_GANGING (64 << 10)
#define DEFAULT_FORCE_GANGING_STR "64K"
/* Simplifying assumption: -1 is not a valid default. */
#define NO_DEFAULT -1
static const ztest_shared_opts_t ztest_opts_defaults = {
.zo_pool = "ztest",
.zo_dir = "/tmp",
.zo_pool = DEFAULT_POOL,
.zo_dir = DEFAULT_VDEV_DIR,
.zo_alt_ztest = { '\0' },
.zo_alt_libpath = { '\0' },
.zo_vdevs = 5,
.zo_ashift = SPA_MINBLOCKSHIFT,
.zo_mirrors = 2,
.zo_raid_children = 4,
.zo_raid_parity = 1,
.zo_vdevs = DEFAULT_VDEV_COUNT,
.zo_ashift = DEFAULT_ASHIFT,
.zo_mirrors = DEFAULT_MIRRORS,
.zo_raid_children = DEFAULT_RAID_CHILDREN,
.zo_raid_parity = DEFAULT_RAID_PARITY,
.zo_raid_type = VDEV_TYPE_RAIDZ,
.zo_vdev_size = SPA_MINDEVSIZE * 4, /* 256m default size */
.zo_draid_data = 4, /* data drives */
.zo_draid_spares = 1, /* distributed spares */
.zo_datasets = 7,
.zo_threads = 23,
.zo_passtime = 60, /* 60 seconds */
.zo_killrate = 70, /* 70% kill rate */
.zo_vdev_size = DEFAULT_VDEV_SIZE,
.zo_draid_data = DEFAULT_DRAID_DATA, /* data drives */
.zo_draid_spares = DEFAULT_DRAID_SPARES, /* distributed spares */
.zo_datasets = DEFAULT_DATASETS_COUNT,
.zo_threads = DEFAULT_THREADS,
.zo_passtime = DEFAULT_PASS_TIME,
.zo_killrate = DEFAULT_KILL_RATE,
.zo_verbose = 0,
.zo_mmp_test = 0,
.zo_init = 1,
.zo_time = 300, /* 5 minutes */
.zo_maxloops = 50, /* max loops during spa_freeze() */
.zo_metaslab_force_ganging = 64 << 10,
.zo_init = DEFAULT_INITS,
.zo_time = DEFAULT_RUN_TIME,
.zo_maxloops = DEFAULT_MAX_LOOPS, /* max loops during spa_freeze() */
.zo_metaslab_force_ganging = DEFAULT_FORCE_GANGING,
.zo_special_vdevs = ZTEST_VDEV_CLASS_RND,
.zo_gvars_count = 0,
};
@ -684,68 +713,154 @@ nicenumtoull(const char *buf)
return (val);
}
typedef struct ztest_option {
const char short_opt;
const char *long_opt;
const char *long_opt_param;
const char *comment;
unsigned int default_int;
char *default_str;
} ztest_option_t;
/*
* The following option_table is used for generating the usage info as well as
* the long and short option information for calling getopt_long().
*/
static ztest_option_t option_table[] = {
{ 'v', "vdevs", "INTEGER", "Number of vdevs", DEFAULT_VDEV_COUNT,
NULL},
{ 's', "vdev-size", "INTEGER", "Size of each vdev",
NO_DEFAULT, DEFAULT_VDEV_SIZE_STR},
{ 'a', "alignment-shift", "INTEGER",
"Alignment shift; use 0 for random", DEFAULT_ASHIFT, NULL},
{ 'm', "mirror-copies", "INTEGER", "Number of mirror copies",
DEFAULT_MIRRORS, NULL},
{ 'r', "raid-disks", "INTEGER", "Number of raidz/draid disks",
DEFAULT_RAID_CHILDREN, NULL},
{ 'R', "raid-parity", "INTEGER", "Raid parity",
DEFAULT_RAID_PARITY, NULL},
{ 'K', "raid-kind", "raidz|draid|random", "Raid kind",
NO_DEFAULT, "random"},
{ 'D', "draid-data", "INTEGER", "Number of draid data drives",
DEFAULT_DRAID_DATA, NULL},
{ 'S', "draid-spares", "INTEGER", "Number of draid spares",
DEFAULT_DRAID_SPARES, NULL},
{ 'd', "datasets", "INTEGER", "Number of datasets",
DEFAULT_DATASETS_COUNT, NULL},
{ 't', "threads", "INTEGER", "Number of ztest threads",
DEFAULT_THREADS, NULL},
{ 'g', "gang-block-threshold", "INTEGER",
"Metaslab gang block threshold",
NO_DEFAULT, DEFAULT_FORCE_GANGING_STR},
{ 'i', "init-count", "INTEGER", "Number of times to initialize pool",
DEFAULT_INITS, NULL},
{ 'k', "kill-percentage", "INTEGER", "Kill percentage",
NO_DEFAULT, DEFAULT_KILLRATE_STR},
{ 'p', "pool-name", "STRING", "Pool name",
NO_DEFAULT, DEFAULT_POOL},
{ 'f', "vdev-file-directory", "PATH", "File directory for vdev files",
NO_DEFAULT, DEFAULT_VDEV_DIR},
{ 'M', "multi-host", NULL,
"Multi-host; simulate pool imported on remote host",
NO_DEFAULT, NULL},
{ 'E', "use-existing-pool", NULL,
"Use existing pool instead of creating new one", NO_DEFAULT, NULL},
{ 'T', "run-time", "INTEGER", "Total run time",
NO_DEFAULT, DEFAULT_RUN_TIME_STR},
{ 'P', "pass-time", "INTEGER", "Time per pass",
NO_DEFAULT, DEFAULT_PASS_TIME_STR},
{ 'F', "freeze-loops", "INTEGER", "Max loops in spa_freeze()",
DEFAULT_MAX_LOOPS, NULL},
{ 'B', "alt-ztest", "PATH", "Alternate ztest path",
NO_DEFAULT, NULL},
{ 'C', "vdev-class-state", "on|off|random", "vdev class state",
NO_DEFAULT, "random"},
{ 'o', "option", "\"OPTION=INTEGER\"",
"Set global variable to an unsigned 32-bit integer value",
NO_DEFAULT, NULL},
{ 'G', "dump-debug-msg", NULL,
"Dump zfs_dbgmsg buffer before exiting due to an error",
NO_DEFAULT, NULL},
{ 'V', "verbose", NULL,
"Verbose (use multiple times for ever more verbosity)",
NO_DEFAULT, NULL},
{ 'h', "help", NULL, "Show this help",
NO_DEFAULT, NULL},
{0, 0, 0, 0, 0, 0}
};
static struct option *long_opts = NULL;
static char *short_opts = NULL;
static void
init_options(void)
{
ASSERT3P(long_opts, ==, NULL);
ASSERT3P(short_opts, ==, NULL);
int count = sizeof (option_table) / sizeof (option_table[0]);
long_opts = umem_alloc(sizeof (struct option) * count, UMEM_NOFAIL);
short_opts = umem_alloc(sizeof (char) * 2 * count, UMEM_NOFAIL);
int short_opt_index = 0;
for (int i = 0; i < count; i++) {
long_opts[i].val = option_table[i].short_opt;
long_opts[i].name = option_table[i].long_opt;
long_opts[i].has_arg = option_table[i].long_opt_param != NULL
? required_argument : no_argument;
long_opts[i].flag = NULL;
short_opts[short_opt_index++] = option_table[i].short_opt;
if (option_table[i].long_opt_param != NULL) {
short_opts[short_opt_index++] = ':';
}
}
}
static void
fini_options(void)
{
int count = sizeof (option_table) / sizeof (option_table[0]);
umem_free(long_opts, sizeof (struct option) * count);
umem_free(short_opts, sizeof (char) * 2 * count);
long_opts = NULL;
short_opts = NULL;
}
static void
usage(boolean_t requested)
{
const ztest_shared_opts_t *zo = &ztest_opts_defaults;
char nice_vdev_size[NN_NUMBUF_SZ];
char nice_force_ganging[NN_NUMBUF_SZ];
char option[80];
FILE *fp = requested ? stdout : stderr;
nicenum(zo->zo_vdev_size, nice_vdev_size, sizeof (nice_vdev_size));
nicenum(zo->zo_metaslab_force_ganging, nice_force_ganging,
sizeof (nice_force_ganging));
(void) fprintf(fp, "Usage: %s [OPTIONS...]\n", DEFAULT_POOL);
for (int i = 0; option_table[i].short_opt != 0; i++) {
if (option_table[i].long_opt_param != NULL) {
(void) sprintf(option, " -%c --%s=%s",
option_table[i].short_opt,
option_table[i].long_opt,
option_table[i].long_opt_param);
} else {
(void) sprintf(option, " -%c --%s",
option_table[i].short_opt,
option_table[i].long_opt);
}
(void) fprintf(fp, " %-40s%s", option,
option_table[i].comment);
(void) fprintf(fp, "Usage: %s\n"
"\t[-v vdevs (default: %llu)]\n"
"\t[-s size_of_each_vdev (default: %s)]\n"
"\t[-a alignment_shift (default: %d)] use 0 for random\n"
"\t[-m mirror_copies (default: %d)]\n"
"\t[-r raidz_disks / draid_disks (default: %d)]\n"
"\t[-R raid_parity (default: %d)]\n"
"\t[-K raid_kind (default: random)] raidz|draid|random\n"
"\t[-D draid_data (default: %d)] in config\n"
"\t[-S draid_spares (default: %d)]\n"
"\t[-d datasets (default: %d)]\n"
"\t[-t threads (default: %d)]\n"
"\t[-g gang_block_threshold (default: %s)]\n"
"\t[-i init_count (default: %d)] initialize pool i times\n"
"\t[-k kill_percentage (default: %llu%%)]\n"
"\t[-p pool_name (default: %s)]\n"
"\t[-f dir (default: %s)] file directory for vdev files\n"
"\t[-M] Multi-host simulate pool imported on remote host\n"
"\t[-V] verbose (use multiple times for ever more blather)\n"
"\t[-E] use existing pool instead of creating new one\n"
"\t[-T time (default: %llu sec)] total run time\n"
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
"\t[-P passtime (default: %llu sec)] time per pass\n"
"\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
"\t[-C vdev class state (default: random)] special=on|off|random\n"
"\t[-o variable=value] ... set global variable to an unsigned\n"
"\t 32-bit integer value\n"
"\t[-G dump zfs_dbgmsg buffer before exiting due to an error\n"
"\t[-h] (print help)\n"
"",
zo->zo_pool,
(u_longlong_t)zo->zo_vdevs, /* -v */
nice_vdev_size, /* -s */
zo->zo_ashift, /* -a */
zo->zo_mirrors, /* -m */
zo->zo_raid_children, /* -r */
zo->zo_raid_parity, /* -R */
zo->zo_draid_data, /* -D */
zo->zo_draid_spares, /* -S */
zo->zo_datasets, /* -d */
zo->zo_threads, /* -t */
nice_force_ganging, /* -g */
zo->zo_init, /* -i */
(u_longlong_t)zo->zo_killrate, /* -k */
zo->zo_pool, /* -p */
zo->zo_dir, /* -f */
(u_longlong_t)zo->zo_time, /* -T */
(u_longlong_t)zo->zo_maxloops, /* -F */
(u_longlong_t)zo->zo_passtime);
if (option_table[i].long_opt_param != NULL) {
if (option_table[i].default_str != NULL) {
(void) fprintf(fp, " (default: %s)",
option_table[i].default_str);
} else if (option_table[i].default_int != NO_DEFAULT) {
(void) fprintf(fp, " (default: %u)",
option_table[i].default_int);
}
}
(void) fprintf(fp, "\n");
}
exit(requested ? 0 : 1);
}
@ -817,8 +932,10 @@ process_options(int argc, char **argv)
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
while ((opt = getopt(argc, argv,
"v:s:a:m:r:R:K:D:S:d:t:g:i:k:p:f:MVET:P:hF:B:C:o:G")) != EOF) {
init_options();
while ((opt = getopt_long(argc, argv, short_opts, long_opts,
NULL)) != EOF) {
value = 0;
switch (opt) {
case 'v':
@ -953,6 +1070,8 @@ process_options(int argc, char **argv)
}
}
fini_options();
/* When raid choice is 'random' add a draid pool 50% of the time */
if (strcmp(raid_kind, "random") == 0) {
(void) strlcpy(raid_kind, (ztest_random(2) == 0) ?

View file

@ -1 +1,3 @@
include $(top_srcdir)/config/Shellcheck.am
dist_bin_SCRIPTS = zvol_wait

View file

@ -20,6 +20,7 @@ filter_out_deleted_zvols() {
OIFS="$IFS"
IFS="
"
# shellcheck disable=SC2086
zfs list -H -o name $zvols 2>/dev/null
IFS="$OIFS"
}

View file

@ -0,0 +1,22 @@
.PHONY: shellcheck
shellcheck: $(SCRIPTS) $(SHELLCHECKSCRIPTS)
if HAVE_SHELLCHECK
[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; shellcheck $$([ -n "$(SHELLCHECK_SHELL)" ] && echo "--shell=$(SHELLCHECK_SHELL)") --exclude=SC1090,SC1091$(SHELLCHECK_IGNORE) --format=gcc $(SCRIPTS) $(SHELLCHECKSCRIPTS)
else
@[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping shellcheck of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because shellcheck is not installed"
endif
@set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir shellcheck; done
# command -v *is* specified by POSIX and every shell in existence supports it
.PHONY: checkbashisms
checkbashisms: $(SCRIPTS) $(SHELLCHECKSCRIPTS)
if HAVE_CHECKBASHISMS
[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; ! if [ -z "$(SHELLCHECK_SHELL)" ]; then \
checkbashisms -npx $(SCRIPTS) $(SHELLCHECKSCRIPTS); else \
for f in $(SCRIPTS) $(SHELLCHECKSCRIPTS); do echo $$f >&3; { echo '#!/bin/$(SHELLCHECK_SHELL)'; cat $$f; } | checkbashisms -npx; done; \
fi 3>&2 2>&1 | grep -vFe "'command' with option other than -p" -e 'command -v' $(CHECKBASHISMS_IGNORE) >&2
else
@[ -z "$(SCRIPTS)$(SHELLCHECKSCRIPTS)" ] && exit; echo "skipping checkbashisms of" $(SCRIPTS) $(SHELLCHECKSCRIPTS) "because checkbashisms is not installed"
endif
@set -e; for dir in $(SHELLCHECKDIRS); do $(MAKE) -C $$dir checkbashisms; done

View file

@ -0,0 +1,10 @@
dnl #
dnl # Check if shellcheck and/or checkbashisms are available.
dnl #
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_SHELLCHECK], [
AC_CHECK_PROG([SHELLCHECK], [shellcheck], [yes])
AC_CHECK_PROG([CHECKBASHISMS], [checkbashisms], [yes])
AM_CONDITIONAL([HAVE_SHELLCHECK], [test "x$SHELLCHECK" = "xyes"])
AM_CONDITIONAL([HAVE_CHECKBASHISMS], [test "x$CHECKBASHISMS" = "xyes"])
])

View file

@ -148,8 +148,7 @@ variable to configure. See ``configure --help'' for reference.
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
if test $? -eq 0; then
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])

View file

@ -25,6 +25,31 @@ AC_DEFUN([ZFS_AC_KERNEL_PERCPU_COUNTER_INIT], [
])
])
dnl #
dnl # 4.13 API change,
dnl # __percpu_counter_add() was renamed to percpu_counter_add_batch().
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_ADD_BATCH], [
ZFS_LINUX_TEST_SRC([percpu_counter_add_batch], [
#include <linux/percpu_counter.h>
],[
struct percpu_counter counter;
percpu_counter_add_batch(&counter, 1, 1);
])
])
AC_DEFUN([ZFS_AC_KERNEL_PERCPU_COUNTER_ADD_BATCH], [
AC_MSG_CHECKING([whether percpu_counter_add_batch() is defined])
ZFS_LINUX_TEST_RESULT([percpu_counter_add_batch], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PERCPU_COUNTER_ADD_BATCH, 1,
[percpu_counter_add_batch() is defined])
],[
AC_MSG_RESULT(no)
])
])
dnl #
dnl # 5.10 API change,
dnl # The "count" was moved into ref->data, from ref
@ -51,10 +76,12 @@ AC_DEFUN([ZFS_AC_KERNEL_PERCPU_REF_COUNT_IN_DATA], [
])
AC_DEFUN([ZFS_AC_KERNEL_SRC_PERCPU], [
ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_INIT
ZFS_AC_KERNEL_SRC_PERCPU_COUNTER_ADD_BATCH
ZFS_AC_KERNEL_SRC_PERCPU_REF_COUNT_IN_DATA
])
AC_DEFUN([ZFS_AC_KERNEL_PERCPU], [
ZFS_AC_KERNEL_PERCPU_COUNTER_INIT
ZFS_AC_KERNEL_PERCPU_COUNTER_ADD_BATCH
ZFS_AC_KERNEL_PERCPU_REF_COUNT_IN_DATA
])

View file

@ -34,6 +34,9 @@ dnl # When debugging is enabled:
dnl # - Enable all ASSERTs (-DDEBUG)
dnl # - Promote all compiler warnings to errors (-Werror)
dnl #
dnl # (If INVARIANTS is detected, we need to force DEBUG, or strange panics
dnl # can ensue.)
dnl #
AC_DEFUN([ZFS_AC_DEBUG], [
AC_MSG_CHECKING([whether assertion support will be enabled])
AC_ARG_ENABLE([debug],
@ -49,6 +52,20 @@ AC_DEFUN([ZFS_AC_DEBUG], [
[ZFS_AC_DEBUG_DISABLE],
[AC_MSG_ERROR([Unknown option $enable_debug])])
AS_CASE(["x$enable_invariants"],
["xyes"],
[],
["xno"],
[],
[ZFS_AC_DEBUG_INVARIANTS_DETECT])
AS_CASE(["x$enable_invariants"],
["xyes"],
[ZFS_AC_DEBUG_ENABLE],
["xno"],
[],
[AC_MSG_ERROR([Unknown option $enable_invariants])])
AC_SUBST(DEBUG_CFLAGS)
AC_SUBST(DEBUG_CPPFLAGS)
AC_SUBST(DEBUG_LDFLAGS)
@ -207,6 +224,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
ZFS_AC_CONFIG_ALWAYS_PYZFS
ZFS_AC_CONFIG_ALWAYS_SED
ZFS_AC_CONFIG_ALWAYS_CPPCHECK
ZFS_AC_CONFIG_ALWAYS_SHELLCHECK
])
AC_DEFUN([ZFS_AC_CONFIG], [

View file

@ -48,6 +48,7 @@ AC_CONFIG_HEADERS([zfs_config.h], [
LT_INIT
AC_PROG_INSTALL
AC_PROG_CC
AC_PROG_LN_S
PKG_PROG_PKG_CONFIG
AM_PROG_AS
AM_PROG_CC_C_O
@ -83,7 +84,6 @@ AC_CONFIG_FILES([
cmd/zinject/Makefile
cmd/zpool/Makefile
cmd/zstream/Makefile
cmd/zstreamdump/Makefile
cmd/ztest/Makefile
cmd/zvol_id/Makefile
cmd/zvol_wait/Makefile
@ -171,9 +171,6 @@ AC_CONFIG_FILES([
lib/libzstd/Makefile
lib/libzutil/Makefile
man/Makefile
man/man1/Makefile
man/man5/Makefile
man/man8/Makefile
module/Kbuild
module/Makefile
module/avl/Makefile

View file

@ -1,3 +1,5 @@
include $(top_srcdir)/config/Shellcheck.am
SUBDIRS = bash_completion.d pyzfs zcp
if BUILD_LINUX
SUBDIRS += bpftrace dracut initramfs
@ -6,3 +8,5 @@ if PAM_ZFS_ENABLED
SUBDIRS += pam_zfs_key
endif
DIST_SUBDIRS = bash_completion.d bpftrace dracut initramfs pam_zfs_key pyzfs zcp
SHELLCHECKDIRS = bash_completion.d bpftrace dracut initramfs

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
bashcompletiondir = $(sysconfdir)/bash_completion.d
@ -6,3 +7,7 @@ noinst_DATA = zfs
EXTRA_DIST += $(noinst_DATA)
SUBSTFILES += $(noinst_DATA)
SHELLCHECKSCRIPTS = $(noinst_DATA)
SHELLCHECK_SHELL = bash
SHELLCHECK_IGNORE = ,SC2207

View file

@ -62,24 +62,25 @@ __zfs_list_filesystems()
__zfs_match_snapshot()
{
local base_dataset=${cur%@*}
if [[ $base_dataset != $cur ]]
local base_dataset="${cur%@*}"
if [ "$base_dataset" != "$cur" ]
then
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset"
else
if [[ $cur != "" ]] && __zfs_list_datasets $cur &> /dev/null
if [ "$cur" != "" ] && __zfs_list_datasets "$cur" &> /dev/null
then
$__ZFS_CMD list -H -o name -s name -t filesystem -r $cur | tail -n +2
$__ZFS_CMD list -H -o name -s name -t filesystem -r "$cur" | tail -n +2
# We output the base dataset name even though we might be
# completing a command that can only take a snapshot, because it
# prevents bash from considering the completion finished when it
# ends in the bare @.
echo $cur
echo $cur@
echo "$cur"
echo "$cur@"
else
local datasets=$(__zfs_list_datasets)
local datasets
datasets="$(__zfs_list_datasets)"
# As above
echo $datasets
echo "$datasets"
if [[ "$cur" == */ ]]
then
# If the current command ends with a slash, then the only way
@ -89,54 +90,57 @@ __zfs_match_snapshot()
local num_children
# This is actually off by one as zfs list includes the named
# dataset in addition to its children
num_children=$(__zfs_list_datasets -d 1 ${cur%/} 2> /dev/null | wc -l)
num_children=$(__zfs_list_datasets -d 1 "${cur%/}" 2> /dev/null | wc -l)
if [[ $num_children != 2 ]]
then
return 0
fi
fi
echo "$datasets" | awk '{print $1"@"}'
echo "$datasets" | awk '{print $1 "@"}'
fi
fi
}
__zfs_match_snapshot_or_bookmark()
{
local base_dataset=${cur%[#@]*}
if [[ $base_dataset != $cur ]]
local base_dataset="${cur%[#@]*}"
if [ "$base_dataset" != "$cur" ]
then
if [[ $cur == *@* ]]
then
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset"
else
$__ZFS_CMD list -H -o name -s name -t bookmark -d 1 $base_dataset
$__ZFS_CMD list -H -o name -s name -t bookmark -d 1 "$base_dataset"
fi
else
$__ZFS_CMD list -H -o name -s name -t filesystem,volume
if [[ $cur != "" ]] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume $cur &> /dev/null
if [ -e "$cur" ] && $__ZFS_CMD list -H -o name -s name -t filesystem,volume "$cur" &> /dev/null
then
echo $cur@
echo $cur#
echo "$cur@"
echo "$cur#"
fi
fi
}
__zfs_match_multiple_snapshots()
{
local existing_opts=$(expr "$cur" : '\(.*\)[%,]')
if [[ $existing_opts ]]
local existing_opts
existing_opts="$(expr "$cur" : '\(.*\)[%,]')"
if [ -e "$existing_opts" ]
then
local base_dataset=${cur%@*}
if [[ $base_dataset != $cur ]]
local base_dataset="${cur%@*}"
if [ "$base_dataset" != "$cur" ]
then
local cur=${cur##*,}
local cur="${cur##*,}"
if [[ $cur =~ ^%|%.*% ]]
then
# correct range syntax is start%end
return 1
fi
local range_start=$(expr "$cur" : '\(.*%\)')
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 $base_dataset | sed 's$.*@$'$range_start'$g'
local range_start
range_start="$(expr "$cur" : '\(.*%\)')"
# shellcheck disable=SC2016
$__ZFS_CMD list -H -o name -s name -t snapshot -d 1 "$base_dataset" | sed 's$.*@$'"$range_start"'$g'
fi
else
__zfs_match_snapshot_or_bookmark
@ -160,7 +164,7 @@ __zfs_argument_chosen()
then
return 0
fi
for property in $@
for property in "$@"
do
if [[ $prev == "$property"* ]]
then
@ -178,6 +182,7 @@ __zfs_complete_ordered_arguments()
local list2=$2
local cur=$3
local extra=$4
# shellcheck disable=SC2086
if __zfs_argument_chosen $list1
then
COMPREPLY=($(compgen -W "$list2 $extra" -- "$cur"))
@ -190,9 +195,10 @@ __zfs_complete_multiple_options()
{
local options=$1
local cur=$2
local existing_opts
COMPREPLY=($(compgen -W "$options" -- "${cur##*,}"))
local existing_opts=$(expr "$cur" : '\(.*,\)')
existing_opts=$(expr "$cur" : '\(.*,\)')
if [[ $existing_opts ]]
then
COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" )
@ -287,6 +293,7 @@ __zfs_complete()
*)
if ! __zfs_complete_switch "H,r,p,d,o,t,s"
then
# shellcheck disable=SC2046
if __zfs_argument_chosen $(__zfs_get_properties)
then
COMPREPLY=($(compgen -W "$(__zfs_match_snapshot)" -- "$cur"))
@ -300,7 +307,7 @@ __zfs_complete()
inherit)
if ! __zfs_complete_switch "r"
then
__zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" $cur
__zfs_complete_ordered_arguments "$(__zfs_get_inheritable_properties)" "$(__zfs_match_snapshot)" "$cur"
fi
;;
list)
@ -366,7 +373,7 @@ __zfs_complete()
esac
;;
set)
__zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" $cur
__zfs_complete_ordered_arguments "$(__zfs_get_editable_properties)" "$(__zfs_match_snapshot)" "$cur"
__zfs_complete_nospace
;;
upgrade)
@ -385,7 +392,7 @@ __zfs_complete()
destroy)
if ! __zfs_complete_switch "d,f,n,p,R,r,v"
then
__zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" $cur
__zfs_complete_multiple_options "$(__zfs_match_multiple_snapshots)" "$cur"
__zfs_complete_nospace
fi
;;
@ -422,7 +429,7 @@ __zpool_list_pools()
__zpool_complete()
{
local cur prev cmd cmds
local cur prev cmd cmds pools
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
@ -437,7 +444,7 @@ __zpool_complete()
case "${cmd}" in
get)
__zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" $cur
__zfs_complete_ordered_arguments "$(__zpool_get_properties)" "$(__zpool_list_pools)" "$cur"
return 0
;;
import)
@ -450,12 +457,13 @@ __zpool_complete()
return 0
;;
set)
__zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" $cur
__zfs_complete_ordered_arguments "$(__zpool_get_editable_properties)" "$(__zpool_list_pools)" "$cur"
__zfs_complete_nospace
return 0
;;
add|attach|clear|create|detach|offline|online|remove|replace)
local pools="$(__zpool_list_pools)"
pools="$(__zpool_list_pools)"
# shellcheck disable=SC2086
if __zfs_argument_chosen $pools
then
_filedir

View file

@ -1,3 +1,7 @@
include $(top_srcdir)/config/Shellcheck.am
EXTRA_DIST = \
taskqlatency.bt \
zfs-trace.sh
SHELLCHECKSCRIPTS = zfs-trace.sh

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
pkgdracutdir = $(dracutdir)/modules.d/02zfsexpandknowledge
pkgdracut_SCRIPTS = \

View file

@ -14,22 +14,16 @@ get_pool_devices() {
local poolconfigtemp
local poolconfigoutput
local pooldev
local prefix
local resolved
poolconfigtemp=`mktemp`
@sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1
if [ "$?" != "0" ] ; then
poolconfigoutput=$(cat "$poolconfigtemp")
poolconfigtemp="$(mktemp)"
if ! @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1 ; then
poolconfigoutput="$(cat "$poolconfigtemp")"
dinfo "zfsexpandknowledge: pool $1 cannot be listed: $poolconfigoutput"
else
cat "$poolconfigtemp" | awk -F '\t' '/\t\/dev/ { print $2 }' | \
while read pooldev ; do
if [ -n "$pooldev" -a -e "$pooldev" ] ; then
if [ -h "$pooldev" ] ; then
resolved=`readlink -f "$pooldev"`
else
resolved="$pooldev"
fi
awk -F '\t' '/\t\/dev/ { print $2 }' "$poolconfigtemp" | \
while read -r pooldev ; do
if [ -e "$pooldev" ] ; then
resolved="$(readlink -f "$pooldev")"
dinfo "zfsexpandknowledge: pool $1 has device $pooldev (which resolves to $resolved)"
echo "$resolved"
fi
@ -40,22 +34,20 @@ get_pool_devices() {
find_zfs_block_devices() {
local dev
local blockdev
local mp
local fstype
local pool
local key
local n
local poolconfigoutput
numfields=`head -1 /proc/self/mountinfo | awk '{print NF}'`
if [ "$numfields" == "10" ] ; then
fields="n n n n mp n n fstype dev n"
local _
numfields="$(awk '{print NF; exit}' /proc/self/mountinfo)"
if [ "$numfields" = "10" ] ; then
fields="_ _ _ _ mp _ _ fstype dev _"
else
fields="n n n n mp n n n fstype dev n"
fields="_ _ _ _ mp _ _ _ fstype dev _"
fi
while read $fields ; do
if [ "$fstype" != "zfs" ]; then continue ; fi
if [ "$mp" == "$1" ]; then
# shellcheck disable=SC2086
while read -r ${fields?} ; do
[ "$fstype" = "zfs" ] || continue
if [ "$mp" = "$1" ]; then
pool=$(echo "$dev" | cut -d / -f 1)
get_pool_devices "$pool"
fi
@ -77,10 +69,9 @@ check() {
local _depdev
local _depdevname
local _depdevtype
local _depmajmin
local _dev
if [[ $hostonly ]]; then
# shellcheck disable=SC2154
if [ -n "$hostonly" ]; then
for mp in \
"/" \
@ -107,13 +98,12 @@ if [[ $hostonly ]]; then
fstype=$(get_devtype "$dev")
host_fs_types["$dev"]="$fstype"
majmin=$(get_maj_min "$dev")
if [[ -d /sys/dev/block/$majmin/slaves ]] ; then
for _depdev in /sys/dev/block/$majmin/slaves/*; do
if [ -d "/sys/dev/block/$majmin/slaves" ] ; then
for _depdev in "/sys/dev/block/$majmin/slaves"/*; do
[[ -f $_depdev/dev ]] || continue
_depdev=/dev/$(basename "$_depdev")
_depdevname=$(udevadm info --query=property --name="$_depdev" | grep "^DEVNAME=" | sed 's|^DEVNAME=||')
_depdevtype=$(get_devtype "$_depdevname")
_depmajmin=$(get_maj_min "$_depdevname")
dinfo "zfsexpandknowledge: underlying block device backing ZFS dataset $mp: ${_depdevname//$'\n'/ }"
array_contains "$_depdevname" "${host_devs[@]}" || host_devs+=("$_depdevname")
host_fs_types["$_depdevname"]="$_depdevtype"

View file

@ -1,11 +1,2 @@
export-zfs.sh
module-setup.sh
mount-zfs.sh
parse-zfs.sh
zfs-generator.sh
zfs-lib.sh
zfs-load-key.sh
zfs-needshutdown.sh
zfs-env-bootfs.service
zfs-snapshot-bootfs.service
zfs-rollback-bootfs.service
*.sh
*.service

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
pkgdracutdir = $(dracutdir)/modules.d/90zfs
pkgdracut_SCRIPTS = \
@ -9,7 +10,8 @@ pkgdracut_SCRIPTS = \
zfs-generator.sh \
zfs-load-key.sh \
zfs-needshutdown.sh \
zfs-lib.sh
zfs-lib.sh \
import-opts-generator.sh
pkgdracut_DATA = \
zfs-env-bootfs.service \
@ -17,3 +19,6 @@ pkgdracut_DATA = \
zfs-rollback-bootfs.service
SUBSTFILES += $(pkgdracut_SCRIPTS) $(pkgdracut_DATA)
# Provided by /bin/sleep, and, again, every implementation of that supports this
CHECKBASHISMS_IGNORE = -e 'sleep only takes one integer' -e 'sleep 0.'

View file

@ -0,0 +1,5 @@
#!/bin/sh
. /lib/dracut-zfs-lib.sh
echo ZPOOL_IMPORT_OPTS="$ZPOOL_IMPORT_OPTS"

View file

@ -1,4 +1,5 @@
#!/usr/bin/env bash
# shellcheck disable=SC2154
check() {
# We depend on udev-rules being loaded
@ -8,8 +9,6 @@ check() {
for tool in "@sbindir@/zgenhostid" "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs" ; do
test -x "$tool" || return 1
done
# Verify grep exists
which grep >/dev/null 2>&1 || return 1
return 0
}
@ -43,19 +42,23 @@ install() {
dracut_install @sbindir@/zpool
# Workaround for https://github.com/openzfs/zfs/issues/4749 by
# ensuring libgcc_s.so(.1) is included
if [[ -n "$(ldd @sbindir@/zpool | grep -F 'libgcc_s.so')" ]]; then
if ldd @sbindir@/zpool | grep -qF 'libgcc_s.so'; then
# Dracut will have already tracked and included it
:;
elif command -v gcc-config 2>&1 1>/dev/null; then
elif command -v gcc-config >/dev/null 2>&1; then
# On systems with gcc-config (Gentoo, Funtoo, etc.):
# Use the current profile to resolve the appropriate path
dracut_install "/usr/lib/gcc/$(s=$(gcc-config -c); echo ${s%-*}/${s##*-})/libgcc_s.so.1"
elif [[ -n "$(ls /usr/lib/libgcc_s.so* 2>/dev/null)" ]]; then
s="$(gcc-config -c)"
dracut_install "/usr/lib/gcc/${s%-*}/${s##*-}/libgcc_s.so"*
elif [ "$(echo /usr/lib/libgcc_s.so*)" != "/usr/lib/libgcc_s.so*" ]; then
# Try a simple path first
dracut_install /usr/lib/libgcc_s.so*
elif [ "$(echo /lib*/libgcc_s.so*)" != "/lib*/libgcc_s.so*" ]; then
# SUSE
dracut_install /lib*/libgcc_s.so*
else
# Fallback: Guess the path and include all matches
dracut_install /usr/lib/gcc/*/*/libgcc_s.so*
dracut_install /usr/lib*/gcc/**/libgcc_s.so*
fi
dracut_install @mounthelperdir@/mount.zfs
dracut_install @udevdir@/vdev_id
@ -95,29 +98,40 @@ install() {
if dracut_module_included "systemd"; then
mkdir -p "${initdir}/$systemdsystemunitdir/zfs-import.target.wants"
for _item in scan cache ; do
dracut_install @systemdunitdir@/zfs-import-$_item.service
if ! [ -L "${initdir}/$systemdsystemunitdir/zfs-import.target.wants"/zfs-import-$_item.service ]; then
ln -s ../zfs-import-$_item.service "${initdir}/$systemdsystemunitdir/zfs-import.target.wants"/zfs-import-$_item.service
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-import-$_item.service
for _service in "zfs-import-scan.service" "zfs-import-cache.service" ; do
dracut_install "@systemdunitdir@/$_service"
if ! [ -L "${initdir}/$systemdsystemunitdir/zfs-import.target.wants/$_service" ]; then
ln -sf ../$_service "${initdir}/$systemdsystemunitdir/zfs-import.target.wants/$_service"
type mark_hostonly >/dev/null 2>&1 && mark_hostonly "@systemdunitdir@/$_service"
fi
done
inst "${moddir}"/zfs-env-bootfs.service "${systemdsystemunitdir}"/zfs-env-bootfs.service
ln -s ../zfs-env-bootfs.service "${initdir}/${systemdsystemunitdir}/zfs-import.target.wants"/zfs-env-bootfs.service
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-env-bootfs.service
dracut_install systemd-ask-password
dracut_install systemd-tty-ask-password-agent
mkdir -p "${initdir}/$systemdsystemunitdir/initrd.target.wants"
dracut_install @systemdunitdir@/zfs-import.target
if ! [ -L "${initdir}/$systemdsystemunitdir/initrd.target.wants"/zfs-import.target ]; then
ln -s ../zfs-import.target "${initdir}/$systemdsystemunitdir/initrd.target.wants"/zfs-import.target
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-import.target
fi
for _service in zfs-snapshot-bootfs.service zfs-rollback-bootfs.service ; do
inst "${moddir}"/$_service "${systemdsystemunitdir}"/$_service
if ! [ -L "${initdir}/$systemdsystemunitdir/initrd.target.wants"/$_service ]; then
ln -s ../$_service "${initdir}/$systemdsystemunitdir/initrd.target.wants"/$_service
inst "${moddir}/$_service" "${systemdsystemunitdir}/$_service"
if ! [ -L "${initdir}/$systemdsystemunitdir/initrd.target.wants/$_service" ]; then
ln -s "../$_service" "${initdir}/$systemdsystemunitdir/initrd.target.wants/$_service"
fi
done
# There isn't a pkg-config variable for this,
# and dracut doesn't automatically resolve anything this'd be next to
local systemdsystemenvironmentgeneratordir
systemdsystemenvironmentgeneratordir="$(pkg-config --variable=prefix systemd || echo "/usr")/lib/systemd/system-environment-generators"
mkdir -p "${initdir}/${systemdsystemenvironmentgeneratordir}"
inst "${moddir}"/import-opts-generator.sh "${systemdsystemenvironmentgeneratordir}"/zfs-import-opts.sh
fi
}

View file

@ -1,4 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2034,SC2154
. /lib/dracut-zfs-lib.sh
@ -38,11 +39,10 @@ modprobe zfs 2>/dev/null
udevadm settle
if [ "${root}" = "zfs:AUTO" ] ; then
ZFS_DATASET="$(find_bootfs)"
if [ $? -ne 0 ] ; then
if ! ZFS_DATASET="$(find_bootfs)" ; then
# shellcheck disable=SC2086
zpool import -N -a ${ZPOOL_IMPORT_OPTS}
ZFS_DATASET="$(find_bootfs)"
if [ $? -ne 0 ] ; then
if ! ZFS_DATASET="$(find_bootfs)" ; then
warn "ZFS: No bootfs attribute found in importable pools."
export_all -F
@ -58,7 +58,7 @@ ZFS_POOL="${ZFS_DATASET%%/*}"
if import_pool "${ZFS_POOL}" ; then
# Load keys if we can or if we need to
if [ "$(zpool list -H -o feature@encryption "$(echo "${ZFS_POOL}" | awk -F/ '{print $1}')")" = 'active' ]; then
if [ "$(zpool list -H -o feature@encryption "${ZFS_POOL}")" = 'active' ]; then
# if the root dataset has encryption enabled
ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${ZFS_DATASET}")"
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then

View file

@ -1,4 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2034,SC2154
. /lib/dracut-lib.sh
@ -28,7 +29,7 @@ case "${root}" in
info "ZFS: Enabling autodetection of bootfs after udev settles."
;;
ZFS\=*|zfs:*|zfs:FILESYSTEM\=*|FILESYSTEM\=*)
ZFS=*|zfs:*|FILESYSTEM=*)
# root is explicit ZFS root. Parse it now. We can handle
# a root=... param in any of the following formats:
# root=ZFS=rpool/ROOT

View file

@ -1,4 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2016,SC1004
grep -wq debug /proc/cmdline && debug=1
[ -n "$debug" ] && echo "zfs-generator: starting" >> /dev/kmsg

View file

@ -5,12 +5,8 @@ command -v getargbool >/dev/null || {
# Compatibility with older Dracut versions.
# With apologies to the Dracut developers.
getargbool() {
if ! [ -z "$_b" ]; then
unset _b
fi
_default="$1"; shift
_b=$(getarg "$@")
[ $? -ne 0 ] && [ -z "$_b" ] && _b="$_default"
! _b=$(getarg "$@") && [ -z "$_b" ] && _b="$_default"
if [ -n "$_b" ]; then
[ "$_b" = "0" ] && return 1
[ "$_b" = "no" ] && return 1
@ -63,6 +59,7 @@ import_pool() {
if ! zpool list -H "${pool}" > /dev/null 2>&1; then
info "ZFS: Importing pool ${pool}..."
# shellcheck disable=SC2086
if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${pool}" ; then
warn "ZFS: Unable to import pool ${pool}"
return 1
@ -127,13 +124,12 @@ for_relevant_root_children() {
# export_all OPTS
# exports all imported zfs pools.
export_all() {
opts="${@}"
ret=0
IFS="${NEWLINE}"
for pool in $(zpool list -H -o name) ; do
if zpool list -H "${pool}" > /dev/null 2>&1; then
zpool export "${pool}" ${opts} || ret=$?
zpool export "${pool}" "$@" || ret=$?
fi
done
IFS="${OLDIFS}"

View file

@ -1,4 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2154
# only run this on systemd systems, we handle the decrypt in mount-zfs.sh in the mount hook otherwise
[ -e /bin/systemctl ] || [ -e /usr/bin/systemctl ] || return 0
@ -32,16 +33,15 @@ else
fi
# if pool encryption is active and the zfs command understands '-o encryption'
if [ "$(zpool list -H -o feature@encryption "$(echo "${BOOTFS}" | awk -F/ '{print $1}')")" = 'active' ]; then
if [ "$(zpool list -H -o feature@encryption "${BOOTFS%%/*}")" = 'active' ]; then
# if the root dataset has encryption enabled
ENCRYPTIONROOT="$(zfs get -H -o value encryptionroot "${BOOTFS}")"
# where the key is stored (in a file or loaded via prompt)
KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")"
if ! [ "${ENCRYPTIONROOT}" = "-" ]; then
KEYSTATUS="$(zfs get -H -o value keystatus "${ENCRYPTIONROOT}")"
# continue only if the key needs to be loaded
[ "$KEYSTATUS" = "unavailable" ] || exit 0
# if key is stored in a file, do not prompt
KEYLOCATION="$(zfs get -H -o value keylocation "${ENCRYPTIONROOT}")"
if ! [ "${KEYLOCATION}" = "prompt" ]; then
zfs load-key "${ENCRYPTIONROOT}"
else

View file

@ -1,3 +1,6 @@
include $(top_srcdir)/config/Shellcheck.am
SUBDIRS = 02zfsexpandknowledge 90zfs
SHELLCHECKDIRS = $(SUBDIRS)
EXTRA_DIST = README.dracut.markdown

View file

@ -1,9 +1,12 @@
include $(top_srcdir)/config/Shellcheck.am
initrddir = /usr/share/initramfs-tools
dist_initrd_SCRIPTS = \
zfsunlock
SUBDIRS = conf.d conf-hooks.d hooks scripts
SHELLCHECKDIRS = hooks scripts
EXTRA_DIST = \
README.initramfs.markdown

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
hooksdir = /usr/share/initramfs-tools/hooks

View file

@ -3,107 +3,48 @@
# Add OpenZFS filesystem capabilities to an initrd, usually for a native ZFS root.
#
# This hook installs udev rules for OpenZFS.
PREREQ="udev"
# These prerequisites are provided by the zfsutils package. The zdb utility is
# not strictly required, but it can be useful at the initramfs recovery prompt.
COPY_EXEC_LIST="@sbindir@/zdb @sbindir@/zpool @sbindir@/zfs"
COPY_EXEC_LIST="$COPY_EXEC_LIST @mounthelperdir@/mount.zfs @udevdir@/vdev_id"
COPY_EXEC_LIST="$COPY_EXEC_LIST @udevdir@/zvol_id"
COPY_FILE_LIST="/etc/hostid @sysconfdir@/zfs/zpool.cache"
COPY_FILE_LIST="$COPY_FILE_LIST @initconfdir@/zfs"
COPY_FILE_LIST="$COPY_FILE_LIST @sysconfdir@/zfs/zfs-functions"
COPY_FILE_LIST="$COPY_FILE_LIST @sysconfdir@/zfs/vdev_id.conf"
COPY_FILE_LIST="$COPY_FILE_LIST @udevruledir@/60-zvol.rules"
COPY_FILE_LIST="$COPY_FILE_LIST @udevruledir@/69-vdev.rules"
# These prerequisites are provided by the base system.
COPY_EXEC_LIST="$COPY_EXEC_LIST /usr/bin/dirname /bin/hostname /sbin/blkid"
COPY_EXEC_LIST="$COPY_EXEC_LIST /usr/bin/env"
COPY_EXEC_LIST="$COPY_EXEC_LIST $(which systemd-ask-password)"
# Explicitly specify all kernel modules because automatic dependency resolution
# is unreliable on many systems.
BASE_MODULES="zlib_deflate spl zavl zcommon znvpair zunicode zlua zfs icp"
CRPT_MODULES="sun-ccm sun-gcm sun-ctr"
MANUAL_ADD_MODULES_LIST="$BASE_MODULES"
# Generic result code.
RC=0
case $1 in
prereqs)
echo "$PREREQ"
exit 0
;;
esac
for ii in $COPY_EXEC_LIST
do
if [ ! -x "$ii" ]
then
echo "Error: $ii is not executable."
RC=2
fi
done
if [ "$RC" -ne 0 ]
then
exit "$RC"
if [ "$1" = "prereqs" ]; then
echo "udev"
exit
fi
. /usr/share/initramfs-tools/hook-functions
mkdir -p "$DESTDIR/etc/"
# ZDB uses pthreads for some functions, but the library dependency is not
# automatically detected. The `find` utility and extended `cp` options are
# used here because libgcc_s.so could be in a subdirectory of /lib for
# multi-arch installations.
cp --target-directory="$DESTDIR" --parents $(find /lib/ -type f -name libgcc_s.so.1)
for ii in $COPY_EXEC_LIST
do
copy_exec "$ii"
for req in "@sbindir@/zpool" "@sbindir@/zfs" "@mounthelperdir@/mount.zfs"; do
copy_exec "$req" || {
echo "$req not available!" >&2
exit 2
}
done
for ii in $COPY_FILE_LIST
do
dir=$(dirname "$ii")
[ -d "$dir" ] && mkdir -p "$DESTDIR/$dir"
[ -f "$ii" ] && cp -p "$ii" "$DESTDIR/$ii"
copy_exec "@sbindir@/zdb"
copy_exec "@udevdir@/vdev_id"
copy_exec "@udevdir@/zvol_id"
if command -v systemd-ask-password > /dev/null; then
copy_exec "$(command -v systemd-ask-password)"
fi
# We use pthreads, but i-t from buster doesn't automatically
# copy this indirect dependency: this can be removed when buster finally dies.
find /lib/ -type f -name "libgcc_s.so.[1-9]" | while read -r libgcc; do
copy_exec "$libgcc"
done
for ii in $MANUAL_ADD_MODULES_LIST
do
manual_add_modules "$ii"
done
copy_file config "/etc/hostid"
copy_file cache "@sysconfdir@/zfs/zpool.cache"
copy_file config "@initconfdir@/zfs"
copy_file config "@sysconfdir@/zfs/zfs-functions"
copy_file config "@sysconfdir@/zfs/vdev_id.conf"
copy_file rule "@udevruledir@/60-zvol.rules"
copy_file rule "@udevruledir@/69-vdev.rules"
if [ -f "/etc/hostname" ]
then
cp -p "/etc/hostname" "$DESTDIR/etc/"
manual_add_modules zfs
if [ -f "/etc/hostname" ]; then
copy_file config "/etc/hostname"
else
hostname >"$DESTDIR/etc/hostname"
hostname="$(mktemp -t hostname.XXXXXXXXXX)"
hostname > "$hostname"
copy_file config "$hostname" "/etc/hostname"
rm -f "$hostname"
fi
for ii in zfs zfs.conf spl spl.conf
do
if [ -f "/etc/modprobe.d/$ii" ]; then
if [ ! -d "$DESTDIR/etc/modprobe.d" ]; then
mkdir -p $DESTDIR/etc/modprobe.d
fi
cp -p "/etc/modprobe.d/$ii" $DESTDIR/etc/modprobe.d/
fi
done
# With pull request #1476 (not yet merged) comes a verbose warning
# if /usr/bin/net doesn't exist or isn't executable. Just create
# a dummy...
[ ! -d "$DESTDIR/usr/bin" ] && mkdir -p "$DESTDIR/usr/bin"
if [ ! -x "$DESTDIR/usr/bin/net" ]; then
touch "$DESTDIR/usr/bin/net"
chmod +x "$DESTDIR/usr/bin/net"
fi
exit 0

View file

@ -1,17 +1,9 @@
#!/bin/sh
PREREQ="dropbear"
prereqs() {
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
if [ "$1" = "prereqs" ]; then
echo "dropbear"
exit
fi
. /usr/share/initramfs-tools/hook-functions

View file

@ -1,6 +1,11 @@
include $(top_srcdir)/config/Shellcheck.am
scriptsdir = /usr/share/initramfs-tools/scripts
dist_scripts_DATA = \
dist_scripts_SCRIPTS = \
zfs
SUBDIRS = local-top
SHELLCHECKDIRS = $(SUBDIRS)
SHELLCHECK_SHELL = sh

View file

@ -1,3 +1,5 @@
include $(top_srcdir)/config/Shellcheck.am
localtopdir = /usr/share/initramfs-tools/scripts/local-top
dist_localtop_SCRIPTS = \

View file

@ -1,18 +1,11 @@
#!/bin/sh
PREREQ="mdadm mdrun multipath"
# shellcheck disable=SC2154
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
if [ "$1" = "prereqs" ]; then
echo mdadm mdrun multipath
exit 0
;;
esac
fi
#
@ -20,10 +13,10 @@ esac
#
message()
{
if [ -x /bin/plymouth ] && plymouth --ping; then
plymouth message --text="$@"
if plymouth --ping 2>/dev/null; then
plymouth message --text="$*"
else
echo "$@" >&2
echo "$*" >&2
fi
return 0
}

View file

@ -5,6 +5,8 @@
#
# Enable this by passing boot=zfs on the kernel command line.
#
# $quiet, $root, $rpool, $bootfs come from the cmdline:
# shellcheck disable=SC2154
# Source the common functions
. /etc/zfs/zfs-functions
@ -102,14 +104,10 @@ find_rootfs()
# Support function to get a list of all pools, separated with ';'
find_pools()
{
CMD="$*"
pools=$($CMD 2> /dev/null | \
pools=$("$@" 2> /dev/null | \
grep -E "pool:|^[a-zA-Z0-9]" | \
sed 's@.*: @@' | \
while read -r pool; do \
printf "%s" "$pool;"
done)
tr '\n' ';')
echo "${pools%%;}" # Return without the last ';'.
}
@ -203,7 +201,7 @@ import_pool()
# exists).
if [ -n "$USE_DISK_BY_ID" ] && [ -z "$ZPOOL_IMPORT_PATH" ]
then
dirs="$(for dir in $(echo /dev/disk/by-*)
dirs="$(for dir in /dev/disk/by-*
do
# Ignore by-vdev here - we want it first!
echo "$dir" | grep -q /by-vdev && continue
@ -273,6 +271,8 @@ import_pool()
# with more logging etc.
load_module_initrd()
{
[ -n "$ROOTDELAY" ] && ZFS_INITRD_PRE_MOUNTROOT_SLEEP="$ROOTDELAY"
if [ "$ZFS_INITRD_PRE_MOUNTROOT_SLEEP" -gt 0 ] 2>/dev/null
then
if [ "$quiet" != "y" ]; then
@ -327,6 +327,7 @@ mount_fs()
# Need the _original_ datasets mountpoint!
mountpoint=$(get_fs_value "$fs" mountpoint)
ZFS_CMD="mount -o zfsutil -t zfs"
if [ "$mountpoint" = "legacy" ] || [ "$mountpoint" = "none" ]; then
# Can't use the mountpoint property. Might be one of our
# clones. Check the 'org.zol:mountpoint' property set in
@ -346,15 +347,11 @@ mount_fs()
fi
fi
# If it's not a legacy filesystem, it can only be a
# native one...
if [ "$mountpoint" = "legacy" ]; then
ZFS_CMD="mount -t zfs"
else
# If it's not a legacy filesystem, it can only be a
# native one...
ZFS_CMD="mount -o zfsutil -t zfs"
fi
else
ZFS_CMD="mount -o zfsutil -t zfs"
fi
# Possibly decrypt a filesystem using native encryption.
@ -393,7 +390,7 @@ decrypt_fs()
fs="$1"
# If pool encryption is active and the zfs command understands '-o encryption'
if [ "$(zpool list -H -o feature@encryption "$(echo "${fs}" | awk -F/ '{print $1}')")" = 'active' ]; then
if [ "$(zpool list -H -o feature@encryption "${fs%%/*}")" = 'active' ]; then
# Determine dataset that holds key for root dataset
ENCRYPTIONROOT="$(get_fs_value "${fs}" encryptionroot)"
@ -554,7 +551,6 @@ rollback_snap()
ask_user_snap()
{
fs="$1"
i=1
# We need to temporarily disable debugging. Set 'debug' so we
# remember to enabled it again.
@ -567,16 +563,25 @@ ask_user_snap()
# Because we need the resulting snapshot, which is sent on
# stdout to the caller, we use stderr for our questions.
echo "What snapshot do you want to boot from?" > /dev/stderr
while read -r snap; do
echo " $i: ${snap}" > /dev/stderr
eval "$(echo SNAP_$i=$snap)"
i=$((i + 1))
done <<EOT
$("${ZFS}" list -H -oname -tsnapshot -r "${fs}")
EOT
# shellcheck disable=SC2046
IFS="
" set -- $("${ZFS}" list -H -oname -tsnapshot -r "${fs}")
echo "%s" " Snap nr [1-$((i-1))]? " > /dev/stderr
read -r snapnr
i=1
for snap in "$@"; do
echo " $i: $snap"
i=$((i + 1))
done > /dev/stderr
# expr instead of test here because [ a -lt 0 ] errors out,
# but expr falls back to lexicographical, which works out right
snapnr=0
while expr "$snapnr" "<" 1 > /dev/null ||
expr "$snapnr" ">" "$#" > /dev/null
do
printf "%s" "Snap nr [1-$#]? " > /dev/stderr
read -r snapnr
done
# Re-enable debugging.
if [ -n "${debug}" ]; then
@ -584,7 +589,7 @@ EOT
set -x
fi
echo "$(eval echo '$SNAP_'$snapnr)"
eval echo '$'"$snapnr"
}
setup_snapshot_booting()
@ -704,7 +709,8 @@ mountroot()
# ------------
# Look for the cache file (if any).
[ ! -f ${ZPOOL_CACHE} ] && unset ZPOOL_CACHE
[ -f "${ZPOOL_CACHE}" ] || unset ZPOOL_CACHE
[ -s "${ZPOOL_CACHE}" ] || unset ZPOOL_CACHE
# ------------
# Compatibility: 'ROOT' is for Debian GNU/Linux (etc),
@ -794,7 +800,8 @@ mountroot()
#
# Reassign the variable by dumping the environment and
# stripping the zfs-bootfs= prefix. Let the shell handle
# quoting through the eval command.
# quoting through the eval command:
# shellcheck disable=SC2046
eval ZFS_RPOOL=$(set | sed -n -e 's,^zfs-bootfs=,,p')
fi
@ -876,7 +883,7 @@ mountroot()
echo ""
echo "No pool imported. Manually import the root pool"
echo "at the command prompt and then exit."
echo "Hint: Try: zpool import -R ${rootmnt} -N ${ZFS_RPOOL}"
echo "Hint: Try: zpool import -N ${ZFS_RPOOL}"
shell
fi
@ -948,7 +955,7 @@ mountroot()
touch /run/zfs_unlock_complete
if [ -e /run/zfs_unlock_complete_notify ]; then
read -r zfs_unlock_complete_notify < /run/zfs_unlock_complete_notify
read -r < /run/zfs_unlock_complete_notify
fi
# ------------

View file

@ -1,5 +1,9 @@
include $(top_srcdir)/config/Shellcheck.am
SUBDIRS = zfs sudoers.d
SHELLCHECKDIRS = zfs
if BUILD_LINUX
SHELLCHECKDIRS += default $(ZFS_INIT_SYSV)
SUBDIRS += default $(ZFS_INIT_SYSTEMD) $(ZFS_INIT_SYSV) $(ZFS_MODULE_LOAD)
endif
DIST_SUBDIRS = default init.d zfs systemd modules-load.d sudoers.d

View file

@ -1,5 +1,9 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
initconf_SCRIPTS = zfs
SUBSTFILES += $(initconf_SCRIPTS)
SHELLCHECK_SHELL = sh
SHELLCHECK_IGNORE = ,SC2034

View file

@ -1,7 +1,10 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
EXTRA_DIST += README.md
init_SCRIPTS = zfs-import zfs-mount zfs-share zfs-zed
SUBSTFILES += $(init_SCRIPTS)
SHELLCHECK_SHELL = dash # local variables

View file

@ -26,10 +26,8 @@
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
# This script is based on debian/zfsutils.zfs.init from the
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
# Source the common init script
. @sysconfdir@/zfs/zfs-functions
@ -56,16 +54,13 @@ do_verbatim_import()
# Support function to get a list of all pools, separated with ';'
find_pools()
{
local CMD="$*"
local pools
pools=$($CMD 2> /dev/null | \
pools=$("$@" 2> /dev/null | \
grep -E "pool:|^[a-zA-Z0-9]" | \
sed 's@.*: @@' | \
sort | \
while read pool; do \
echo -n "$pool;"
done)
tr '\n' ';')
echo "${pools%%;}" # Return without the last ';'.
}
@ -77,10 +72,11 @@ do_import_all_visible()
local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
# In case not shutdown cleanly.
# shellcheck disable=SC2154
[ -n "$init" ] && rm -f /etc/dfs/sharetab
# Just simplify code later on.
if [ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ]
if [ -n "$USE_DISK_BY_ID" ] && [ "$USE_DISK_BY_ID" != 'yes' ]
then
# It's something, but not 'yes' so it's no good to us.
unset USE_DISK_BY_ID
@ -153,7 +149,7 @@ do_import_all_visible()
# to something we can use later with the real import(s). We want to
# make sure we find all by* dirs, BUT by-vdev should be first (if it
# exists).
if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
if [ -n "$USE_DISK_BY_ID" ] && [ -z "$ZPOOL_IMPORT_PATH" ]
then
local dirs
dirs="$(for dir in $(echo /dev/disk/by-*)
@ -162,7 +158,7 @@ do_import_all_visible()
echo "$dir" | grep -q /by-vdev && continue
[ ! -d "$dir" ] && continue
echo -n "$dir:"
printf "%s" "$dir:"
done | sed 's,:$,,g')"
if [ -d "/dev/disk/by-vdev" ]
@ -219,6 +215,7 @@ do_import_all_visible()
# Import by using ZPOOL_IMPORT_PATH (either set above or in
# the config file) _or_ with the 'built in' default search
# paths. This is the preferred way.
# shellcheck disable=SC2086
"$ZPOOL" import -N ${ZPOOL_IMPORT_OPTS} "$pool" 2> /dev/null
r="$?" ; RET=$((RET + r))
if [ "$r" -eq 0 ]
@ -231,7 +228,7 @@ do_import_all_visible()
# using the cache file soon and that might succeed.
[ ! -f "$ZPOOL_CACHE" ] && zfs_log_end_msg "$RET"
if [ "$r" -gt 0 -a -f "$ZPOOL_CACHE" ]
if [ "$r" -gt 0 ] && [ -f "$ZPOOL_CACHE" ]
then
# Failed to import without a cache file. Try WITH...
if [ -z "$init" ] && check_boolean "$VERBOSE_MOUNT"
@ -240,6 +237,7 @@ do_import_all_visible()
zfs_log_progress_msg " using cache file"
fi
# shellcheck disable=SC2086
"$ZPOOL" import -c "$ZPOOL_CACHE" -N ${ZPOOL_IMPORT_OPTS} \
"$pool" 2> /dev/null
r="$?" ; RET=$((RET + r))
@ -254,7 +252,7 @@ do_import_all_visible()
[ -n "$init" ] && zfs_log_end_msg "$RET"
IFS="$OLD_IFS"
[ -n "$already_imported" -a -z "$available_pools" ] && return 0
[ -n "$already_imported" ] && [ -z "$available_pools" ] && return 0
return "$RET"
}

View file

@ -23,10 +23,8 @@
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
# This script is based on debian/zfsutils.zfs.init from the
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
# Source the common init script
. @sysconfdir@/zfs/zfs-functions
@ -34,9 +32,8 @@
# ----------------------------------------------------
chkroot() {
while read line; do
set -- $line
if [ "$2" = "/" ]; then
while read -r _ mp _; do
if [ "$mp" = "/" ]; then
return 0
fi
done < /proc/self/mounts
@ -65,7 +62,7 @@ do_depend()
# Mount all datasets/filesystems
do_mount()
{
local verbose overlay i mntpt val
local verbose overlay i mntpt
check_boolean "$VERBOSE_MOUNT" && verbose=v
check_boolean "$DO_OVERLAY_MOUNTS" && overlay=O
@ -83,11 +80,11 @@ do_mount()
read_mtab "^/dev/(zd|zvol)"
read_fstab "^/dev/(zd|zvol)"
i=0; var=$(eval echo FSTAB_$i)
while [ -n "$(eval echo "$""$var")" ]
i=0; var="FSTAB_0"
while [ -n "$(eval echo "\$$var")" ]
do
mntpt=$(eval echo "$""$var")
dev=$(eval echo "$"FSTAB_dev_$i)
mntpt=$(eval echo "\$$var")
dev=$(eval echo "\$FSTAB_dev_$i")
if ! in_mtab "$mntpt" && ! is_mounted "$mntpt" && [ -e "$dev" ]
then
check_boolean "$VERBOSE_MOUNT" && \
@ -96,15 +93,15 @@ do_mount()
fi
i=$((i + 1))
var=$(eval echo FSTAB_$i)
var=$(eval echo "FSTAB_$i")
done
read_mtab "[[:space:]]zfs[[:space:]]"
read_fstab "[[:space:]]zfs[[:space:]]"
i=0; var=$(eval echo FSTAB_$i)
while [ -n "$(eval echo "$""$var")" ]
i=0; var=$(eval echo "FSTAB_$i")
while [ -n "$(eval echo "\$$var")" ]
do
mntpt=$(eval echo "$""$var")
mntpt=$(eval echo "\$$var")
if ! in_mtab "$mntpt" && ! is_mounted "$mntpt"
then
check_boolean "$VERBOSE_MOUNT" && \
@ -113,7 +110,7 @@ do_mount()
fi
i=$((i + 1))
var=$(eval echo FSTAB_$i)
var=$(eval echo "FSTAB_$i")
done
check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0
@ -136,11 +133,11 @@ do_unmount()
read_mtab "^/dev/(zd|zvol)"
read_fstab "^/dev/(zd|zvol)"
i=0; var=$(eval echo FSTAB_$i)
while [ -n "$(eval echo "$""$var")" ]
i=0; var="FSTAB_0"
while [ -n "$(eval echo "\$$var")" ]
do
mntpt=$(eval echo "$""$var")
dev=$(eval echo "$"FSTAB_dev_$i)
mntpt=$(eval echo "\$$var")
dev=$(eval echo "\$FSTAB_dev_$i")
if in_mtab "$mntpt"
then
check_boolean "$VERBOSE_MOUNT" && \
@ -149,15 +146,15 @@ do_unmount()
fi
i=$((i + 1))
var=$(eval echo FSTAB_$i)
var=$(eval echo "FSTAB_$i")
done
read_mtab "[[:space:]]zfs[[:space:]]"
read_fstab "[[:space:]]zfs[[:space:]]"
i=0; var=$(eval echo FSTAB_$i)
while [ -n "$(eval echo "$""$var")" ]
i=0; var="FSTAB_0"
while [ -n "$(eval echo "\$$var")" ]
do
mntpt=$(eval echo "$""$var")
mntpt=$(eval echo "\$$var")
if in_mtab "$mntpt"; then
check_boolean "$VERBOSE_MOUNT" && \
zfs_log_progress_msg "$mntpt "
@ -165,7 +162,7 @@ do_unmount()
fi
i=$((i + 1))
var=$(eval echo FSTAB_$i)
var=$(eval echo "FSTAB_$i")
done
check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0

View file

@ -22,10 +22,8 @@
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
# This script is based on debian/zfsutils.zfs.init from the
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
# Source the common init script
. @sysconfdir@/zfs/zfs-functions

View file

@ -21,10 +21,8 @@
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
# This script is based on debian/zfsutils.zfs.init from the
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
# Source the common init script
. @sysconfdir@/zfs/zfs-functions
@ -32,6 +30,7 @@
ZED_NAME="zed"
ZED_PIDFILE="@runstatedir@/$ZED_NAME.pid"
# shellcheck disable=SC2034
extra_started_commands="reload"
# Exit if the package is not installed
@ -57,24 +56,20 @@ do_start()
do_stop()
{
local pools RET
local pools
check_module_loaded "zfs" || exit 0
zfs_action "Stopping ZFS Event Daemon" zfs_daemon_stop \
"$ZED_PIDFILE" "$ZED" "$ZED_NAME"
if [ "$?" -eq "0" ]
"$ZED_PIDFILE" "$ZED" "$ZED_NAME" || return "$?"
# Let's see if we have any pools imported
pools=$("$ZPOOL" list -H -oname)
if [ -z "$pools" ]
then
# Let's see if we have any pools imported
pools=$("$ZPOOL" list -H -oname)
if [ -z "$pools" ]
then
# No pools imported, it is/should be safe/possible to
# unload modules.
zfs_action "Unloading modules" rmmod zfs zunicode \
zavl zcommon znvpair zlua spl
return "$?"
fi
else
# No pools imported, it is/should be safe/possible to
# unload modules.
zfs_action "Unloading modules" rmmod zfs zunicode \
zavl zcommon znvpair zlua spl
return "$?"
fi
}

View file

@ -1 +1,4 @@
include $(top_srcdir)/config/Shellcheck.am
SUBDIRS = system system-generators
SHELLCHECKDIRS = system-generators

View file

@ -1,6 +1,14 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Rules.am
systemdgenerator_SCRIPTS = \
systemdgenerator_PROGRAMS = \
zfs-mount-generator
SUBSTFILES += $(systemdgenerator_SCRIPTS)
zfs_mount_generator_SOURCES = \
zfs-mount-generator.c
zfs_mount_generator_LDADD = \
$(abs_top_builddir)/lib/libzfs/libzfs.la
zfs_mount_generator_LDFLAGS = -pthread
include $(top_srcdir)/config/CppCheck.am

File diff suppressed because it is too large Load diff

View file

@ -1,474 +0,0 @@
#!/bin/sh
# zfs-mount-generator - generates systemd mount units for zfs
# Copyright (c) 2017 Antonio Russo <antonio.e.russo@gmail.com>
# Copyright (c) 2020 InsanePrawn <insane.prawny@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
set -e
FSLIST="@sysconfdir@/zfs/zfs-list.cache"
[ -d "${FSLIST}" ] || exit 0
[ "$(echo "${FSLIST}"/*)" = "${FSLIST}/*" ] && exit 0
do_fail() {
printf 'zfs-mount-generator: %s\n' "$*" > /dev/kmsg
exit 1
}
# test if $1 is in space-separated list $2
is_known() {
query="$1"
IFS=' '
for element in $2 ; do
if [ "$query" = "$element" ] ; then
return 0
fi
done
return 1
}
# create dependency on unit file $1
# of type $2, i.e. "wants" or "requires"
# in the target units from space-separated list $3
create_dependencies() {
unitfile="$1"
suffix="$2"
IFS=' '
for target in $3 ; do
target_dir="${dest_norm}/${target}.${suffix}/"
mkdir -p "${target_dir}"
ln -s "../${unitfile}" "${target_dir}"
done
}
# see systemd.generator
if [ $# -eq 0 ] ; then
dest_norm="/tmp"
elif [ $# -eq 3 ] ; then
dest_norm="${1}"
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>
# cached in $FSLIST, and each line is processed by the following function:
# See the list below for the properties and their order
process_line() {
# zfs list -H -o name,...
# fields are tab separated
IFS="$(printf '\t')"
# shellcheck disable=SC2086
set -- $1
dataset="${1}"
pool="${dataset%%/*}"
p_mountpoint="${2}"
p_canmount="${3}"
p_atime="${4}"
p_relatime="${5}"
p_devices="${6}"
p_exec="${7}"
p_readonly="${8}"
p_setuid="${9}"
p_nbmand="${10}"
p_encroot="${11}"
p_keyloc="${12}"
p_systemd_requires="${13}"
p_systemd_requiresmountsfor="${14}"
p_systemd_before="${15}"
p_systemd_after="${16}"
p_systemd_wantedby="${17}"
p_systemd_requiredby="${18}"
p_systemd_nofail="${19}"
p_systemd_ignore="${20}"
# Minimal pre-requisites to mount a ZFS dataset
# By ordering before zfs-mount.service, we avoid race conditions.
after="zfs-import.target"
before="zfs-mount.service"
wants="zfs-import.target"
requires=""
requiredmounts=""
bindsto=""
wantedby=""
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}"
fi
if [ -n "${p_systemd_before}" ] && \
[ "${p_systemd_before}" != "-" ] ; then
before="${p_systemd_before} ${before}"
fi
if [ -n "${p_systemd_requires}" ] && \
[ "${p_systemd_requires}" != "-" ] ; then
requires="Requires=${p_systemd_requires}"
fi
if [ -n "${p_systemd_requiresmountsfor}" ] && \
[ "${p_systemd_requiresmountsfor}" != "-" ] ; then
requiredmounts="RequiresMountsFor=${p_systemd_requiresmountsfor}"
fi
# Handle encryption
if [ -n "${p_encroot}" ] &&
[ "${p_encroot}" != "-" ] ; then
keyloadunit="zfs-load-key-$(systemd-escape "${p_encroot}").service"
if [ "${p_encroot}" = "${dataset}" ] ; then
keymountdep=""
if [ "${p_keyloc%%://*}" = "file" ] ; then
if [ -n "${requiredmounts}" ] ; then
keymountdep="${requiredmounts} '${p_keyloc#file://}'"
else
keymountdep="RequiresMountsFor='${p_keyloc#file://}'"
fi
keyloadscript="@sbindir@/zfs load-key \"${dataset}\""
elif [ "${p_keyloc}" = "prompt" ] ; then
keyloadscript="\
count=0;\
while [ \$\$count -lt 3 ];do\
systemd-ask-password --id=\"zfs:${dataset}\"\
\"Enter passphrase for ${dataset}:\"|\
@sbindir@/zfs load-key \"${dataset}\" && exit 0;\
count=\$\$((count + 1));\
done;\
exit 1"
else
printf 'zfs-mount-generator: (%s) invalid keylocation\n' \
"${dataset}" >/dev/kmsg
fi
keyloadcmd="\
/bin/sh -c '\
set -eu;\
keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\
[ \"\$\$keystatus\" = \"unavailable\" ] || exit 0;\
${keyloadscript}'"
keyunloadcmd="\
/bin/sh -c '\
set -eu;\
keystatus=\"\$\$(@sbindir@/zfs get -H -o value keystatus \"${dataset}\")\";\
[ \"\$\$keystatus\" = \"available\" ] || exit 0;\
@sbindir@/zfs unload-key \"${dataset}\"'"
# Generate the key-load .service unit
#
# Note: It is tempting to use a `<<EOF` style here-document for this, but
# bash requires a writable /tmp or $TMPDIR for that. This is not always
# available early during boot.
#
echo \
"# Automatically generated by zfs-mount-generator
[Unit]
Description=Load ZFS key for ${dataset}
SourcePath=${cachefile}
Documentation=man:zfs-mount-generator(8)
DefaultDependencies=no
Wants=${wants}
After=${after}
${requires}
${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
# Update the dependencies for the mount file to want the
# key-loading unit.
wants="${wants}"
bindsto="BindsTo=${keyloadunit}"
after="${after} ${keyloadunit}"
fi
# Prepare the .mount unit
# skip generation of the mount unit if org.openzfs.systemd:ignore is "on"
if [ -n "${p_systemd_ignore}" ] ; then
if [ "${p_systemd_ignore}" = "on" ] ; then
return
elif [ "${p_systemd_ignore}" = "-" ] \
|| [ "${p_systemd_ignore}" = "off" ] ; then
: # This is OK
else
do_fail "invalid org.openzfs.systemd:ignore for ${dataset}"
fi
fi
# Check for canmount=off .
if [ "${p_canmount}" = "off" ] ; then
return
elif [ "${p_canmount}" = "noauto" ] ; then
noauto="on"
elif [ "${p_canmount}" = "on" ] ; then
: # This is OK
else
do_fail "invalid canmount for ${dataset}"
fi
# Check for legacy and blank mountpoints.
if [ "${p_mountpoint}" = "legacy" ] ; then
return
elif [ "${p_mountpoint}" = "none" ] ; then
return
elif [ "${p_mountpoint%"${p_mountpoint#?}"}" != "/" ] ; then
do_fail "invalid mountpoint for ${dataset}"
fi
# Escape the mountpoint per systemd policy.
mountfile="$(systemd-escape --path --suffix=mount "${p_mountpoint}")"
# Parse options
# see lib/libzfs/libzfs_mount.c:zfs_add_options
opts=""
# atime
if [ "${p_atime}" = on ] ; then
# relatime
if [ "${p_relatime}" = on ] ; then
opts="${opts},atime,relatime"
elif [ "${p_relatime}" = off ] ; then
opts="${opts},atime,strictatime"
else
printf 'zfs-mount-generator: (%s) invalid relatime\n' \
"${dataset}" >/dev/kmsg
fi
elif [ "${p_atime}" = off ] ; then
opts="${opts},noatime"
else
printf 'zfs-mount-generator: (%s) invalid atime\n' \
"${dataset}" >/dev/kmsg
fi
# devices
if [ "${p_devices}" = on ] ; then
opts="${opts},dev"
elif [ "${p_devices}" = off ] ; then
opts="${opts},nodev"
else
printf 'zfs-mount-generator: (%s) invalid devices\n' \
"${dataset}" >/dev/kmsg
fi
# exec
if [ "${p_exec}" = on ] ; then
opts="${opts},exec"
elif [ "${p_exec}" = off ] ; then
opts="${opts},noexec"
else
printf 'zfs-mount-generator: (%s) invalid exec\n' \
"${dataset}" >/dev/kmsg
fi
# readonly
if [ "${p_readonly}" = on ] ; then
opts="${opts},ro"
elif [ "${p_readonly}" = off ] ; then
opts="${opts},rw"
else
printf 'zfs-mount-generator: (%s) invalid readonly\n' \
"${dataset}" >/dev/kmsg
fi
# setuid
if [ "${p_setuid}" = on ] ; then
opts="${opts},suid"
elif [ "${p_setuid}" = off ] ; then
opts="${opts},nosuid"
else
printf 'zfs-mount-generator: (%s) invalid setuid\n' \
"${dataset}" >/dev/kmsg
fi
# nbmand
if [ "${p_nbmand}" = on ] ; then
opts="${opts},mand"
elif [ "${p_nbmand}" = off ] ; then
opts="${opts},nomand"
else
printf 'zfs-mount-generator: (%s) invalid nbmand\n' \
"${dataset}" >/dev/kmsg
fi
if [ -n "${p_systemd_wantedby}" ] && \
[ "${p_systemd_wantedby}" != "-" ] ; then
noauto="on"
if [ "${p_systemd_wantedby}" = "none" ] ; then
wantedby=""
else
wantedby="${p_systemd_wantedby}"
before="${before} ${wantedby}"
fi
fi
if [ -n "${p_systemd_requiredby}" ] && \
[ "${p_systemd_requiredby}" != "-" ] ; then
noauto="on"
if [ "${p_systemd_requiredby}" = "none" ] ; then
requiredby=""
else
requiredby="${p_systemd_requiredby}"
before="${before} ${requiredby}"
fi
fi
# For datasets with canmount=on, a dependency is created for
# local-fs.target by default. To avoid regressions, this dependency
# is reduced to "wants" rather than "requires" when nofail is not "off".
# **THIS MAY CHANGE**
# noauto=on disables this behavior completely.
if [ "${noauto}" != "on" ] ; then
if [ "${p_systemd_nofail}" = "off" ] ; then
requiredby="local-fs.target"
before="${before} local-fs.target"
else
wantedby="local-fs.target"
if [ "${p_systemd_nofail}" != "on" ] ; then
before="${before} local-fs.target"
fi
fi
fi
# Handle existing files:
# 1. We never overwrite existing files, although we may delete
# files if we're sure they were created by us. (see 5.)
# 2. We handle files differently based on canmount. Units with canmount=on
# always have precedence over noauto. This is enforced by the sort pipe
# in the loop around this function.
# It is important to use $p_canmount and not $noauto here, since we
# sort by canmount while other properties also modify $noauto, e.g.
# org.openzfs.systemd:wanted-by.
# 3. If no unit file exists for a noauto dataset, we create one.
# Additionally, we use $noauto_files to track the unit file names
# (which are the systemd-escaped mountpoints) of all (exclusively)
# noauto datasets that had a file created.
# 4. If the file to be created is found in the tracking variable,
# we do NOT create it.
# 5. If a file exists for a noauto dataset, we check whether the file
# name is in the variable. If it is, we have multiple noauto datasets
# for the same mountpoint. In such cases, we remove the file for safety.
# To avoid further noauto datasets creating a file for this path again,
# we leave the file name in the tracking variable.
if [ -e "${dest_norm}/${mountfile}" ] ; then
if is_known "$mountfile" "$noauto_files" ; then
# if it's in $noauto_files, we must be noauto too. See 2.
printf 'zfs-mount-generator: removing duplicate noauto %s\n' \
"${mountfile}" >/dev/kmsg
# See 5.
rm "${dest_norm}/${mountfile}"
else
# don't log for canmount=noauto
if [ "${p_canmount}" = "on" ] ; then
printf 'zfs-mount-generator: %s already exists. Skipping.\n' \
"${mountfile}" >/dev/kmsg
fi
fi
# file exists; Skip current dataset.
return
else
if is_known "${mountfile}" "${noauto_files}" ; then
# See 4.
return
elif [ "${p_canmount}" = "noauto" ] ; then
noauto_files="${mountfile} ${noauto_files}"
fi
fi
# Create the .mount unit file.
#
# (Do not use `<<EOF`-style here-documents for this, see warning above)
#
echo \
"# Automatically generated by zfs-mount-generator
[Unit]
SourcePath=${cachefile}
Documentation=man:zfs-mount-generator(8)
Before=${before}
After=${after}
Wants=${wants}
${bindsto}
${requires}
${requiredmounts}
[Mount]
Where=${p_mountpoint}
What=${dataset}
Type=zfs
Options=defaults${opts},zfsutil" > "${dest_norm}/${mountfile}"
# Finally, create the appropriate dependencies
create_dependencies "${mountfile}" "wants" "$wantedby"
create_dependencies "${mountfile}" "requires" "$requiredby"
}
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}" | \
( # subshell is necessary for `sort|while read` and $noauto_files
noauto_files=""
while read -r fs ; do
process_line "${fs}"
done
)
done

View file

@ -14,7 +14,7 @@ ConditionPathIsDirectory=/sys/module/zfs
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN ${ZPOOL_IMPORT_OPTS}
[Install]
WantedBy=zfs-import.target

View file

@ -13,7 +13,7 @@ ConditionPathIsDirectory=/sys/module/zfs
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=@sbindir@/zpool import -aN -o cachefile=none
ExecStart=@sbindir@/zpool import -aN -o cachefile=none ${ZPOOL_IMPORT_OPTS}
[Install]
WantedBy=zfs-import.target

View file

@ -1,4 +1,5 @@
include $(top_srcdir)/config/Substfiles.am
include $(top_srcdir)/config/Shellcheck.am
pkgsysconfdir = $(sysconfdir)/zfs
@ -13,3 +14,5 @@ pkgsysconf_SCRIPTS = \
zfs-functions
SUBSTFILES += $(pkgsysconf_SCRIPTS)
SHELLCHECK_SHELL = dash # local variables

View file

@ -5,10 +5,8 @@
#
# Released under the 2-clause BSD license.
#
# The original script that acted as a template for this script came from
# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
# licensing stansa) in the commit dated Mar 24, 2011:
# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
# This script is based on debian/zfsutils.zfs.init from the
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
PATH=/sbin:/bin:/usr/bin:/usr/sbin
@ -20,7 +18,7 @@ elif [ -L /etc/init.d/functions.sh ]; then
# Gentoo
. /etc/init.d/functions.sh
elif [ -f /lib/lsb/init-functions ]; then
# LSB, Debian GNU/Linux and derivatives
# LSB, Debian, and derivatives
. /lib/lsb/init-functions
fi
@ -46,7 +44,7 @@ elif type success > /dev/null 2>&1 ; then
fi
}
zfs_log_begin_msg() { echo -n "$1 "; }
zfs_log_begin_msg() { printf "%s" "$1 "; }
zfs_log_end_msg() {
zfs_set_ifs "$OLD_IFS"
if [ "$1" -eq 0 ]; then
@ -63,17 +61,17 @@ elif type success > /dev/null 2>&1 ; then
echo
zfs_set_ifs "$TMP_IFS"
}
zfs_log_progress_msg() { echo -n $"$1"; }
zfs_log_progress_msg() { printf "%s" "$""$1"; }
elif type einfo > /dev/null 2>&1 ; then
# Gentoo functions
zfs_log_begin_msg() { ebegin "$1"; }
zfs_log_end_msg() { eend "$1"; }
zfs_log_failure_msg() { eend "$1"; }
# zfs_log_progress_msg() { echo -n "$1"; }
zfs_log_progress_msg() { echo -n; }
# zfs_log_progress_msg() { printf "%s" "$1"; }
zfs_log_progress_msg() { :; }
else
# Unknown - simple substitutes.
zfs_log_begin_msg() { echo -n "$1"; }
zfs_log_begin_msg() { printf "%s" "$1"; }
zfs_log_end_msg() {
ret=$1
if [ "$ret" -ge 1 ]; then
@ -84,7 +82,7 @@ else
return "$ret"
}
zfs_log_failure_msg() { echo "$1"; }
zfs_log_progress_msg() { echo -n "$1"; }
zfs_log_progress_msg() { printf "%s" "$1"; }
fi
# Paths to what we need
@ -136,27 +134,28 @@ zfs_daemon_start()
{
local PIDFILE="$1"; shift
local DAEMON_BIN="$1"; shift
local DAEMON_ARGS="$*"
if type start-stop-daemon > /dev/null 2>&1 ; then
# LSB functions
start-stop-daemon --start --quiet --pidfile "$PIDFILE" \
--exec "$DAEMON_BIN" --test > /dev/null || return 1
start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \
$DAEMON_ARGS || return 2
# shellcheck disable=SC2086
start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \
"$@" || return 2
# On Debian GNU/Linux, there's a 'sendsigs' script that will
# On Debian, there's a 'sendsigs' script that will
# kill basically everything quite early and zed is stopped
# much later than that. We don't want zed to be among them,
# so add the zed pid to list of pids to ignore.
if [ -f "$PIDFILE" -a -d /run/sendsigs.omit.d ]
if [ -f "$PIDFILE" ] && [ -d /run/sendsigs.omit.d ]
then
ln -sf "$PIDFILE" /run/sendsigs.omit.d/zed
fi
elif type daemon > /dev/null 2>&1 ; then
# Fedora/RedHat functions
daemon --pidfile "$PIDFILE" "$DAEMON_BIN" $DAEMON_ARGS
# Fedora/RedHat functions
# shellcheck disable=SC2086
daemon --pidfile "$PIDFILE" "$DAEMON_BIN" "$@"
return $?
else
# Unsupported
@ -182,15 +181,17 @@ zfs_daemon_stop()
# LSB functions
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
--pidfile "$PIDFILE" --name "$DAEMON_NAME"
[ "$?" = 0 ] && rm -f "$PIDFILE"
ret="$?"
[ "$ret" = 0 ] && rm -f "$PIDFILE"
return $?
return "$ret"
elif type killproc > /dev/null 2>&1 ; then
# Fedora/RedHat functions
killproc -p "$PIDFILE" "$DAEMON_NAME"
[ "$?" = 0 ] && rm -f "$PIDFILE"
ret="$?"
[ "$ret" = 0 ] && rm -f "$PIDFILE"
return $?
return "$ret"
else
# Unsupported
return 3
@ -234,7 +235,7 @@ zfs_daemon_reload()
return $?
elif type killproc > /dev/null 2>&1 ; then
# Fedora/RedHat functions
killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP
killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP
return $?
else
# Unsupported
@ -287,6 +288,7 @@ checksystem()
# HOWEVER, only do this if we're called at the boot up
# (from init), not if we're running interactively (as in
# from the shell - we know what we're doing).
# shellcheck disable=SC2154
[ -n "$init" ] && exit 3
fi
@ -301,6 +303,7 @@ checksystem()
get_root_pool()
{
# shellcheck disable=SC2046
set -- $(mount | grep ' on / ')
[ "$5" = "zfs" ] && echo "${1%%/*}"
}
@ -338,9 +341,10 @@ load_module()
read_mtab()
{
local match="$1"
local fs mntpnt fstype opts rest TMPFILE
local fs mntpnt fstype opts rest
# Unset all MTAB_* variables
# shellcheck disable=SC2046
unset $(env | grep ^MTAB_ | sed 's,=.*,,')
while read -r fs mntpnt fstype opts rest; do
@ -352,8 +356,8 @@ read_mtab()
# * We need to use the external echo, because the
# internal one would interpret the backslash code
# (incorrectly), giving us a  instead.
mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,g")
fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,")
mntpnt=$(/bin/echo "$mntpnt" | sed 's,\\0,\\00,g')
fs=$(/bin/echo "$fs" | sed 's,\\0,\\00,')
# Remove 'unwanted' characters.
mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,,g' \
@ -361,7 +365,7 @@ read_mtab()
fs=$(printf '%b\n' "$fs")
# Set the variable.
eval export MTAB_$mntpnt=\"$fs\"
eval export "MTAB_$mntpnt=\"$fs\""
fi
done < /proc/self/mounts
}
@ -371,10 +375,10 @@ in_mtab()
local mntpnt="$1"
# Remove 'unwanted' characters.
mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,,g' \
-e 's,-,,g' -e 's,\.,,g' -e 's, ,,g')
-e 's,-,,g' -e 's,\.,,g' -e 's, ,,g')
local var
var="$(eval echo MTAB_$mntpnt)"
var="$(eval echo "MTAB_$mntpnt")"
[ "$(eval echo "$""$var")" != "" ]
return "$?"
}
@ -383,21 +387,22 @@ in_mtab()
read_fstab()
{
local match="$1"
local i var TMPFILE
local i var
# Unset all FSTAB_* variables
# shellcheck disable=SC2046
unset $(env | grep ^FSTAB_ | sed 's,=.*,,')
i=0
while read -r fs mntpnt fstype opts; do
echo "$fs" | egrep -qE '^#|^$' && continue
echo "$mntpnt" | egrep -qE '^none|^swap' && continue
echo "$fstype" | egrep -qE '^swap' && continue
echo "$fs" | grep -qE '^#|^$' && continue
echo "$mntpnt" | grep -qE '^none|^swap' && continue
echo "$fstype" | grep -qE '^swap' && continue
if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then
eval export FSTAB_dev_$i="$fs"
eval export "FSTAB_dev_$i=$fs"
fs=$(printf '%b\n' "$fs" | sed 's,/,_,g')
eval export FSTAB_$i="$mntpnt"
eval export "FSTAB_$i=$mntpnt"
i=$((i + 1))
fi
@ -408,7 +413,7 @@ in_fstab()
{
local var
var="$(eval echo FSTAB_$1)"
var="$(eval echo "FSTAB_$1")"
[ "${var}" != "" ]
return $?
}
@ -416,19 +421,11 @@ in_fstab()
is_mounted()
{
local mntpt="$1"
local line
local mp
mount | \
while read line; do
if echo "$line" | grep -q " on $mntpt "; then
# returns:
# 0 on unsuccessful match
# 1 on a successful match
return 1
fi
done
while read -r _ mp _; do
[ "$mp" = "$mntpt" ] && return 0
done < /proc/self/mounts
# The negation will flip the subshell return result where the default
# return value is 0 when a match is not found.
return $(( !$? ))
return 1
}

View file

@ -68,6 +68,7 @@ KERNEL_H = \
vmsystm.h \
vnode_impl.h \
vnode.h \
wmsum.h \
zmod.h \
zone.h

View file

@ -210,10 +210,6 @@ extern kstat_t *__kstat_create(const char *ks_module, int ks_instance,
extern void __kstat_install(kstat_t *ksp);
extern void __kstat_delete(kstat_t *ksp);
extern void kstat_waitq_enter(kstat_io_t *);
extern void kstat_waitq_exit(kstat_io_t *);
extern void kstat_runq_enter(kstat_io_t *);
extern void kstat_runq_exit(kstat_io_t *);
#define kstat_set_seq_raw_ops(k, h, d, a) \
__kstat_set_seq_raw_ops(k, h, d, a)

View file

@ -0,0 +1,72 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* wmsum counters are a reduced version of aggsum counters, optimized for
* write-mostly scenarios. They do not provide optimized read functions,
* but instead allow much cheaper add function. The primary usage is
* infrequently read statistic counters, not requiring exact precision.
*
* The FreeBSD implementation is directly mapped into counter(9) KPI.
*/
#ifndef _SYS_WMSUM_H
#define _SYS_WMSUM_H
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/counter.h>
#include <sys/malloc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define wmsum_t counter_u64_t
static inline void
wmsum_init(wmsum_t *ws, uint64_t value)
{
*ws = counter_u64_alloc(M_WAITOK);
counter_u64_add(*ws, value);
}
static inline void
wmsum_fini(wmsum_t *ws)
{
counter_u64_free(*ws);
}
static inline uint64_t
wmsum_value(wmsum_t *ws)
{
return (counter_u64_fetch(*ws));
}
static inline void
wmsum_add(wmsum_t *ws, int64_t delta)
{
counter_u64_add(*ws, delta);
}
#ifdef __cplusplus
}
#endif
#endif /* _SYS_WMSUM_H */

View file

@ -54,6 +54,7 @@ KERNEL_H = \
vmsystm.h \
vnode.h \
wait.h \
wmsum.h \
zmod.h \
zone.h

View file

@ -48,6 +48,8 @@
#define atomic_sub_32_nv(v, i) atomic_sub_return((i), (atomic_t *)(v))
#define atomic_cas_32(v, x, y) atomic_cmpxchg((atomic_t *)(v), x, y)
#define atomic_swap_32(v, x) atomic_xchg((atomic_t *)(v), x)
#define atomic_load_32(v) atomic_read((atomic_t *)(v))
#define atomic_store_32(v, x) atomic_set((atomic_t *)(v), x)
#define atomic_inc_64(v) atomic64_inc((atomic64_t *)(v))
#define atomic_dec_64(v) atomic64_dec((atomic64_t *)(v))
#define atomic_add_64(v, i) atomic64_add((i), (atomic64_t *)(v))
@ -58,6 +60,8 @@
#define atomic_sub_64_nv(v, i) atomic64_sub_return((i), (atomic64_t *)(v))
#define atomic_cas_64(v, x, y) atomic64_cmpxchg((atomic64_t *)(v), x, y)
#define atomic_swap_64(v, x) atomic64_xchg((atomic64_t *)(v), x)
#define atomic_load_64(v) atomic64_read((atomic64_t *)(v))
#define atomic_store_64(v, x) atomic64_set((atomic64_t *)(v), x)
#ifdef _LP64
static __inline__ void *

View file

@ -206,10 +206,6 @@ extern void kstat_proc_entry_install(kstat_proc_entry_t *kpep, mode_t mode,
extern void __kstat_install(kstat_t *ksp);
extern void __kstat_delete(kstat_t *ksp);
extern void kstat_waitq_enter(kstat_io_t *);
extern void kstat_waitq_exit(kstat_io_t *);
extern void kstat_runq_enter(kstat_io_t *);
extern void kstat_runq_exit(kstat_io_t *);
#define kstat_set_raw_ops(k, h, d, a) \
__kstat_set_raw_ops(k, h, d, a)

View file

@ -0,0 +1,76 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* wmsum counters are a reduced version of aggsum counters, optimized for
* write-mostly scenarios. They do not provide optimized read functions,
* but instead allow much cheaper add function. The primary usage is
* infrequently read statistic counters, not requiring exact precision.
*
* The Linux implementation is directly mapped into percpu_counter KPI.
*/
#ifndef _SYS_WMSUM_H
#define _SYS_WMSUM_H
#include <linux/percpu_counter.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct percpu_counter wmsum_t;
static inline void
wmsum_init(wmsum_t *ws, uint64_t value)
{
#ifdef HAVE_PERCPU_COUNTER_INIT_WITH_GFP
percpu_counter_init(ws, value, GFP_KERNEL);
#else
percpu_counter_init(ws, value);
#endif
}
static inline void
wmsum_fini(wmsum_t *ws)
{
percpu_counter_destroy(ws);
}
static inline uint64_t
wmsum_value(wmsum_t *ws)
{
return (percpu_counter_sum(ws));
}
static inline void
wmsum_add(wmsum_t *ws, int64_t delta)
{
#ifdef HAVE_PERCPU_COUNTER_ADD_BATCH
percpu_counter_add_batch(ws, delta, INT_MAX / 2);
#else
__percpu_counter_add(ws, delta, INT_MAX / 2);
#endif
}
#ifdef __cplusplus
}
#endif
#endif /* _SYS_WMSUM_H */

View file

@ -39,15 +39,16 @@ struct aggsum_bucket {
typedef struct aggsum {
kmutex_t as_lock;
int64_t as_lower_bound;
int64_t as_upper_bound;
uint64_t as_upper_bound;
aggsum_bucket_t *as_buckets ____cacheline_aligned;
uint_t as_numbuckets;
aggsum_bucket_t *as_buckets;
uint_t as_bucketshift;
} aggsum_t;
void aggsum_init(aggsum_t *, uint64_t);
void aggsum_fini(aggsum_t *);
int64_t aggsum_lower_bound(aggsum_t *);
int64_t aggsum_upper_bound(aggsum_t *);
uint64_t aggsum_upper_bound(aggsum_t *);
int aggsum_compare(aggsum_t *, uint64_t);
uint64_t aggsum_value(aggsum_t *);
void aggsum_add(aggsum_t *, int64_t);

View file

@ -74,20 +74,20 @@ typedef struct arc_state {
/*
* list of evictable buffers
*/
multilist_t *arcs_list[ARC_BUFC_NUMTYPES];
multilist_t arcs_list[ARC_BUFC_NUMTYPES];
/*
* supports the "dbufs" kstat
*/
arc_state_type_t arcs_state;
/*
* total amount of evictable data in this state
*/
zfs_refcount_t arcs_esize[ARC_BUFC_NUMTYPES];
zfs_refcount_t arcs_esize[ARC_BUFC_NUMTYPES] ____cacheline_aligned;
/*
* total amount of data in this state; this includes: evictable,
* non-evictable, ARC_BUFC_DATA, and ARC_BUFC_METADATA.
*/
zfs_refcount_t arcs_size;
/*
* supports the "dbufs" kstat
*/
arc_state_type_t arcs_state;
} arc_state_t;
typedef struct arc_callback arc_callback_t;

View file

@ -27,18 +27,18 @@
#ifndef _SYS_DATASET_KSTATS_H
#define _SYS_DATASET_KSTATS_H
#include <sys/aggsum.h>
#include <sys/wmsum.h>
#include <sys/dmu.h>
#include <sys/kstat.h>
typedef struct dataset_aggsum_stats_t {
aggsum_t das_writes;
aggsum_t das_nwritten;
aggsum_t das_reads;
aggsum_t das_nread;
aggsum_t das_nunlinks;
aggsum_t das_nunlinked;
} dataset_aggsum_stats_t;
typedef struct dataset_sum_stats_t {
wmsum_t dss_writes;
wmsum_t dss_nwritten;
wmsum_t dss_reads;
wmsum_t dss_nread;
wmsum_t dss_nunlinks;
wmsum_t dss_nunlinked;
} dataset_sum_stats_t;
typedef struct dataset_kstat_values {
kstat_named_t dkv_ds_name;
@ -59,7 +59,7 @@ typedef struct dataset_kstat_values {
} dataset_kstat_values_t;
typedef struct dataset_kstats {
dataset_aggsum_stats_t dk_aggsums;
dataset_sum_stats_t dk_sums;
kstat_t *dk_kstats;
} dataset_kstats_t;

View file

@ -153,7 +153,7 @@ struct objset {
/* no lock needed: */
struct dmu_tx *os_synctx; /* XXX sketchy */
zil_header_t os_zil_header;
multilist_t *os_synced_dnodes;
multilist_t os_synced_dnodes;
uint64_t os_flags;
uint64_t os_freed_dnodes;
boolean_t os_rescan_dnodes;
@ -172,7 +172,7 @@ struct objset {
/* Protected by os_lock */
kmutex_t os_lock;
multilist_t *os_dirty_dnodes[TXG_SIZE];
multilist_t os_dirty_dnodes[TXG_SIZE];
list_t os_dnodes;
list_t os_downgraded_dbufs;

View file

@ -206,7 +206,7 @@ struct metaslab_class {
* List of all loaded metaslabs in the class, sorted in order of most
* recent use.
*/
multilist_t *mc_metaslab_txg_list;
multilist_t mc_metaslab_txg_list;
metaslab_class_allocator_t mc_allocator[];
};

View file

@ -71,8 +71,9 @@ struct multilist {
multilist_sublist_index_func_t *ml_index_func;
};
void multilist_create(multilist_t *, size_t, size_t,
multilist_sublist_index_func_t *);
void multilist_destroy(multilist_t *);
multilist_t *multilist_create(size_t, size_t, multilist_sublist_index_func_t *);
void multilist_insert(multilist_t *, void *);
void multilist_remove(multilist_t *, void *);

View file

@ -916,7 +916,6 @@ typedef struct spa_stats {
spa_history_list_t read_history;
spa_history_list_t txg_history;
spa_history_kstat_t tx_assign_histogram;
spa_history_kstat_t io_history;
spa_history_list_t mmp_history;
spa_history_kstat_t state; /* pool state */
spa_history_kstat_t iostats;

View file

@ -362,12 +362,6 @@ extern kstat_t *kstat_create(const char *, int,
const char *, const char *, uchar_t, ulong_t, uchar_t);
extern void kstat_install(kstat_t *);
extern void kstat_delete(kstat_t *);
extern void kstat_waitq_enter(kstat_io_t *);
extern void kstat_waitq_exit(kstat_io_t *);
extern void kstat_runq_enter(kstat_io_t *);
extern void kstat_runq_exit(kstat_io_t *);
extern void kstat_waitq_to_runq(kstat_io_t *);
extern void kstat_runq_back_to_waitq(kstat_io_t *);
extern void kstat_set_raw_ops(kstat_t *ksp,
int (*headers)(char *buf, size_t size),
int (*data)(char *buf, size_t size, void *data),

View file

@ -82,6 +82,7 @@ void zfs_ioctl_register(const char *, zfs_ioc_t, zfs_ioc_func_t *,
boolean_t, boolean_t, const zfs_ioc_key_t *, size_t);
uint64_t zfs_max_nvlist_src_size_os(void);
void zfs_ioctl_update_mount_cache(const char *dsname);
void zfs_ioctl_init_os(void);
boolean_t zfs_vfs_held(zfsvfs_t *);

View file

@ -54,6 +54,13 @@ nvlist_print_json_string(FILE *fp, const char *input)
FPRINTF(fp, "\"");
while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
if (sz == (size_t)-1 || sz == (size_t)-2) {
/*
* We last read an invalid multibyte character sequence,
* so return an error.
*/
return (-1);
}
switch (c) {
case '"':
FPRINTF(fp, "\\\"");
@ -97,14 +104,6 @@ nvlist_print_json_string(FILE *fp, const char *input)
input += sz;
}
if (sz == (size_t)-1 || sz == (size_t)-2) {
/*
* We last read an invalid multibyte character sequence,
* so return an error.
*/
return (-1);
}
FPRINTF(fp, "\"");
return (0);
}

Some files were not shown because too many files have changed in this diff Show more