zfs: merge openzfs/zfs@e63d026b9
Notable upstream pull request merges: #1747702fdd26e5Add knob to disable slow io notifications #17792d0294aa75Update dnode_next_offset_level to accept blkid instead of offset #178248c225ff1bFix gang write late_arrival bug #17861 -multiple Lift userspace definitions out of zfs_context.h #17872dcada084bPass flags to more DMU write/hold functions #17875ec268cdf9Fix caching of DDT log and BRT #17875ea125eeb5BRT: Round bv_entcount up to BRT_BLOCKSIZE #178776cfc3dba9Cleanup ZIO_FLAG_IO_RETRY vs TRYHARD usage #17885e63d026b9cmd/zpool cstyle issues #17890b4f073b5aAdd BRT support to zpool prefetch command #17903baefe098eZIO: Set minimum number of free issue threads to 32 #179066e12f0bd7spa_misc: add an API for spa_namespace_lock #17908e26b9fc87FreeBSD: Add support for _PC_CASE_INSENSITIVE #17911 -multiple Update library ABI versions for v2.4.0 #179158aaed7dc4BRT: Fix ranges to blocks conversion math #17916cc5cae547BRT: Increase block size from 4KB to 8KB #1792172b2a9571ZAP: Remove dmu_object_info_from_dnode() call Obtained from: OpenZFS OpenZFS commit:e63d026b91
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
- the *last* commit message contains 'ZFS-CI-Type: quick'
|
||||
or if (heuristics):
|
||||
- the files changed are not in the list of specified directories, and
|
||||
- all commit messages do not contain 'ZFS-CI-Type: full'
|
||||
- all commit messages do not contain 'ZFS-CI-Type: (full|linux|freebsd)'
|
||||
|
||||
Otherwise prints "full".
|
||||
"""
|
||||
@@ -70,7 +70,7 @@ def output_type(type, reason):
|
||||
|
||||
for line in last_commit_message_raw.stdout.decode().splitlines():
|
||||
if line.strip().lower() == 'zfs-ci-type: quick':
|
||||
output_type('quick', f'explicitly requested by HEAD commit {head}')
|
||||
output_type('quick', f'requested by HEAD commit {head}')
|
||||
|
||||
# check all commit messages
|
||||
all_commit_message_raw = subprocess.run([
|
||||
@@ -83,8 +83,12 @@ def output_type(type, reason):
|
||||
for line in all_commit_message:
|
||||
if line.startswith('ZFS-CI-Commit:'):
|
||||
commit_ref = line.lstrip('ZFS-CI-Commit:').rstrip()
|
||||
if line.strip().lower() == 'zfs-ci-type: freebsd':
|
||||
output_type('freebsd', f'requested by commit {commit_ref}')
|
||||
if line.strip().lower() == 'zfs-ci-type: linux':
|
||||
output_type('linux', f'requested by commit {commit_ref}')
|
||||
if line.strip().lower() == 'zfs-ci-type: full':
|
||||
output_type('full', f'explicitly requested by commit {commit_ref}')
|
||||
output_type('full', f'requested by commit {commit_ref}')
|
||||
|
||||
# check changed files
|
||||
changed_files_raw = subprocess.run([
|
||||
|
||||
@@ -47,16 +47,15 @@ case "$OS" in
|
||||
OSNAME="Archlinux"
|
||||
URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
|
||||
;;
|
||||
centos-stream10)
|
||||
OSNAME="CentOS Stream 10"
|
||||
# TODO: #16903 Overwrite OSv to stream9 for virt-install until it's added to osinfo
|
||||
OSv="centos-stream9"
|
||||
URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
|
||||
;;
|
||||
centos-stream9)
|
||||
OSNAME="CentOS Stream 9"
|
||||
URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"
|
||||
;;
|
||||
centos-stream10)
|
||||
OSNAME="CentOS Stream 10"
|
||||
OSv="centos-stream9"
|
||||
URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2"
|
||||
;;
|
||||
debian11)
|
||||
OSNAME="Debian 11"
|
||||
URL="https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-generic-amd64.qcow2"
|
||||
@@ -83,6 +82,11 @@ case "$OS" in
|
||||
OSv="fedora-unknown"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-42-1.1.x86_64.qcow2"
|
||||
;;
|
||||
fedora43)
|
||||
OSNAME="Fedora 43"
|
||||
OSv="fedora-unknown"
|
||||
URL="https://download.fedoraproject.org/pub/fedora/linux/releases/43/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2"
|
||||
;;
|
||||
freebsd13-5r)
|
||||
FreeBSD="13.5-RELEASE"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
@@ -95,8 +99,8 @@ case "$OS" in
|
||||
FreeBSD="14.2-RELEASE"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
OSv="freebsd14.0"
|
||||
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
|
||||
URLxz="$FREEBSD_REL/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI.raw.xz"
|
||||
KSRC="$FREEBSD_REL/../amd64/$FreeBSD/src.txz"
|
||||
;;
|
||||
freebsd14-3r)
|
||||
FreeBSD="14.3-RELEASE"
|
||||
@@ -120,8 +124,8 @@ case "$OS" in
|
||||
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
|
||||
KSRC="$FREEBSD_SNAP/../amd64/$FreeBSD/src.txz"
|
||||
;;
|
||||
freebsd15-0c)
|
||||
FreeBSD="15.0-ALPHA4"
|
||||
freebsd15-0s)
|
||||
FreeBSD="15.0-STABLE"
|
||||
OSNAME="FreeBSD $FreeBSD"
|
||||
OSv="freebsd14.0"
|
||||
URLxz="$FREEBSD_SNAP/$FreeBSD/amd64/Latest/FreeBSD-$FreeBSD-amd64-BASIC-CI-ufs.raw.xz"
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42']
|
||||
os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42', 'fedora43']
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
+24
-14
@@ -29,24 +29,34 @@ jobs:
|
||||
- name: Generate OS config and CI type
|
||||
id: os
|
||||
run: |
|
||||
FULL_OS='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora41", "fedora42", "freebsd13-5r", "freebsd14-3s", "freebsd15-0c", "ubuntu22", "ubuntu24"]'
|
||||
QUICK_OS='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd14-3s", "ubuntu24"]'
|
||||
ci_type="default"
|
||||
|
||||
# determine CI type when running on PR
|
||||
ci_type="full"
|
||||
if ${{ github.event_name == 'pull_request' }}; then
|
||||
head=${{ github.event.pull_request.head.sha }}
|
||||
base=${{ github.event.pull_request.base.sha }}
|
||||
ci_type=$(python3 .github/workflows/scripts/generate-ci-type.py $head $base)
|
||||
fi
|
||||
if [ "$ci_type" == "quick" ]; then
|
||||
os_selection="$QUICK_OS"
|
||||
else
|
||||
os_selection="$FULL_OS"
|
||||
fi
|
||||
|
||||
case "$ci_type" in
|
||||
quick)
|
||||
os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-0s", "ubuntu24"]'
|
||||
;;
|
||||
linux)
|
||||
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora41", "fedora42", "fedora43", "ubuntu22", "ubuntu24"]'
|
||||
;;
|
||||
freebsd)
|
||||
os_selection='["freebsd13-5r", "freebsd14-2r", "freebsd14-3r", "freebsd13-5s", "freebsd14-3s", "freebsd15-0s", "freebsd16-0c"]'
|
||||
;;
|
||||
*)
|
||||
# default list
|
||||
os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "freebsd14-3r", "freebsd15-0s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
|
||||
;;
|
||||
esac
|
||||
|
||||
if ${{ github.event.inputs.fedora_kernel_ver != '' }}; then
|
||||
# They specified a custom kernel version for Fedora. Use only
|
||||
# Fedora runners.
|
||||
# They specified a custom kernel version for Fedora.
|
||||
# Use only Fedora runners.
|
||||
os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]')
|
||||
else
|
||||
# Normal case
|
||||
@@ -62,13 +72,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# rhl: almalinux8, almalinux9, centos-stream9, fedora4x
|
||||
# rhl: almalinux8, almalinux9, centos-streamX, fedora4x
|
||||
# debian: debian12, debian13, ubuntu22, ubuntu24
|
||||
# misc: archlinux, tumbleweed
|
||||
# FreeBSD variants of 2025-06:
|
||||
# FreeBSD variants of november 2025:
|
||||
# FreeBSD Release: freebsd13-5r, freebsd14-2r, freebsd14-3r
|
||||
# FreeBSD Stable: freebsd13-5s, freebsd14-3s
|
||||
# FreeBSD Current: freebsd15-0c, freebsd16-0c
|
||||
# FreeBSD Stable: freebsd13-5s, freebsd14-3s, freebsd15-0s
|
||||
# FreeBSD Current: freebsd16-0c
|
||||
os: ${{ fromJson(needs.test-config.outputs.test_os) }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
|
||||
@@ -10,7 +10,7 @@ This repository contains the code for running OpenZFS on Linux and FreeBSD.
|
||||
# Official Resources
|
||||
|
||||
* [Documentation](https://openzfs.github.io/openzfs-docs/) - for using and developing this repo
|
||||
* [ZoL Site](https://zfsonlinux.org) - Linux release info & links
|
||||
* [ZoL site](https://zfsonlinux.org) - Linux release info & links
|
||||
* [Mailing lists](https://openzfs.github.io/openzfs-docs/Project%20and%20Community/Mailing%20Lists.html)
|
||||
* [OpenZFS site](https://openzfs.org/) - for conference videos and info on other platforms (illumos, OSX, Windows, etc)
|
||||
|
||||
|
||||
@@ -1,62 +1,3 @@
|
||||
#!/bin/sh
|
||||
[ "${0%/*}" = "$0" ] || cd "${0%/*}" || exit
|
||||
|
||||
# %reldir%/%canon_reldir% (%D%/%C%) only appeared in automake 1.14, but RHEL/CentOS 7 has 1.13.4
|
||||
# This is an (overly) simplistic preprocessor that papers around this for the duration of the generation step,
|
||||
# and can be removed once support for CentOS 7 is dropped
|
||||
automake --version | awk '{print $NF; exit}' | (
|
||||
IFS=. read -r AM_MAJ AM_MIN _
|
||||
[ "$AM_MAJ" -gt 1 ] || [ "$AM_MIN" -ge 14 ]
|
||||
) || {
|
||||
process_root() {
|
||||
root="$1"; shift
|
||||
|
||||
grep -q '%[CD]%' "$root/Makefile.am" || return
|
||||
find "$root" -name Makefile.am "$@" | while read -r dir; do
|
||||
dir="${dir%/Makefile.am}"
|
||||
grep -q '%[CD]%' "$dir/Makefile.am" || continue
|
||||
|
||||
reldir="${dir#"$root"}"
|
||||
reldir="${reldir#/}"
|
||||
|
||||
canon_reldir="$(printf '%s' "$reldir" | tr -C 'a-zA-Z0-9@_' '_')"
|
||||
|
||||
reldir_slash="$reldir/"
|
||||
canon_reldir_slash="${canon_reldir}_"
|
||||
[ -z "$reldir" ] && reldir_slash=
|
||||
[ -z "$reldir" ] && canon_reldir_slash=
|
||||
|
||||
echo "$dir/Makefile.am" >&3
|
||||
sed -i~ -e "s:%D%/:$reldir_slash:g" -e "s:%D%:$reldir:g" \
|
||||
-e "s:%C%_:$canon_reldir_slash:g" -e "s:%C%:$canon_reldir:g" "$dir/Makefile.am"
|
||||
done 3>>"$substituted_files"
|
||||
}
|
||||
|
||||
rollback() {
|
||||
while read -r f; do
|
||||
mv "$f~" "$f"
|
||||
done < "$substituted_files"
|
||||
rm -f "$substituted_files"
|
||||
}
|
||||
|
||||
|
||||
echo "Automake <1.14; papering over missing %reldir%/%canon_reldir% support" >&2
|
||||
|
||||
substituted_files="$(mktemp)"
|
||||
trap rollback EXIT
|
||||
|
||||
roots="$(sed '/Makefile$/!d;/module/d;s:^\s*:./:;s:/Makefile::;/^\.$/d' configure.ac)"
|
||||
|
||||
IFS="
|
||||
"
|
||||
for root in $roots; do
|
||||
root="${root#./}"
|
||||
process_root "$root"
|
||||
done
|
||||
|
||||
set -f
|
||||
# shellcheck disable=SC2086,SC2046
|
||||
process_root . $(printf '!\n-path\n%s/*\n' $roots)
|
||||
}
|
||||
|
||||
autoreconf -fiv && rm -rf autom4te.cache
|
||||
autoreconf -fiv "$(dirname "$0")" && rm -rf "$(dirname "$0")"/autom4te.cache
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <sys/vdev_raidz_impl.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <libzpool.h>
|
||||
#include "raidz_test.h"
|
||||
|
||||
static int *rand_data;
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include <sys/zstd/zstd.h>
|
||||
#include <sys/backtrace.h>
|
||||
|
||||
#include <libzpool.h>
|
||||
#include <libnvpair.h>
|
||||
#include <libzutil.h>
|
||||
#include <libzfs_core.h>
|
||||
@@ -7899,11 +7900,11 @@ zdb_set_skip_mmp(char *target)
|
||||
* Disable the activity check to allow examination of
|
||||
* active pools.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if ((spa = spa_lookup(target)) != NULL) {
|
||||
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
|
||||
}
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
#define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE"
|
||||
@@ -10022,13 +10023,13 @@ main(int argc, char **argv)
|
||||
* try opening the pool after clearing the
|
||||
* log state.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
if ((spa = spa_lookup(target)) != NULL &&
|
||||
spa->spa_log_state == SPA_LOG_MISSING) {
|
||||
spa->spa_log_state = SPA_LOG_CLEAR;
|
||||
error = 0;
|
||||
}
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
if (!error) {
|
||||
error = spa_open_rewind(target, &spa,
|
||||
|
||||
@@ -145,11 +145,11 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
|
||||
switch (zpc->zpc_op) {
|
||||
case ZFS_PROJECT_OP_LIST:
|
||||
(void) printf("%5u %c %s\n", fsx.fsx_projid,
|
||||
(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) ? 'P' : '-', name);
|
||||
(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) ? 'P' : '-', name);
|
||||
goto out;
|
||||
case ZFS_PROJECT_OP_CHECK:
|
||||
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
|
||||
fsx.fsx_xflags & ZFS_PROJINHERIT_FL)
|
||||
fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)
|
||||
goto out;
|
||||
|
||||
if (!zpc->zpc_newline) {
|
||||
@@ -164,29 +164,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
|
||||
"(%u/%u)\n", name, fsx.fsx_projid,
|
||||
(uint32_t)zpc->zpc_expected_projid);
|
||||
|
||||
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
|
||||
if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
|
||||
(void) printf("%s - project inherit flag is not set\n",
|
||||
name);
|
||||
|
||||
goto out;
|
||||
case ZFS_PROJECT_OP_CLEAR:
|
||||
if (!(fsx.fsx_xflags & ZFS_PROJINHERIT_FL) &&
|
||||
if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) &&
|
||||
(zpc->zpc_keep_projid ||
|
||||
fsx.fsx_projid == ZFS_DEFAULT_PROJID))
|
||||
goto out;
|
||||
|
||||
fsx.fsx_xflags &= ~ZFS_PROJINHERIT_FL;
|
||||
fsx.fsx_xflags &= ~FS_XFLAG_PROJINHERIT;
|
||||
if (!zpc->zpc_keep_projid)
|
||||
fsx.fsx_projid = ZFS_DEFAULT_PROJID;
|
||||
break;
|
||||
case ZFS_PROJECT_OP_SET:
|
||||
if (fsx.fsx_projid == zpc->zpc_expected_projid &&
|
||||
(!zpc->zpc_set_flag || fsx.fsx_xflags & ZFS_PROJINHERIT_FL))
|
||||
(!zpc->zpc_set_flag ||
|
||||
fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
|
||||
goto out;
|
||||
|
||||
fsx.fsx_projid = zpc->zpc_expected_projid;
|
||||
if (zpc->zpc_set_flag)
|
||||
fsx.fsx_xflags |= ZFS_PROJINHERIT_FL;
|
||||
fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
@@ -194,11 +195,30 @@ zfs_project_handle_one(const char *name, zfs_project_control_t *zpc)
|
||||
}
|
||||
|
||||
ret = ioctl(fd, ZFS_IOC_FSSETXATTR, &fsx);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("failed to set xattr for %s: %s\n"),
|
||||
name, strerror(errno));
|
||||
|
||||
if (errno == ENOTSUP) {
|
||||
char *kver = zfs_version_kernel();
|
||||
/*
|
||||
* Special case: a module/userspace version mismatch can
|
||||
* return ENOTSUP due to us fixing the XFLAGs bits in
|
||||
* #17884. In that case give a hint to the user that
|
||||
* they should take action to make the versions match.
|
||||
*/
|
||||
if (strcmp(kver, ZFS_META_ALIAS) != 0) {
|
||||
fprintf(stderr,
|
||||
gettext("Warning: The zfs module version "
|
||||
"(%s) and userspace\nversion (%s) do not "
|
||||
"match up. This may be the\ncause of the "
|
||||
"\"Operation not supported\" error.\n"),
|
||||
kver, ZFS_META_ALIAS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return (ret);
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <zfeature_common.h>
|
||||
#include <libzutil.h>
|
||||
#include <sys/metaslab_impl.h>
|
||||
#include <libzpool.h>
|
||||
|
||||
static importargs_t g_importargs;
|
||||
static char *g_pool;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -195,7 +195,7 @@ is_shorthand_path(const char *arg, char *path, size_t path_size,
|
||||
return (0);
|
||||
}
|
||||
|
||||
strlcpy(path, arg, path_size);
|
||||
(void) strlcpy(path, arg, path_size);
|
||||
memset(statbuf, 0, sizeof (*statbuf));
|
||||
*wholedisk = B_FALSE;
|
||||
|
||||
@@ -308,7 +308,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
|
||||
}
|
||||
|
||||
/* After whole disk check restore original passed path */
|
||||
strlcpy(path, arg, sizeof (path));
|
||||
(void) strlcpy(path, arg, sizeof (path));
|
||||
} else if (zpool_is_draid_spare(arg)) {
|
||||
if (!is_primary) {
|
||||
(void) fprintf(stderr,
|
||||
@@ -318,7 +318,7 @@ make_leaf_vdev(const char *arg, boolean_t is_primary, uint64_t ashift)
|
||||
}
|
||||
|
||||
wholedisk = B_TRUE;
|
||||
strlcpy(path, arg, sizeof (path));
|
||||
(void) strlcpy(path, arg, sizeof (path));
|
||||
type = VDEV_TYPE_DRAID_SPARE;
|
||||
} else {
|
||||
err = is_shorthand_path(arg, path, sizeof (path),
|
||||
@@ -1010,7 +1010,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv, boolean_t replacing)
|
||||
* window between when udev deletes and recreates the link
|
||||
* during which access attempts will fail with ENOENT.
|
||||
*/
|
||||
strlcpy(udevpath, path, MAXPATHLEN);
|
||||
(void) strlcpy(udevpath, path, MAXPATHLEN);
|
||||
(void) zfs_append_partition(udevpath, MAXPATHLEN);
|
||||
|
||||
fd = open(devpath, O_RDWR|O_EXCL);
|
||||
|
||||
@@ -191,9 +191,9 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
|
||||
#ifdef _ILP32
|
||||
uint64_t max_rde_size = SMALLEST_POSSIBLE_MAX_RDT_MB << 20;
|
||||
#else
|
||||
uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
uint64_t physbytes = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
|
||||
uint64_t max_rde_size =
|
||||
MAX((physmem * MAX_RDT_PHYSMEM_PERCENT) / 100,
|
||||
MAX((physbytes * MAX_RDT_PHYSMEM_PERCENT) / 100,
|
||||
SMALLEST_POSSIBLE_MAX_RDT_MB << 20);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -139,9 +139,10 @@
|
||||
#include <sys/crypto/icp.h>
|
||||
#include <sys/zfs_impl.h>
|
||||
#include <sys/backtrace.h>
|
||||
#include <libzpool.h>
|
||||
#include <libspl.h>
|
||||
|
||||
static int ztest_fd_data = -1;
|
||||
static int ztest_fd_rand = -1;
|
||||
|
||||
typedef struct ztest_shared_hdr {
|
||||
uint64_t zh_hdr_size;
|
||||
@@ -902,13 +903,10 @@ ztest_random(uint64_t range)
|
||||
{
|
||||
uint64_t r;
|
||||
|
||||
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||
|
||||
if (range == 0)
|
||||
return (0);
|
||||
|
||||
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
|
||||
fatal(B_TRUE, "short read from /dev/urandom");
|
||||
random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
|
||||
|
||||
return (r % range);
|
||||
}
|
||||
@@ -1228,10 +1226,10 @@ ztest_kill(ztest_shared_t *zs)
|
||||
* See comment above spa_write_cachefile().
|
||||
*/
|
||||
if (raidz_expand_pause_point != RAIDZ_EXPAND_PAUSE_NONE) {
|
||||
if (mutex_tryenter(&spa_namespace_lock)) {
|
||||
if (spa_namespace_tryenter(FTAG)) {
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE,
|
||||
B_FALSE);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
ztest_scratch_state->zs_raidz_scratch_verify_pause =
|
||||
raidz_expand_pause_point;
|
||||
@@ -1246,9 +1244,9 @@ ztest_kill(ztest_shared_t *zs)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa_write_cachefile(ztest_spa, B_FALSE, B_FALSE, B_FALSE);
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
(void) raise(SIGKILL);
|
||||
@@ -2306,7 +2304,8 @@ ztest_replay_write(void *arg1, void *arg2, boolean_t byteswap)
|
||||
}
|
||||
|
||||
if (abuf == NULL) {
|
||||
dmu_write(os, lr->lr_foid, offset, length, data, tx);
|
||||
dmu_write(os, lr->lr_foid, offset, length, data, tx,
|
||||
DMU_READ_PREFETCH);
|
||||
} else {
|
||||
memcpy(abuf->b_data, data, length);
|
||||
VERIFY0(dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx, 0));
|
||||
@@ -3688,10 +3687,10 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
|
||||
|
||||
if (error == 0) {
|
||||
(void) printf("successful split - results:\n");
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
show_pool_stats(spa);
|
||||
show_pool_stats(spa_lookup("splitp"));
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
++zs->zs_splits;
|
||||
--zs->zs_mirrors;
|
||||
}
|
||||
@@ -3975,11 +3974,11 @@ raidz_scratch_verify(void)
|
||||
|
||||
kernel_init(SPA_MODE_READ);
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
spa = spa_lookup(ztest_opts.zo_pool);
|
||||
ASSERT(spa);
|
||||
spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
|
||||
|
||||
@@ -5243,7 +5242,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
|
||||
* We've verified all the old bufwads, and made new ones.
|
||||
* Now write them out.
|
||||
*/
|
||||
dmu_write(os, packobj, packoff, packsize, packbuf, tx);
|
||||
dmu_write(os, packobj, packoff, packsize, packbuf, tx,
|
||||
DMU_READ_PREFETCH);
|
||||
|
||||
if (freeit) {
|
||||
if (ztest_opts.zo_verbose >= 7) {
|
||||
@@ -5258,7 +5258,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
|
||||
" txg %"PRIx64"\n",
|
||||
bigoff, bigsize, txg);
|
||||
}
|
||||
dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx);
|
||||
dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx,
|
||||
DMU_READ_PREFETCH);
|
||||
}
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
@@ -5513,7 +5514,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
|
||||
* We've verified all the old bufwads, and made new ones.
|
||||
* Now write them out.
|
||||
*/
|
||||
dmu_write(os, packobj, packoff, packsize, packbuf, tx);
|
||||
dmu_write(os, packobj, packoff, packsize, packbuf, tx,
|
||||
DMU_READ_PREFETCH);
|
||||
if (ztest_opts.zo_verbose >= 7) {
|
||||
(void) printf("writing offset %"PRIx64" size %"PRIx64""
|
||||
" txg %"PRIx64"\n",
|
||||
@@ -6119,7 +6121,8 @@ ztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
|
||||
"future leak: got %"PRIu64", open txg is %"PRIu64"",
|
||||
old_txg, txg);
|
||||
|
||||
dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx);
|
||||
dmu_write(os, od->od_object, 0, sizeof (uint64_t), &txg, tx,
|
||||
DMU_READ_PREFETCH);
|
||||
|
||||
(void) mutex_enter(&zcl.zcl_callbacks_lock);
|
||||
|
||||
@@ -7422,11 +7425,11 @@ ztest_walk_pool_directory(const char *header)
|
||||
if (ztest_opts.zo_verbose >= 6)
|
||||
(void) puts(header);
|
||||
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
while ((spa = spa_next(spa)) != NULL)
|
||||
if (ztest_opts.zo_verbose >= 6)
|
||||
(void) printf("\t%s\n", spa_name(spa));
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8140,10 +8143,8 @@ ztest_raidz_expand_run(ztest_shared_t *zs, spa_t *spa)
|
||||
/* Setup a 1 MiB buffer of random data */
|
||||
uint64_t bufsize = 1024 * 1024;
|
||||
void *buffer = umem_alloc(bufsize, UMEM_NOFAIL);
|
||||
random_get_pseudo_bytes((uint8_t *)&buffer, bufsize);
|
||||
|
||||
if (read(ztest_fd_rand, buffer, bufsize) != bufsize) {
|
||||
fatal(B_TRUE, "short read from /dev/urandom");
|
||||
}
|
||||
/*
|
||||
* Put some data in the pool and then attach a vdev to initiate
|
||||
* reflow.
|
||||
@@ -8541,11 +8542,11 @@ ztest_run(ztest_shared_t *zs)
|
||||
/*
|
||||
* Verify that we can loop over all pools.
|
||||
*/
|
||||
mutex_enter(&spa_namespace_lock);
|
||||
spa_namespace_enter(FTAG);
|
||||
for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
|
||||
if (ztest_opts.zo_verbose > 3)
|
||||
(void) printf("spa_next: found %s\n", spa_name(spa));
|
||||
mutex_exit(&spa_namespace_lock);
|
||||
spa_namespace_exit(FTAG);
|
||||
|
||||
/*
|
||||
* Verify that we can export the pool and reimport it under a
|
||||
@@ -8949,13 +8950,13 @@ main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
libspl_init();
|
||||
|
||||
/*
|
||||
* Force random_get_bytes() to use /dev/urandom in order to prevent
|
||||
* ztest from needlessly depleting the system entropy pool.
|
||||
*/
|
||||
random_path = "/dev/urandom";
|
||||
ztest_fd_rand = open(random_path, O_RDONLY | O_CLOEXEC);
|
||||
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||
random_force_pseudo(B_TRUE);
|
||||
|
||||
if (!fd_data_str) {
|
||||
process_options(argc, argv);
|
||||
|
||||
@@ -8,9 +8,9 @@ AM_CPPFLAGS = \
|
||||
-include $(top_builddir)/zfs_config.h \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/module/icp/include \
|
||||
-I$(top_srcdir)/lib/libspl/include \
|
||||
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@
|
||||
-I$(top_srcdir)/lib/libspl/include/os/@ac_system_l@ \
|
||||
-I$(top_srcdir)/lib/libzpool/include
|
||||
|
||||
AM_LIBTOOLFLAGS = --silent
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@ deb-utils: deb-local rpm-utils-initramfs
|
||||
pkg1=$${name}-$${version}.$${arch}.rpm; \
|
||||
pkg2=libnvpair3-$${version}.$${arch}.rpm; \
|
||||
pkg3=libuutil3-$${version}.$${arch}.rpm; \
|
||||
pkg4=libzfs6-$${version}.$${arch}.rpm; \
|
||||
pkg5=libzpool6-$${version}.$${arch}.rpm; \
|
||||
pkg6=libzfs6-devel-$${version}.$${arch}.rpm; \
|
||||
pkg4=libzfs7-$${version}.$${arch}.rpm; \
|
||||
pkg5=libzpool7-$${version}.$${arch}.rpm; \
|
||||
pkg6=libzfs7-devel-$${version}.$${arch}.rpm; \
|
||||
pkg7=$${name}-test-$${version}.$${arch}.rpm; \
|
||||
pkg8=$${name}-dracut-$${version}.noarch.rpm; \
|
||||
pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
|
||||
@@ -72,7 +72,7 @@ deb-utils: deb-local rpm-utils-initramfs
|
||||
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
|
||||
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
|
||||
echo "`which dh_shlibdeps` -- \
|
||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs6linux -xlibzpool6linux" \
|
||||
-xlibuutil3linux -xlibnvpair3linux -xlibzfs7linux -xlibzpool7linux" \
|
||||
>> $${path_prepend}/dh_shlibdeps; \
|
||||
## These -x arguments are passed to dpkg-shlibdeps, which exclude the
|
||||
## Debianized packages from the auto-generated dependencies of the new debs,
|
||||
|
||||
@@ -12,14 +12,14 @@ dist_noinst_DATA += %D%/openzfs-libpam-zfs.postinst
|
||||
dist_noinst_DATA += %D%/openzfs-libpam-zfs.prerm
|
||||
dist_noinst_DATA += %D%/openzfs-libuutil3.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libuutil3.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs6.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs6.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs7.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs7.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfsbootenv1.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs-dev.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzfs-dev.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool6.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool6.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool7.docs
|
||||
dist_noinst_DATA += %D%/openzfs-libzpool7.install.in
|
||||
dist_noinst_DATA += %D%/openzfs-python3-pyzfs.install
|
||||
dist_noinst_DATA += %D%/openzfs-zfs-dkms.config
|
||||
dist_noinst_DATA += %D%/openzfs-zfs-dkms.dkms
|
||||
|
||||
@@ -6,6 +6,6 @@ contrib/pyzfs/libzfs_core/bindings/__pycache__/
|
||||
contrib/pyzfs/pyzfs.egg-info/
|
||||
debian/openzfs-libnvpair3.install
|
||||
debian/openzfs-libuutil3.install
|
||||
debian/openzfs-libzfs6.install
|
||||
debian/openzfs-libzfs7.install
|
||||
debian/openzfs-libzfs-dev.install
|
||||
debian/openzfs-libzpool6.install
|
||||
debian/openzfs-libzpool7.install
|
||||
|
||||
@@ -79,9 +79,9 @@ Architecture: linux-any
|
||||
Depends: libssl-dev | libssl1.0-dev,
|
||||
openzfs-libnvpair3 (= ${binary:Version}),
|
||||
openzfs-libuutil3 (= ${binary:Version}),
|
||||
openzfs-libzfs6 (= ${binary:Version}),
|
||||
openzfs-libzfs7 (= ${binary:Version}),
|
||||
openzfs-libzfsbootenv1 (= ${binary:Version}),
|
||||
openzfs-libzpool6 (= ${binary:Version}),
|
||||
openzfs-libzpool7 (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Replaces: libzfslinux-dev
|
||||
Conflicts: libzfslinux-dev
|
||||
@@ -91,18 +91,18 @@ Description: OpenZFS filesystem development files for Linux
|
||||
libraries of OpenZFS filesystem.
|
||||
.
|
||||
This package includes the development files of libnvpair3, libuutil3,
|
||||
libzpool6 and libzfs6.
|
||||
libzpool7 and libzfs7.
|
||||
|
||||
Package: openzfs-libzfs6
|
||||
Package: openzfs-libzfs7
|
||||
Section: contrib/libs
|
||||
Architecture: linux-any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
# The libcurl4 is loaded through dlopen("libcurl.so.4").
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988521
|
||||
Recommends: libcurl4
|
||||
Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4
|
||||
Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, openzfs-libzfs4
|
||||
Conflicts: libzfs6linux
|
||||
Breaks: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6
|
||||
Replaces: libzfs2, libzfs4, libzfs4linux, libzfs6linux, libzfs7linux, openzfs-libzfs4, openzfs-libzfs6
|
||||
Conflicts: libzfs7linux
|
||||
Description: OpenZFS filesystem library for Linux - general support
|
||||
OpenZFS is a storage platform that encompasses the functionality of
|
||||
traditional filesystems and volume managers. It supports data checksums,
|
||||
@@ -124,13 +124,13 @@ Description: OpenZFS filesystem library for Linux - label info support
|
||||
.
|
||||
The zfsbootenv library provides support for modifying ZFS label information.
|
||||
|
||||
Package: openzfs-libzpool6
|
||||
Package: openzfs-libzpool7
|
||||
Section: contrib/libs
|
||||
Architecture: linux-any
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Breaks: libzpool2, libzpool5, libzpool6linux
|
||||
Replaces: libzpool2, libzpool5, libzpool6linux
|
||||
Conflicts: libzpool6linux
|
||||
Breaks: libzpool2, libzpool5, libzpool6linux, libzpool7linux
|
||||
Replaces: libzpool2, libzpool5, libzpool6linux, libzpool7linux
|
||||
Conflicts: libzpool7linux
|
||||
Description: OpenZFS pool library for Linux
|
||||
OpenZFS is a storage platform that encompasses the functionality of
|
||||
traditional filesystems and volume managers. It supports data checksums,
|
||||
@@ -247,8 +247,8 @@ Architecture: linux-any
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Depends: openzfs-libnvpair3 (= ${binary:Version}),
|
||||
openzfs-libuutil3 (= ${binary:Version}),
|
||||
openzfs-libzfs6 (= ${binary:Version}),
|
||||
openzfs-libzpool6 (= ${binary:Version}),
|
||||
openzfs-libzfs7 (= ${binary:Version}),
|
||||
openzfs-libzpool7 (= ${binary:Version}),
|
||||
python3,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
|
||||
@@ -191,6 +191,7 @@ USER_H = \
|
||||
libzfs.h \
|
||||
libzfs_core.h \
|
||||
libzfsbootenv.h \
|
||||
libzpool.h \
|
||||
libzutil.h \
|
||||
thread_pool.h
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBZPOOL_H
|
||||
#define _LIBZPOOL_H extern __attribute__((visibility("default")))
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *vn_dumpdir;
|
||||
|
||||
_LIBZPOOL_H void kernel_init(int mode);
|
||||
_LIBZPOOL_H void kernel_fini(void);
|
||||
|
||||
struct spa;
|
||||
_LIBZPOOL_H void show_pool_stats(struct spa *);
|
||||
_LIBZPOOL_H int handle_tunable_option(const char *, boolean_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -165,6 +165,7 @@ _LIBZUTIL_H void zfs_nicetime(uint64_t, char *, size_t);
|
||||
_LIBZUTIL_H void zfs_niceraw(uint64_t, char *, size_t);
|
||||
|
||||
#define nicenum(num, buf, size) zfs_nicenum(num, buf, size)
|
||||
#define NN_NUMBUF_SZ (6)
|
||||
|
||||
_LIBZUTIL_H void zpool_dump_ddt(const ddt_stat_t *, const ddt_histogram_t *);
|
||||
_LIBZUTIL_H int zpool_history_unpack(char *, uint64_t, uint64_t *, nvlist_t ***,
|
||||
|
||||
@@ -44,7 +44,6 @@ noinst_HEADERS = \
|
||||
%D%/spl/sys/procfs_list.h \
|
||||
%D%/spl/sys/random.h \
|
||||
%D%/spl/sys/rwlock.h \
|
||||
%D%/spl/sys/sdt.h \
|
||||
%D%/spl/sys/sid.h \
|
||||
%D%/spl/sys/sig.h \
|
||||
%D%/spl/sys/simd.h \
|
||||
@@ -63,7 +62,6 @@ noinst_HEADERS = \
|
||||
%D%/spl/sys/time.h \
|
||||
%D%/spl/sys/timer.h \
|
||||
%D%/spl/sys/trace.h \
|
||||
%D%/spl/sys/trace_zfs.h \
|
||||
%D%/spl/sys/types.h \
|
||||
%D%/spl/sys/types32.h \
|
||||
%D%/spl/sys/uio.h \
|
||||
@@ -82,10 +80,12 @@ noinst_HEADERS = \
|
||||
%D%/zfs/sys/arc_os.h \
|
||||
%D%/zfs/sys/freebsd_crypto.h \
|
||||
%D%/zfs/sys/freebsd_event.h \
|
||||
%D%/zfs/sys/trace_zfs.h \
|
||||
%D%/zfs/sys/vdev_os.h \
|
||||
%D%/zfs/sys/zfs_bootenv_os.h \
|
||||
%D%/zfs/sys/zfs_context_os.h \
|
||||
%D%/zfs/sys/zfs_ctldir.h \
|
||||
%D%/zfs/sys/zfs_debug_os.h \
|
||||
%D%/zfs/sys/zfs_dir.h \
|
||||
%D%/zfs/sys/zfs_ioctl_compat.h \
|
||||
%D%/zfs/sys/zfs_vfsops_os.h \
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
#define spa_taskq_write_param_set_args(var) \
|
||||
CTLTYPE_STRING, NULL, 0, spa_taskq_write_param, "A"
|
||||
|
||||
#define spa_taskq_free_param_set_args(var) \
|
||||
CTLTYPE_STRING, NULL, 0, spa_taskq_free_param, "A"
|
||||
|
||||
#define fletcher_4_param_set_args(var) \
|
||||
CTLTYPE_STRING, NULL, 0, fletcher_4_param, "A"
|
||||
|
||||
|
||||
+5
-4
@@ -27,10 +27,11 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _OPENSOLARIS_SYS_SDT_H_
|
||||
#define _OPENSOLARIS_SYS_SDT_H_
|
||||
#ifndef _SYS_ZFS_DEBUG_OS_H
|
||||
#define _SYS_ZFS_DEBUG_OS_H
|
||||
|
||||
#include <sys/sdt.h>
|
||||
|
||||
#include_next <sys/sdt.h>
|
||||
#ifdef KDTRACE_HOOKS
|
||||
SDT_PROBE_DECLARE(sdt, , , set__error);
|
||||
|
||||
@@ -44,4 +45,4 @@ SDT_PROBE_DECLARE(sdt, , , set__error);
|
||||
#define SET_ERROR(err) (err)
|
||||
#endif
|
||||
|
||||
#endif /* _OPENSOLARIS_SYS_SDT_H_ */
|
||||
#endif /* _SYS_ZFS_DEBUG_OS_H */
|
||||
@@ -41,6 +41,7 @@ kernel_sys_HEADERS = \
|
||||
%D%/zfs/sys/zfs_bootenv_os.h \
|
||||
%D%/zfs/sys/zfs_context_os.h \
|
||||
%D%/zfs/sys/zfs_ctldir.h \
|
||||
%D%/zfs/sys/zfs_debug_os.h \
|
||||
%D%/zfs/sys/zfs_dir.h \
|
||||
%D%/zfs/sys/zfs_vfsops_os.h \
|
||||
%D%/zfs/sys/zfs_vnops_os.h \
|
||||
@@ -97,7 +98,6 @@ kernel_spl_sys_HEADERS = \
|
||||
%D%/spl/sys/time.h \
|
||||
%D%/spl/sys/timer.h \
|
||||
%D%/spl/sys/trace.h \
|
||||
%D%/spl/sys/trace_spl.h \
|
||||
%D%/spl/sys/trace_taskq.h \
|
||||
%D%/spl/sys/tsd.h \
|
||||
%D%/spl/sys/types.h \
|
||||
|
||||
@@ -34,11 +34,6 @@
|
||||
#include <sys/signal.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
|
||||
#ifndef _KERNEL
|
||||
#define _KERNEL __KERNEL__
|
||||
#endif
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
@@ -202,9 +197,6 @@ makedev(unsigned int major, unsigned int minor)
|
||||
#define P2SAMEHIGHBIT_TYPED(x, y, type) \
|
||||
(((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y)))
|
||||
|
||||
#define SET_ERROR(err) \
|
||||
(__set_error(__FILE__, __func__, __LINE__, err), err)
|
||||
|
||||
#include <linux/sort.h>
|
||||
#define qsort(base, num, size, cmp) \
|
||||
sort(base, num, size, cmp, NULL)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZFS_DEBUG_OS_H
|
||||
#define _SYS_ZFS_DEBUG_OS_H
|
||||
|
||||
#define SET_ERROR(err) \
|
||||
(__set_error(__FILE__, __func__, __LINE__, err), err)
|
||||
|
||||
#endif /* _SYS_ZFS_DEBUG_OS_H */
|
||||
@@ -56,6 +56,7 @@ extern void brt_create(spa_t *spa);
|
||||
extern int brt_load(spa_t *spa);
|
||||
extern void brt_unload(spa_t *spa);
|
||||
extern void brt_sync(spa_t *spa, uint64_t txg);
|
||||
extern void brt_prefetch_all(spa_t *spa);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ _Static_assert(BRT_RANGESIZE / SPA_MINBLOCKSIZE <= UINT16_MAX,
|
||||
*/
|
||||
#define BRT_BLOCKSIZE (32 * 1024)
|
||||
#define BRT_RANGESIZE_TO_NBLOCKS(size) \
|
||||
(((size) - 1) / BRT_BLOCKSIZE / sizeof (uint16_t) + 1)
|
||||
(((size) - 1) / (BRT_BLOCKSIZE / sizeof (uint16_t)) + 1)
|
||||
|
||||
#define BRT_LITTLE_ENDIAN 0
|
||||
#define BRT_BIG_ENDIAN 1
|
||||
|
||||
@@ -38,6 +38,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
/* Cryptographic Mechanisms */
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ typedef enum dmu_object_byteswap {
|
||||
(ot) < DMU_OT_NUMTYPES)
|
||||
|
||||
#define DMU_OT_IS_METADATA_CACHED(ot) (((ot) & DMU_OT_NEWTYPE) ? \
|
||||
B_TRUE : dmu_ot[(ot)].ot_dbuf_metadata_cache)
|
||||
((ot) & DMU_OT_METADATA) != 0 : dmu_ot[(ot)].ot_dbuf_metadata_cache)
|
||||
|
||||
/*
|
||||
* MDB doesn't have dmu_ot; it defines these macros itself.
|
||||
@@ -625,7 +625,7 @@ int dmu_buf_hold(objset_t *os, uint64_t object, uint64_t offset,
|
||||
const void *tag, dmu_buf_t **, dmu_flags_t flags);
|
||||
int dmu_buf_hold_array(objset_t *os, uint64_t object, uint64_t offset,
|
||||
uint64_t length, int read, const void *tag, int *numbufsp,
|
||||
dmu_buf_t ***dbpp);
|
||||
dmu_buf_t ***dbpp, dmu_flags_t flags);
|
||||
int dmu_buf_hold_noread(objset_t *os, uint64_t object, uint64_t offset,
|
||||
const void *tag, dmu_buf_t **dbp);
|
||||
int dmu_buf_hold_by_dnode(dnode_t *dn, uint64_t offset,
|
||||
@@ -668,7 +668,7 @@ uint64_t dmu_buf_user_refcount(dmu_buf_t *db);
|
||||
*/
|
||||
int dmu_buf_hold_array_by_bonus(dmu_buf_t *db, uint64_t offset,
|
||||
uint64_t length, boolean_t read, const void *tag,
|
||||
int *numbufsp, dmu_buf_t ***dbpp);
|
||||
int *numbufsp, dmu_buf_t ***dbpp, dmu_flags_t flags);
|
||||
void dmu_buf_rele_array(dmu_buf_t **, int numbufs, const void *tag);
|
||||
|
||||
typedef void dmu_buf_evict_func_t(void *user_ptr);
|
||||
@@ -924,7 +924,7 @@ int dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||
int dmu_read_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size, void *buf,
|
||||
dmu_flags_t flags);
|
||||
void dmu_write(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||
const void *buf, dmu_tx_t *tx);
|
||||
const void *buf, dmu_tx_t *tx, dmu_flags_t flags);
|
||||
int dmu_write_by_dnode(dnode_t *dn, uint64_t offset, uint64_t size,
|
||||
const void *buf, dmu_tx_t *tx, dmu_flags_t flags);
|
||||
void dmu_prealloc(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
|
||||
|
||||
@@ -387,6 +387,7 @@ typedef enum {
|
||||
VDEV_PROP_SLOW_IOS,
|
||||
VDEV_PROP_SIT_OUT,
|
||||
VDEV_PROP_AUTOSIT,
|
||||
VDEV_PROP_SLOW_IO_EVENTS,
|
||||
VDEV_NUM_PROPS
|
||||
} vdev_prop_t;
|
||||
|
||||
@@ -1713,7 +1714,8 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
ZPOOL_PREFETCH_NONE = 0,
|
||||
ZPOOL_PREFETCH_DDT
|
||||
ZPOOL_PREFETCH_DDT,
|
||||
ZPOOL_PREFETCH_BRT
|
||||
} zpool_prefetch_type_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* Copyright 2017 Joyent, Inc.
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
* Copyright (c) 2019, Allan Jude
|
||||
* Copyright (c) 2019, Klara Inc.
|
||||
* Copyright (c) 2019, 2025, Klara, Inc.
|
||||
* Copyright (c) 2019, Datto Inc.
|
||||
*/
|
||||
|
||||
@@ -867,10 +867,14 @@ uint_t spa_acq_allocator(spa_t *spa);
|
||||
void spa_rel_allocator(spa_t *spa, uint_t allocator);
|
||||
void spa_select_allocator(zio_t *zio);
|
||||
|
||||
/* spa namespace global mutex */
|
||||
extern kmutex_t spa_namespace_lock;
|
||||
extern avl_tree_t spa_namespace_avl;
|
||||
extern kcondvar_t spa_namespace_cv;
|
||||
/* spa namespace global lock */
|
||||
extern void spa_namespace_enter(const void *tag);
|
||||
extern boolean_t spa_namespace_tryenter(const void *tag);
|
||||
extern int spa_namespace_enter_interruptible(const void *tag);
|
||||
extern void spa_namespace_exit(const void *tag);
|
||||
extern boolean_t spa_namespace_held(void);
|
||||
extern void spa_namespace_wait(void);
|
||||
extern void spa_namespace_broadcast(void);
|
||||
|
||||
/*
|
||||
* SPA configuration functions in spa_config.c
|
||||
|
||||
@@ -470,6 +470,7 @@ struct vdev {
|
||||
uint64_t vdev_checksum_t;
|
||||
uint64_t vdev_io_n;
|
||||
uint64_t vdev_io_t;
|
||||
boolean_t vdev_slow_io_events;
|
||||
uint64_t vdev_slow_io_n;
|
||||
uint64_t vdev_slow_io_t;
|
||||
};
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#ifdef _KERNEL
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/types32.h>
|
||||
#include <sys/xvattr.h>
|
||||
#endif
|
||||
#include <sys/xvattr.h>
|
||||
#include <sys/acl.h>
|
||||
#include <sys/dmu.h>
|
||||
#include <sys/zfs_fuid.h>
|
||||
|
||||
@@ -31,6 +31,7 @@ extern "C" {
|
||||
#define BE_FREEBSD_VENDOR "freebsd"
|
||||
#define BE_GRUB_VENDOR "grub"
|
||||
#define BE_LINUX_VENDOR "linux"
|
||||
#define BE_POSIX_VENDOR "posix"
|
||||
|
||||
#include <sys/zfs_bootenv_os.h>
|
||||
|
||||
|
||||
@@ -77,14 +77,6 @@ extern "C" {
|
||||
#include <sys/zfs_context_os.h>
|
||||
#else /* _KERNEL || _STANDALONE */
|
||||
|
||||
#define _SYS_MUTEX_H
|
||||
#define _SYS_RWLOCK_H
|
||||
#define _SYS_CONDVAR_H
|
||||
#define _SYS_VNODE_H
|
||||
#define _SYS_VFS_H
|
||||
#define _SYS_SUNDDI_H
|
||||
#define _SYS_CALLB_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -93,10 +85,8 @@ extern "C" {
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <setjmp.h>
|
||||
#include <assert.h>
|
||||
#include <umem.h>
|
||||
#include <limits.h>
|
||||
#include <atomic.h>
|
||||
#include <dirent.h>
|
||||
@@ -119,667 +109,27 @@ extern "C" {
|
||||
#include <sys/sysevent/eventdefs.h>
|
||||
#include <sys/sunddi.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/trace_zfs.h>
|
||||
#include <sys/zone.h>
|
||||
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/cmn_err.h>
|
||||
#include <sys/thread.h>
|
||||
#include <sys/taskq.h>
|
||||
#include <sys/tsd.h>
|
||||
#include <sys/procfs_list.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/zfs_delay.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/callb.h>
|
||||
#include <sys/trace.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/misc.h>
|
||||
#include <sys/random.h>
|
||||
|
||||
#include <sys/zfs_context_os.h>
|
||||
|
||||
/*
|
||||
* Stack
|
||||
*/
|
||||
|
||||
#define noinline __attribute__((noinline))
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
#define unlikely(x) __builtin_expect((x), 0)
|
||||
|
||||
/*
|
||||
* Debugging
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note that we are not using the debugging levels.
|
||||
*/
|
||||
|
||||
#define CE_CONT 0 /* continuation */
|
||||
#define CE_NOTE 1 /* notice */
|
||||
#define CE_WARN 2 /* warning */
|
||||
#define CE_PANIC 3 /* panic */
|
||||
#define CE_IGNORE 4 /* print nothing */
|
||||
|
||||
/*
|
||||
* ZFS debugging
|
||||
*/
|
||||
|
||||
extern void dprintf_setup(int *argc, char **argv);
|
||||
|
||||
extern void cmn_err(int, const char *, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
extern void vcmn_err(int, const char *, va_list)
|
||||
__attribute__((format(printf, 2, 0)));
|
||||
extern void panic(const char *, ...)
|
||||
__attribute__((format(printf, 1, 2), noreturn));
|
||||
extern void vpanic(const char *, va_list)
|
||||
__attribute__((format(printf, 1, 0), noreturn));
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
/*
|
||||
* DTrace SDT probes have different signatures in userland than they do in
|
||||
* the kernel. If they're being used in kernel code, re-define them out of
|
||||
* existence for their counterparts in libzpool.
|
||||
*
|
||||
* Here's an example of how to use the set-error probes in userland:
|
||||
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
|
||||
*
|
||||
* Here's an example of how to use DTRACE_PROBE probes in userland:
|
||||
* If there is a probe declared as follows:
|
||||
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
|
||||
* Then you can use it as follows:
|
||||
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
|
||||
* {printf("%u %p\n", arg1, arg2);}
|
||||
*/
|
||||
|
||||
#ifdef DTRACE_PROBE
|
||||
#undef DTRACE_PROBE
|
||||
#endif /* DTRACE_PROBE */
|
||||
#define DTRACE_PROBE(a)
|
||||
|
||||
#ifdef DTRACE_PROBE1
|
||||
#undef DTRACE_PROBE1
|
||||
#endif /* DTRACE_PROBE1 */
|
||||
#define DTRACE_PROBE1(a, b, c)
|
||||
|
||||
#ifdef DTRACE_PROBE2
|
||||
#undef DTRACE_PROBE2
|
||||
#endif /* DTRACE_PROBE2 */
|
||||
#define DTRACE_PROBE2(a, b, c, d, e)
|
||||
|
||||
#ifdef DTRACE_PROBE3
|
||||
#undef DTRACE_PROBE3
|
||||
#endif /* DTRACE_PROBE3 */
|
||||
#define DTRACE_PROBE3(a, b, c, d, e, f, g)
|
||||
|
||||
#ifdef DTRACE_PROBE4
|
||||
#undef DTRACE_PROBE4
|
||||
#endif /* DTRACE_PROBE4 */
|
||||
#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)
|
||||
|
||||
/*
|
||||
* Threads.
|
||||
*/
|
||||
typedef pthread_t kthread_t;
|
||||
|
||||
#define TS_RUN 0x00000002
|
||||
#define TS_JOINABLE 0x00000004
|
||||
|
||||
#define curthread ((void *)(uintptr_t)pthread_self())
|
||||
#define getcomm() "unknown"
|
||||
|
||||
#define thread_create_named(name, stk, stksize, func, arg, len, \
|
||||
pp, state, pri) \
|
||||
zk_thread_create(name, func, arg, stksize, state)
|
||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||
zk_thread_create(#func, func, arg, stksize, state)
|
||||
#define thread_exit() pthread_exit(NULL)
|
||||
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
||||
|
||||
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
|
||||
/*
|
||||
* Check if the current thread is a memory reclaim thread.
|
||||
* Always returns false in userspace (no memory reclaim thread).
|
||||
*/
|
||||
#define current_is_reclaim_thread() (0)
|
||||
|
||||
/* in libzpool, p0 exists only to have its address taken */
|
||||
typedef struct proc {
|
||||
uintptr_t this_is_never_used_dont_dereference_it;
|
||||
} proc_t;
|
||||
|
||||
extern struct proc p0;
|
||||
#define curproc (&p0)
|
||||
|
||||
#define PS_NONE -1
|
||||
|
||||
extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
|
||||
void *arg, size_t stksize, int state);
|
||||
|
||||
#define issig() (FALSE)
|
||||
|
||||
#define KPREEMPT_SYNC (-1)
|
||||
|
||||
#define kpreempt(x) sched_yield()
|
||||
#define kpreempt_disable() ((void)0)
|
||||
#define kpreempt_enable() ((void)0)
|
||||
|
||||
/*
|
||||
* Mutexes
|
||||
*/
|
||||
typedef struct kmutex {
|
||||
pthread_mutex_t m_lock;
|
||||
pthread_t m_owner;
|
||||
} kmutex_t;
|
||||
|
||||
#define MUTEX_DEFAULT 0
|
||||
#define MUTEX_NOLOCKDEP MUTEX_DEFAULT
|
||||
#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self())
|
||||
#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp)
|
||||
|
||||
extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
|
||||
extern void mutex_destroy(kmutex_t *mp);
|
||||
extern void mutex_enter(kmutex_t *mp);
|
||||
extern int mutex_enter_check_return(kmutex_t *mp);
|
||||
extern void mutex_exit(kmutex_t *mp);
|
||||
extern int mutex_tryenter(kmutex_t *mp);
|
||||
|
||||
#define NESTED_SINGLE 1
|
||||
#define mutex_enter_nested(mp, class) mutex_enter(mp)
|
||||
#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
|
||||
/*
|
||||
* RW locks
|
||||
*/
|
||||
typedef struct krwlock {
|
||||
pthread_rwlock_t rw_lock;
|
||||
pthread_t rw_owner;
|
||||
uint_t rw_readers;
|
||||
} krwlock_t;
|
||||
|
||||
typedef int krw_t;
|
||||
|
||||
#define RW_READER 0
|
||||
#define RW_WRITER 1
|
||||
#define RW_DEFAULT RW_READER
|
||||
#define RW_NOLOCKDEP RW_READER
|
||||
|
||||
#define RW_READ_HELD(rw) ((rw)->rw_readers > 0)
|
||||
#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self())
|
||||
#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw))
|
||||
|
||||
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
|
||||
extern void rw_destroy(krwlock_t *rwlp);
|
||||
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryupgrade(krwlock_t *rwlp);
|
||||
extern void rw_exit(krwlock_t *rwlp);
|
||||
#define rw_downgrade(rwlp) do { } while (0)
|
||||
|
||||
/*
|
||||
* Credentials
|
||||
*/
|
||||
extern uid_t crgetuid(cred_t *cr);
|
||||
extern uid_t crgetruid(cred_t *cr);
|
||||
extern gid_t crgetgid(cred_t *cr);
|
||||
extern int crgetngroups(cred_t *cr);
|
||||
extern gid_t *crgetgroups(cred_t *cr);
|
||||
|
||||
/*
|
||||
* Condition variables
|
||||
*/
|
||||
typedef pthread_cond_t kcondvar_t;
|
||||
|
||||
#define CV_DEFAULT 0
|
||||
#define CALLOUT_FLAG_ABSOLUTE 0x2
|
||||
|
||||
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
|
||||
extern void cv_destroy(kcondvar_t *cv);
|
||||
extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
|
||||
extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp);
|
||||
extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
|
||||
extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
|
||||
hrtime_t res, int flag);
|
||||
extern void cv_signal(kcondvar_t *cv);
|
||||
extern void cv_broadcast(kcondvar_t *cv);
|
||||
|
||||
#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
|
||||
#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
|
||||
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
|
||||
#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
|
||||
cv_timedwait_hires(cv, mp, t, r, f)
|
||||
#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
|
||||
cv_timedwait_hires(cv, mp, t, r, f)
|
||||
|
||||
/*
|
||||
* Thread-specific data
|
||||
*/
|
||||
#define tsd_get(k) pthread_getspecific(k)
|
||||
#define tsd_set(k, v) pthread_setspecific(k, v)
|
||||
#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d)
|
||||
#define tsd_destroy(kp) /* nothing */
|
||||
#ifdef __FreeBSD__
|
||||
typedef off_t loff_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* kstat creation, installation and deletion
|
||||
*/
|
||||
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_set_raw_ops(kstat_t *ksp,
|
||||
int (*headers)(char *buf, size_t size),
|
||||
int (*data)(char *buf, size_t size, void *data),
|
||||
void *(*addr)(kstat_t *ksp, loff_t index));
|
||||
|
||||
/*
|
||||
* procfs list manipulation
|
||||
*/
|
||||
|
||||
typedef struct procfs_list {
|
||||
void *pl_private;
|
||||
kmutex_t pl_lock;
|
||||
list_t pl_list;
|
||||
uint64_t pl_next_id;
|
||||
size_t pl_node_offset;
|
||||
} procfs_list_t;
|
||||
|
||||
#ifndef __cplusplus
|
||||
struct seq_file { };
|
||||
void seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
|
||||
typedef struct procfs_list_node {
|
||||
list_node_t pln_link;
|
||||
uint64_t pln_id;
|
||||
} procfs_list_node_t;
|
||||
|
||||
void procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
int (*show)(struct seq_file *f, void *p),
|
||||
int (*show_header)(struct seq_file *f),
|
||||
int (*clear)(procfs_list_t *procfs_list),
|
||||
size_t procfs_list_node_off);
|
||||
void procfs_list_uninstall(procfs_list_t *procfs_list);
|
||||
void procfs_list_destroy(procfs_list_t *procfs_list);
|
||||
void procfs_list_add(procfs_list_t *procfs_list, void *p);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Kernel memory
|
||||
*/
|
||||
#define KM_SLEEP UMEM_NOFAIL
|
||||
#define KM_PUSHPAGE KM_SLEEP
|
||||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define KMC_KVMEM 0x0
|
||||
#define KMC_RECLAIMABLE 0x0
|
||||
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
|
||||
#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
|
||||
#define kmem_free(_b, _s) umem_free(_b, _s)
|
||||
#define vmem_alloc(_s, _f) kmem_alloc(_s, _f)
|
||||
#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f)
|
||||
#define vmem_free(_b, _s) kmem_free(_b, _s)
|
||||
#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
|
||||
umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
|
||||
#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
|
||||
#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
|
||||
#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
|
||||
#define kmem_debugging() 0
|
||||
#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c);
|
||||
#define kmem_cache_set_move(_c, _cb) /* nothing */
|
||||
#define POINTER_INVALIDATE(_pp) /* nothing */
|
||||
#define POINTER_IS_VALID(_p) 0
|
||||
|
||||
typedef umem_cache_t kmem_cache_t;
|
||||
|
||||
typedef enum kmem_cbrc {
|
||||
KMEM_CBRC_YES,
|
||||
KMEM_CBRC_NO,
|
||||
KMEM_CBRC_LATER,
|
||||
KMEM_CBRC_DONT_NEED,
|
||||
KMEM_CBRC_DONT_KNOW
|
||||
} kmem_cbrc_t;
|
||||
|
||||
/*
|
||||
* Task queues
|
||||
*/
|
||||
|
||||
#define TASKQ_NAMELEN 31
|
||||
|
||||
typedef uintptr_t taskqid_t;
|
||||
typedef void (task_func_t)(void *);
|
||||
|
||||
typedef struct taskq_ent {
|
||||
struct taskq_ent *tqent_next;
|
||||
struct taskq_ent *tqent_prev;
|
||||
task_func_t *tqent_func;
|
||||
void *tqent_arg;
|
||||
uintptr_t tqent_flags;
|
||||
} taskq_ent_t;
|
||||
|
||||
typedef struct taskq {
|
||||
char tq_name[TASKQ_NAMELEN + 1];
|
||||
kmutex_t tq_lock;
|
||||
krwlock_t tq_threadlock;
|
||||
kcondvar_t tq_dispatch_cv;
|
||||
kcondvar_t tq_wait_cv;
|
||||
kthread_t **tq_threadlist;
|
||||
int tq_flags;
|
||||
int tq_active;
|
||||
int tq_nthreads;
|
||||
int tq_nalloc;
|
||||
int tq_minalloc;
|
||||
int tq_maxalloc;
|
||||
kcondvar_t tq_maxalloc_cv;
|
||||
int tq_maxalloc_wait;
|
||||
taskq_ent_t *tq_freelist;
|
||||
taskq_ent_t tq_task;
|
||||
} taskq_t;
|
||||
|
||||
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
|
||||
|
||||
#define TASKQ_PREPOPULATE 0x0001
|
||||
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
||||
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
||||
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
|
||||
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
|
||||
|
||||
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
|
||||
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
|
||||
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
||||
#define TQ_FRONT 0x08 /* Queue in front */
|
||||
|
||||
#define TASKQID_INVALID ((taskqid_t)0)
|
||||
|
||||
extern taskq_t *system_taskq;
|
||||
extern taskq_t *system_delay_taskq;
|
||||
|
||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
|
||||
kthread_t ***);
|
||||
#define taskq_create_proc(a, b, c, d, e, p, f) \
|
||||
(taskq_create(a, b, c, d, e, f))
|
||||
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
||||
((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
|
||||
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
||||
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
|
||||
clock_t);
|
||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||
taskq_ent_t *);
|
||||
extern int taskq_empty_ent(taskq_ent_t *);
|
||||
extern void taskq_init_ent(taskq_ent_t *);
|
||||
extern void taskq_destroy(taskq_t *);
|
||||
extern void taskq_wait(taskq_t *);
|
||||
extern void taskq_wait_id(taskq_t *, taskqid_t);
|
||||
extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
|
||||
extern int taskq_member(taskq_t *, kthread_t *);
|
||||
extern taskq_t *taskq_of_curthread(void);
|
||||
extern int taskq_cancel_id(taskq_t *, taskqid_t);
|
||||
extern void system_taskq_init(void);
|
||||
extern void system_taskq_fini(void);
|
||||
|
||||
#define XVA_MAPSIZE 3
|
||||
#define XVA_MAGIC 0x78766174
|
||||
|
||||
extern char *vn_dumpdir;
|
||||
#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */
|
||||
|
||||
typedef struct xoptattr {
|
||||
inode_timespec_t xoa_createtime; /* Create time of file */
|
||||
uint8_t xoa_archive;
|
||||
uint8_t xoa_system;
|
||||
uint8_t xoa_readonly;
|
||||
uint8_t xoa_hidden;
|
||||
uint8_t xoa_nounlink;
|
||||
uint8_t xoa_immutable;
|
||||
uint8_t xoa_appendonly;
|
||||
uint8_t xoa_nodump;
|
||||
uint8_t xoa_settable;
|
||||
uint8_t xoa_opaque;
|
||||
uint8_t xoa_av_quarantined;
|
||||
uint8_t xoa_av_modified;
|
||||
uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ];
|
||||
uint8_t xoa_reparse;
|
||||
uint8_t xoa_offline;
|
||||
uint8_t xoa_sparse;
|
||||
} xoptattr_t;
|
||||
|
||||
typedef struct vattr {
|
||||
uint_t va_mask; /* bit-mask of attributes */
|
||||
u_offset_t va_size; /* file size in bytes */
|
||||
} vattr_t;
|
||||
|
||||
|
||||
typedef struct xvattr {
|
||||
vattr_t xva_vattr; /* Embedded vattr structure */
|
||||
uint32_t xva_magic; /* Magic Number */
|
||||
uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
|
||||
uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
|
||||
uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
|
||||
uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
|
||||
xoptattr_t xva_xoptattrs; /* Optional attributes */
|
||||
} xvattr_t;
|
||||
|
||||
typedef struct vsecattr {
|
||||
uint_t vsa_mask; /* See below */
|
||||
int vsa_aclcnt; /* ACL entry count */
|
||||
void *vsa_aclentp; /* pointer to ACL entries */
|
||||
int vsa_dfaclcnt; /* default ACL entry count */
|
||||
void *vsa_dfaclentp; /* pointer to default ACL entries */
|
||||
size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
|
||||
} vsecattr_t;
|
||||
|
||||
#define AT_MODE 0x00002
|
||||
#define AT_UID 0x00004
|
||||
#define AT_GID 0x00008
|
||||
#define AT_FSID 0x00010
|
||||
#define AT_NODEID 0x00020
|
||||
#define AT_NLINK 0x00040
|
||||
#define AT_SIZE 0x00080
|
||||
#define AT_ATIME 0x00100
|
||||
#define AT_MTIME 0x00200
|
||||
#define AT_CTIME 0x00400
|
||||
#define AT_RDEV 0x00800
|
||||
#define AT_BLKSIZE 0x01000
|
||||
#define AT_NBLOCKS 0x02000
|
||||
#define AT_SEQ 0x08000
|
||||
#define AT_XVATTR 0x10000
|
||||
|
||||
#define CRCREAT 0
|
||||
|
||||
#define F_FREESP 11
|
||||
#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
|
||||
|
||||
/*
|
||||
* Random stuff
|
||||
*/
|
||||
#define ddi_get_lbolt() (gethrtime() >> 23)
|
||||
#define ddi_get_lbolt64() (gethrtime() >> 23)
|
||||
#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
|
||||
|
||||
#define ddi_time_before(a, b) (a < b)
|
||||
#define ddi_time_after(a, b) ddi_time_before(b, a)
|
||||
#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
|
||||
#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
|
||||
|
||||
#define ddi_time_before64(a, b) (a < b)
|
||||
#define ddi_time_after64(a, b) ddi_time_before64(b, a)
|
||||
#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
|
||||
#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
|
||||
|
||||
extern void delay(clock_t ticks);
|
||||
|
||||
#define SEC_TO_TICK(sec) ((sec) * hz)
|
||||
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
|
||||
#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
|
||||
#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
|
||||
|
||||
#define max_ncpus 64
|
||||
#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
|
||||
|
||||
/*
|
||||
* Process priorities as defined by setpriority(2) and getpriority(2).
|
||||
*/
|
||||
#define minclsyspri 19
|
||||
#define defclsyspri 0
|
||||
/* Write issue taskq priority. */
|
||||
#define wtqclsyspri -19
|
||||
#define maxclsyspri -20
|
||||
|
||||
#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1))
|
||||
#define CPU_SEQID_UNSTABLE CPU_SEQID
|
||||
|
||||
#define kcred NULL
|
||||
#define CRED() NULL
|
||||
|
||||
#define crhold(cr) ((void)cr)
|
||||
#define crfree(cr) ((void)cr)
|
||||
|
||||
#define ptob(x) ((x) * PAGESIZE)
|
||||
|
||||
#define NN_DIVISOR_1000 (1U << 0)
|
||||
#define NN_NUMBUF_SZ (6)
|
||||
|
||||
extern uint64_t physmem;
|
||||
extern const char *random_path;
|
||||
extern const char *urandom_path;
|
||||
|
||||
extern int highbit64(uint64_t i);
|
||||
extern int lowbit64(uint64_t i);
|
||||
extern int random_get_bytes(uint8_t *ptr, size_t len);
|
||||
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
|
||||
|
||||
static __inline__ uint32_t
|
||||
random_in_range(uint32_t range)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
ASSERT(range != 0);
|
||||
|
||||
if (range == 1)
|
||||
return (0);
|
||||
|
||||
(void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
|
||||
|
||||
return (r % range);
|
||||
}
|
||||
|
||||
extern void kernel_init(int mode);
|
||||
extern void kernel_fini(void);
|
||||
extern void random_init(void);
|
||||
extern void random_fini(void);
|
||||
|
||||
struct spa;
|
||||
extern void show_pool_stats(struct spa *);
|
||||
extern int handle_tunable_option(const char *, boolean_t);
|
||||
|
||||
typedef struct callb_cpr {
|
||||
kmutex_t *cc_lockp;
|
||||
} callb_cpr_t;
|
||||
|
||||
#define CALLB_CPR_INIT(cp, lockp, func, name) { \
|
||||
(cp)->cc_lockp = lockp; \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_SAFE_BEGIN(cp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_SAFE_END(cp, lockp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_EXIT(cp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
mutex_exit((cp)->cc_lockp); \
|
||||
}
|
||||
|
||||
#define zone_dataset_visible(x, y) (1)
|
||||
#define INGLOBALZONE(z) (1)
|
||||
extern uint32_t zone_get_hostid(void *zonep);
|
||||
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list adx);
|
||||
extern char *kmem_asprintf(const char *fmt, ...);
|
||||
#define kmem_strfree(str) kmem_free((str), strlen(str) + 1)
|
||||
#define kmem_strdup(s) strdup(s)
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern int kmem_scnprintf(char *restrict str, size_t size,
|
||||
const char *restrict fmt, ...);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hostname information
|
||||
*/
|
||||
extern int ddi_strtoull(const char *str, char **nptr, int base,
|
||||
u_longlong_t *result);
|
||||
|
||||
typedef struct utsname utsname_t;
|
||||
extern utsname_t *utsname(void);
|
||||
|
||||
/* ZFS Boot Related stuff. */
|
||||
|
||||
struct _buf {
|
||||
intptr_t _fd;
|
||||
};
|
||||
|
||||
struct bootstat {
|
||||
uint64_t st_size;
|
||||
};
|
||||
|
||||
typedef struct ace_object {
|
||||
uid_t a_who;
|
||||
uint32_t a_access_mask;
|
||||
uint16_t a_flags;
|
||||
uint16_t a_type;
|
||||
uint8_t a_obj_type[16];
|
||||
uint8_t a_inherit_obj_type[16];
|
||||
} ace_object_t;
|
||||
|
||||
|
||||
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
|
||||
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
|
||||
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
|
||||
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
|
||||
|
||||
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
|
||||
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
|
||||
cred_t *cr);
|
||||
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
|
||||
extern int secpolicy_zfs(const cred_t *cr);
|
||||
extern zoneid_t getzoneid(void);
|
||||
|
||||
/* SID stuff */
|
||||
typedef struct ksiddomain {
|
||||
uint_t kd_ref;
|
||||
uint_t kd_len;
|
||||
char *kd_name;
|
||||
} ksiddomain_t;
|
||||
|
||||
ksiddomain_t *ksid_lookupdomain(const char *);
|
||||
void ksiddomain_rele(ksiddomain_t *);
|
||||
|
||||
#define DDI_SLEEP KM_SLEEP
|
||||
#define ddi_log_sysevent(_a, _b, _c, _d, _e, _f, _g) \
|
||||
sysevent_post_event(_c, _d, _b, "libzpool", _e, _f)
|
||||
|
||||
#define zfs_sleep_until(wakeup) \
|
||||
do { \
|
||||
hrtime_t delta = wakeup - gethrtime(); \
|
||||
struct timespec ts; \
|
||||
ts.tv_sec = delta / NANOSEC; \
|
||||
ts.tv_nsec = delta % NANOSEC; \
|
||||
(void) nanosleep(&ts, NULL); \
|
||||
} while (0)
|
||||
|
||||
typedef int fstrans_cookie_t;
|
||||
|
||||
extern fstrans_cookie_t spl_fstrans_mark(void);
|
||||
extern void spl_fstrans_unmark(fstrans_cookie_t);
|
||||
extern int kmem_cache_reap_active(void);
|
||||
|
||||
|
||||
/*
|
||||
* Kernel modules
|
||||
*/
|
||||
#define __init
|
||||
#define __exit
|
||||
|
||||
#endif /* _KERNEL || _STANDALONE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -40,6 +40,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/nvpair.h>
|
||||
#include <sys/zfs_debug_os.h>
|
||||
|
||||
extern int zfs_flags;
|
||||
extern int zfs_recover;
|
||||
|
||||
@@ -35,18 +35,16 @@
|
||||
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#ifdef FS_PROJINHERIT_FL
|
||||
#define ZFS_PROJINHERIT_FL FS_PROJINHERIT_FL
|
||||
#else
|
||||
#define ZFS_PROJINHERIT_FL 0x20000000
|
||||
#endif
|
||||
|
||||
#ifdef FS_IOC_FSGETXATTR
|
||||
typedef struct fsxattr zfsxattr_t;
|
||||
|
||||
#define ZFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
|
||||
#define ZFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
|
||||
#else
|
||||
/* Non-Linux OS */
|
||||
#define FS_PROJINHERIT_FL 0x20000000
|
||||
#define FS_XFLAG_PROJINHERIT FS_PROJINHERIT_FL
|
||||
|
||||
struct zfsxattr {
|
||||
uint32_t fsx_xflags; /* xflags field value (get/set) */
|
||||
uint32_t fsx_extsize; /* extsize field value (get/set) */
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
libicp_la_CCASFLAGS = $(AM_CCASFLAGS)
|
||||
libicp_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) $(LIBRARY_CFLAGS)
|
||||
|
||||
libicp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBZPOOL_CPPFLAGS)
|
||||
libicp_la_CPPFLAGS += -I$(top_srcdir)/module/icp/include
|
||||
|
||||
noinst_LTLIBRARIES += libicp.la
|
||||
|
||||
nodist_libicp_la_SOURCES = \
|
||||
@@ -35,8 +38,7 @@ nodist_libicp_la_SOURCES = \
|
||||
module/icp/core/kcf_prov_lib.c \
|
||||
module/icp/core/kcf_callprov.c \
|
||||
module/icp/core/kcf_mech_tabs.c \
|
||||
module/icp/core/kcf_prov_tabs.c \
|
||||
module/zfs/zfs_impl.c
|
||||
module/icp/core/kcf_prov_tabs.c
|
||||
|
||||
if TARGET_CPU_AARCH64
|
||||
nodist_libicp_la_SOURCES += \
|
||||
|
||||
@@ -30,6 +30,6 @@ if !ASAN_ENABLED
|
||||
libnvpair_la_LDFLAGS += -Wl,-z,defs
|
||||
endif
|
||||
|
||||
libnvpair_la_LDFLAGS += -version-info 3:0:0
|
||||
libnvpair_la_LDFLAGS += -version-info 4:0:1
|
||||
|
||||
dist_noinst_DATA += %D%/libnvpair.abi %D%/libnvpair.suppr
|
||||
|
||||
@@ -16,12 +16,24 @@ libspl_assert_la_SOURCES = \
|
||||
libspl_la_SOURCES = \
|
||||
%D%/libspl_impl.h \
|
||||
%D%/atomic.c \
|
||||
%D%/condvar.c \
|
||||
%D%/cred.c \
|
||||
%D%/getexecname.c \
|
||||
%D%/kmem.c \
|
||||
%D%/kstat.c \
|
||||
%D%/libspl.c \
|
||||
%D%/list.c \
|
||||
%D%/mkdirp.c \
|
||||
%D%/mutex.c \
|
||||
%D%/page.c \
|
||||
%D%/procfs_list.c \
|
||||
%D%/random.c \
|
||||
%D%/rwlock.c \
|
||||
%D%/sid.c \
|
||||
%D%/strlcat.c \
|
||||
%D%/strlcpy.c \
|
||||
%D%/taskq.c \
|
||||
%D%/thread.c \
|
||||
%D%/timestamp.c \
|
||||
%D%/tunables.c \
|
||||
%D%/include/sys/list.h \
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/timer.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* condition variables
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
cv_init(kcondvar_t *cv, char *name, int type, void *arg)
|
||||
{
|
||||
(void) name, (void) type, (void) arg;
|
||||
VERIFY0(pthread_cond_init(cv, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
cv_destroy(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY0(pthread_cond_destroy(cv));
|
||||
}
|
||||
|
||||
void
|
||||
cv_wait(kcondvar_t *cv, kmutex_t *mp)
|
||||
{
|
||||
memset(&mp->m_owner, 0, sizeof (pthread_t));
|
||||
VERIFY0(pthread_cond_wait(cv, &mp->m_lock));
|
||||
mp->m_owner = pthread_self();
|
||||
}
|
||||
|
||||
int
|
||||
cv_wait_sig(kcondvar_t *cv, kmutex_t *mp)
|
||||
{
|
||||
cv_wait(cv, mp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
|
||||
{
|
||||
int error;
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
clock_t delta;
|
||||
|
||||
delta = abstime - ddi_get_lbolt();
|
||||
if (delta <= 0)
|
||||
return (-1);
|
||||
|
||||
VERIFY0(gettimeofday(&tv, NULL));
|
||||
|
||||
ts.tv_sec = tv.tv_sec + delta / hz;
|
||||
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
|
||||
if (ts.tv_nsec >= NANOSEC) {
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= NANOSEC;
|
||||
}
|
||||
|
||||
memset(&mp->m_owner, 0, sizeof (pthread_t));
|
||||
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
|
||||
mp->m_owner = pthread_self();
|
||||
|
||||
if (error == ETIMEDOUT)
|
||||
return (-1);
|
||||
|
||||
VERIFY0(error);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
|
||||
int flag)
|
||||
{
|
||||
(void) res;
|
||||
int error;
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
hrtime_t delta;
|
||||
|
||||
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
|
||||
|
||||
delta = tim;
|
||||
if (flag & CALLOUT_FLAG_ABSOLUTE)
|
||||
delta -= gethrtime();
|
||||
|
||||
if (delta <= 0)
|
||||
return (-1);
|
||||
|
||||
VERIFY0(gettimeofday(&tv, NULL));
|
||||
|
||||
ts.tv_sec = tv.tv_sec + delta / NANOSEC;
|
||||
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);
|
||||
if (ts.tv_nsec >= NANOSEC) {
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= NANOSEC;
|
||||
}
|
||||
|
||||
memset(&mp->m_owner, 0, sizeof (pthread_t));
|
||||
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
|
||||
mp->m_owner = pthread_self();
|
||||
|
||||
if (error == ETIMEDOUT)
|
||||
return (-1);
|
||||
|
||||
VERIFY0(error);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
cv_signal(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY0(pthread_cond_signal(cv));
|
||||
}
|
||||
|
||||
void
|
||||
cv_broadcast(kcondvar_t *cv)
|
||||
{
|
||||
VERIFY0(pthread_cond_broadcast(cv));
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/cred.h>
|
||||
|
||||
uid_t
|
||||
crgetuid(cred_t *cr)
|
||||
{
|
||||
(void) cr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
uid_t
|
||||
crgetruid(cred_t *cr)
|
||||
{
|
||||
(void) cr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t
|
||||
crgetgid(cred_t *cr)
|
||||
{
|
||||
(void) cr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
crgetngroups(cred_t *cr)
|
||||
{
|
||||
(void) cr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
gid_t *
|
||||
crgetgroups(cred_t *cr)
|
||||
{
|
||||
(void) cr;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ libspl_HEADERS = \
|
||||
%D%/atomic.h \
|
||||
%D%/libgen.h \
|
||||
%D%/libshare.h \
|
||||
%D%/libspl.h \
|
||||
%D%/statcommon.h \
|
||||
%D%/stdlib.h \
|
||||
%D%/string.h \
|
||||
@@ -24,14 +25,13 @@ libspl_rpc_HEADERS = \
|
||||
|
||||
libspl_sysdir = $(libspldir)/sys
|
||||
libspl_sys_HEADERS = \
|
||||
%D%/sys/abd_os.h \
|
||||
%D%/sys/abd_impl_os.h \
|
||||
%D%/sys/acl.h \
|
||||
%D%/sys/acl_impl.h \
|
||||
%D%/sys/asm_linkage.h \
|
||||
%D%/sys/backtrace.h \
|
||||
%D%/sys/callb.h \
|
||||
%D%/sys/cmn_err.h \
|
||||
%D%/sys/condvar.h \
|
||||
%D%/sys/cred.h \
|
||||
%D%/sys/debug.h \
|
||||
%D%/sys/dkio.h \
|
||||
@@ -43,22 +43,33 @@ libspl_sys_HEADERS = \
|
||||
%D%/sys/kstat.h \
|
||||
%D%/sys/list.h \
|
||||
%D%/sys/list_impl.h \
|
||||
%D%/sys/misc.h \
|
||||
%D%/sys/mhd.h \
|
||||
%D%/sys/mkdev.h \
|
||||
%D%/sys/mod.h \
|
||||
%D%/sys/mutex.h \
|
||||
%D%/sys/policy.h \
|
||||
%D%/sys/poll.h \
|
||||
%D%/sys/priv.h \
|
||||
%D%/sys/processor.h \
|
||||
%D%/sys/procfs_list.h \
|
||||
%D%/sys/random.h \
|
||||
%D%/sys/rwlock.h \
|
||||
%D%/sys/sid.h \
|
||||
%D%/sys/simd.h \
|
||||
%D%/sys/stack.h \
|
||||
%D%/sys/stdtypes.h \
|
||||
%D%/sys/string.h \
|
||||
%D%/sys/sunddi.h \
|
||||
%D%/sys/sysmacros.h \
|
||||
%D%/sys/systeminfo.h \
|
||||
%D%/sys/systm.h \
|
||||
%D%/sys/thread.h \
|
||||
%D%/sys/taskq.h \
|
||||
%D%/sys/time.h \
|
||||
%D%/sys/trace_spl.h \
|
||||
%D%/sys/trace_zfs.h \
|
||||
%D%/sys/timer.h \
|
||||
%D%/sys/trace.h \
|
||||
%D%/sys/tsd.h \
|
||||
%D%/sys/tunables.h \
|
||||
%D%/sys/types.h \
|
||||
%D%/sys/types32.h \
|
||||
@@ -77,8 +88,7 @@ libspl_sys_HEADERS += \
|
||||
%D%/os/linux/sys/mount.h \
|
||||
%D%/os/linux/sys/param.h \
|
||||
%D%/os/linux/sys/stat.h \
|
||||
%D%/os/linux/sys/sysmacros.h \
|
||||
%D%/os/linux/sys/zfs_context_os.h
|
||||
%D%/os/linux/sys/vfs.h
|
||||
|
||||
libspl_ia32_HEADERS = \
|
||||
%D%/os/linux/sys/ia32/asm_linkage.h
|
||||
@@ -93,9 +103,7 @@ libspl_sys_HEADERS += \
|
||||
%D%/os/freebsd/sys/mount.h \
|
||||
%D%/os/freebsd/sys/param.h \
|
||||
%D%/os/freebsd/sys/stat.h \
|
||||
%D%/os/freebsd/sys/sysmacros.h \
|
||||
%D%/os/freebsd/sys/vfs.h \
|
||||
%D%/os/freebsd/sys/zfs_context_os.h
|
||||
%D%/os/freebsd/sys/vfs.h
|
||||
|
||||
libspl_ia32_HEADERS = \
|
||||
%D%/os/freebsd/sys/ia32/asm_linkage.h
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_H
|
||||
#define _LIBSPL_H extern __attribute__((visibility("default")))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
_LIBSPL_H void libspl_init(void);
|
||||
_LIBSPL_H void libspl_fini(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _LIBSPL_H */
|
||||
@@ -58,6 +58,8 @@
|
||||
extern size_t spl_pagesize(void);
|
||||
#define PAGESIZE (spl_pagesize())
|
||||
|
||||
#define ptob(x) ((x) * PAGESIZE)
|
||||
|
||||
#ifndef HAVE_EXECVPE
|
||||
extern int execvpe(const char *name, char * const argv[], char * const envp[]);
|
||||
#endif
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
/*
|
||||
* Copyright (c) 2020 iXsystems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef ZFS_CONTEXT_OS_H_
|
||||
#define ZFS_CONTEXT_OS_H_
|
||||
|
||||
#define HAVE_LARGE_STACKS 1
|
||||
|
||||
#endif
|
||||
@@ -65,4 +65,6 @@
|
||||
extern size_t spl_pagesize(void);
|
||||
#define PAGESIZE (spl_pagesize())
|
||||
|
||||
#define ptob(x) ((x) * PAGESIZE)
|
||||
|
||||
#endif
|
||||
|
||||
+7
-3
@@ -20,10 +20,14 @@
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/* Copyright 2025 by Lawrence Livermore National Security, LLC. */
|
||||
|
||||
#ifndef ZFS_CONTEXT_OS_H
|
||||
#define ZFS_CONTEXT_OS_H
|
||||
/* This is the Linux userspace version of include/os/linux/spl/sys/vfs.h */
|
||||
|
||||
#define HAVE_LARGE_STACKS 1
|
||||
#ifndef _LIBSPL_SYS_VFS_H
|
||||
#define _LIBSPL_SYS_VFS_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <sys/statfs.h>
|
||||
|
||||
#endif
|
||||
@@ -141,8 +141,6 @@ typedef struct acl_info acl_t;
|
||||
|
||||
#define ACE_ALL_TYPES 0x001F
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
typedef struct ace_object {
|
||||
uid_t a_who; /* uid or gid */
|
||||
uint32_t a_access_mask; /* read,write,... */
|
||||
@@ -152,8 +150,6 @@ typedef struct ace_object {
|
||||
uint8_t a_inherit_obj_type[16]; /* inherit obj */
|
||||
} ace_object_t;
|
||||
|
||||
#endif
|
||||
|
||||
#define ACE_ALL_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
|
||||
ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \
|
||||
ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
|
||||
|
||||
@@ -21,11 +21,36 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CALLB_H
|
||||
#define _SYS_CALLB_H
|
||||
|
||||
#include <sys/mutex.h>
|
||||
|
||||
typedef struct callb_cpr {
|
||||
kmutex_t *cc_lockp;
|
||||
} callb_cpr_t;
|
||||
|
||||
#define CALLB_CPR_INIT(cp, lockp, func, name) { \
|
||||
(cp)->cc_lockp = lockp; \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_SAFE_BEGIN(cp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_SAFE_END(cp, lockp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
}
|
||||
|
||||
#define CALLB_CPR_EXIT(cp) { \
|
||||
ASSERT(MUTEX_HELD((cp)->cc_lockp)); \
|
||||
mutex_exit((cp)->cc_lockp); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,4 +62,31 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Note that we are not using the debugging levels.
|
||||
*/
|
||||
|
||||
#define CE_CONT 0 /* continuation */
|
||||
#define CE_NOTE 1 /* notice */
|
||||
#define CE_WARN 2 /* warning */
|
||||
#define CE_PANIC 3 /* panic */
|
||||
#define CE_IGNORE 4 /* print nothing */
|
||||
|
||||
/*
|
||||
* ZFS debugging
|
||||
*/
|
||||
|
||||
extern void dprintf_setup(int *argc, char **argv);
|
||||
|
||||
extern void cmn_err(int, const char *, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
extern void vcmn_err(int, const char *, va_list)
|
||||
__attribute__((format(printf, 2, 0)));
|
||||
extern void panic(const char *, ...)
|
||||
__attribute__((format(printf, 1, 2), noreturn));
|
||||
extern void vpanic(const char *, va_list)
|
||||
__attribute__((format(printf, 1, 0), noreturn));
|
||||
|
||||
#define fm_panic panic
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CONDVAR_H
|
||||
#define _SYS_CONDVAR_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
/*
|
||||
* Condition variables
|
||||
*/
|
||||
typedef pthread_cond_t kcondvar_t;
|
||||
|
||||
#define CV_DEFAULT 0
|
||||
#define CALLOUT_FLAG_ABSOLUTE 0x2
|
||||
|
||||
extern void cv_init(kcondvar_t *cv, char *name, int type, void *arg);
|
||||
extern void cv_destroy(kcondvar_t *cv);
|
||||
extern void cv_wait(kcondvar_t *cv, kmutex_t *mp);
|
||||
extern int cv_wait_sig(kcondvar_t *cv, kmutex_t *mp);
|
||||
extern int cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime);
|
||||
extern int cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
|
||||
hrtime_t res, int flag);
|
||||
extern void cv_signal(kcondvar_t *cv);
|
||||
extern void cv_broadcast(kcondvar_t *cv);
|
||||
|
||||
#define cv_timedwait_io(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_timedwait_idle(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_timedwait_sig(cv, mp, at) cv_timedwait(cv, mp, at)
|
||||
#define cv_wait_io(cv, mp) cv_wait(cv, mp)
|
||||
#define cv_wait_idle(cv, mp) cv_wait(cv, mp)
|
||||
#define cv_wait_io_sig(cv, mp) cv_wait_sig(cv, mp)
|
||||
#define cv_timedwait_sig_hires(cv, mp, t, r, f) \
|
||||
cv_timedwait_hires(cv, mp, t, r, f)
|
||||
#define cv_timedwait_idle_hires(cv, mp, t, r, f) \
|
||||
cv_timedwait_hires(cv, mp, t, r, f)
|
||||
|
||||
#endif /* _SYS_CONDVAR_H */
|
||||
@@ -28,6 +28,24 @@
|
||||
#ifndef _LIBSPL_SYS_CRED_H
|
||||
#define _LIBSPL_SYS_CRED_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
* Credentials
|
||||
*/
|
||||
|
||||
typedef struct cred cred_t;
|
||||
|
||||
extern uid_t crgetuid(cred_t *cr);
|
||||
extern uid_t crgetruid(cred_t *cr);
|
||||
extern gid_t crgetgid(cred_t *cr);
|
||||
extern int crgetngroups(cred_t *cr);
|
||||
extern gid_t *crgetgroups(cred_t *cr);
|
||||
|
||||
#define kcred NULL
|
||||
#define CRED() NULL
|
||||
|
||||
#define crhold(cr) ((void)cr)
|
||||
#define crfree(cr) ((void)cr)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,12 @@
|
||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_DEBUG_H
|
||||
#define _LIBSPL_SYS_DEBUG_H
|
||||
@@ -42,4 +48,22 @@
|
||||
#define __must_check __attribute__((warn_unused_result))
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
#define noinline __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
#ifndef likely
|
||||
#define likely(x) __builtin_expect((x), 1)
|
||||
#endif
|
||||
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect((x), 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Kernel modules
|
||||
*/
|
||||
#define __init
|
||||
#define __exit
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,27 +20,67 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_KMEM_H
|
||||
#define _SYS_KMEM_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <umem.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Kernel memory
|
||||
*/
|
||||
#define KM_SLEEP UMEM_NOFAIL
|
||||
#define KM_PUSHPAGE KM_SLEEP
|
||||
#define KM_NOSLEEP UMEM_DEFAULT
|
||||
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
|
||||
#define KMC_NODEBUG UMC_NODEBUG
|
||||
#define KMC_KVMEM 0x0
|
||||
#define KMC_RECLAIMABLE 0x0
|
||||
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
|
||||
#define kmem_zalloc(_s, _f) umem_zalloc(_s, _f)
|
||||
#define kmem_free(_b, _s) umem_free(_b, _s)
|
||||
#define vmem_alloc(_s, _f) kmem_alloc(_s, _f)
|
||||
#define vmem_zalloc(_s, _f) kmem_zalloc(_s, _f)
|
||||
#define vmem_free(_b, _s) kmem_free(_b, _s)
|
||||
#define kmem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i) \
|
||||
umem_cache_create(_a, _b, _c, _d, _e, _f, _g, _h, _i)
|
||||
#define kmem_cache_destroy(_c) umem_cache_destroy(_c)
|
||||
#define kmem_cache_alloc(_c, _f) umem_cache_alloc(_c, _f)
|
||||
#define kmem_cache_free(_c, _b) umem_cache_free(_c, _b)
|
||||
#define kmem_debugging() 0
|
||||
#define kmem_cache_reap_now(_c) umem_cache_reap_now(_c);
|
||||
extern int kmem_cache_reap_active(void);
|
||||
#define kmem_cache_set_move(_c, _cb) /* nothing */
|
||||
#define POINTER_INVALIDATE(_pp) /* nothing */
|
||||
#define POINTER_IS_VALID(_p) 0
|
||||
|
||||
#define KM_SLEEP 0x00000000 /* same as KM_SLEEP */
|
||||
#define KM_NOSLEEP 0x00000001 /* same as KM_NOSLEEP */
|
||||
extern char *kmem_vasprintf(const char *fmt, va_list adx);
|
||||
extern char *kmem_asprintf(const char *fmt, ...);
|
||||
#define kmem_strfree(str) kmem_free((str), strlen(str) + 1)
|
||||
#define kmem_strdup(s) strdup(s)
|
||||
|
||||
#define kmem_alloc(size, flags) ((void) sizeof (flags), malloc(size))
|
||||
#define kmem_free(ptr, size) ((void) sizeof (size), free(ptr))
|
||||
extern int kmem_scnprintf(char *restrict str, size_t size,
|
||||
const char *restrict fmt, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
typedef umem_cache_t kmem_cache_t;
|
||||
|
||||
typedef enum kmem_cbrc {
|
||||
KMEM_CBRC_YES,
|
||||
KMEM_CBRC_NO,
|
||||
KMEM_CBRC_LATER,
|
||||
KMEM_CBRC_DONT_NEED,
|
||||
KMEM_CBRC_DONT_KNOW
|
||||
} kmem_cbrc_t;
|
||||
|
||||
typedef int fstrans_cookie_t;
|
||||
|
||||
extern fstrans_cookie_t spl_fstrans_mark(void);
|
||||
extern void spl_fstrans_unmark(fstrans_cookie_t);
|
||||
|
||||
#endif /* _SYS_KMEM_H */
|
||||
|
||||
@@ -27,758 +27,65 @@
|
||||
#ifndef _SYS_KSTAT_H
|
||||
#define _SYS_KSTAT_H
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Definition of general kernel statistics structures and /dev/kstat ioctls
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int kid_t; /* unique kstat id */
|
||||
|
||||
/*
|
||||
* Kernel statistics driver (/dev/kstat) ioctls
|
||||
*/
|
||||
|
||||
#define KSTAT_IOC_BASE ('K' << 8)
|
||||
|
||||
#define KSTAT_IOC_CHAIN_ID KSTAT_IOC_BASE | 0x01
|
||||
#define KSTAT_IOC_READ KSTAT_IOC_BASE | 0x02
|
||||
#define KSTAT_IOC_WRITE KSTAT_IOC_BASE | 0x03
|
||||
|
||||
/*
|
||||
* /dev/kstat ioctl usage (kd denotes /dev/kstat descriptor):
|
||||
*
|
||||
* kcid = ioctl(kd, KSTAT_IOC_CHAIN_ID, NULL);
|
||||
* kcid = ioctl(kd, KSTAT_IOC_READ, kstat_t *);
|
||||
* kcid = ioctl(kd, KSTAT_IOC_WRITE, kstat_t *);
|
||||
*/
|
||||
|
||||
#define KSTAT_STRLEN 255 /* 254 chars + NULL; must be 16 * n - 1 */
|
||||
|
||||
/*
|
||||
* The generic kstat header
|
||||
*/
|
||||
|
||||
typedef struct kstat {
|
||||
/*
|
||||
* Fields relevant to both kernel and user
|
||||
*/
|
||||
hrtime_t ks_crtime; /* creation time (from gethrtime()) */
|
||||
struct kstat *ks_next; /* kstat chain linkage */
|
||||
kid_t ks_kid; /* unique kstat ID */
|
||||
char ks_module[KSTAT_STRLEN]; /* provider module name */
|
||||
uchar_t ks_resv; /* reserved, currently just padding */
|
||||
int ks_instance; /* provider module's instance */
|
||||
char ks_name[KSTAT_STRLEN]; /* kstat name */
|
||||
uchar_t ks_type; /* kstat data type */
|
||||
char ks_class[KSTAT_STRLEN]; /* kstat class */
|
||||
uchar_t ks_flags; /* kstat flags */
|
||||
void *ks_data; /* kstat type-specific data */
|
||||
uint_t ks_ndata; /* # of type-specific data records */
|
||||
size_t ks_data_size; /* total size of kstat data section */
|
||||
hrtime_t ks_snaptime; /* time of last data snapshot */
|
||||
/*
|
||||
* Fields relevant to kernel only
|
||||
*/
|
||||
int (*ks_update)(struct kstat *, int); /* dynamic update */
|
||||
void *ks_private; /* arbitrary provider-private data */
|
||||
int (*ks_snapshot)(struct kstat *, void *, int);
|
||||
void *ks_lock; /* protects this kstat's data */
|
||||
uchar_t ks_flags;
|
||||
void *ks_data;
|
||||
uint_t ks_ndata;
|
||||
size_t ks_data_size;
|
||||
int (*ks_update)(struct kstat *, int);
|
||||
void *ks_private;
|
||||
void *ks_lock;
|
||||
} kstat_t;
|
||||
|
||||
/*
|
||||
* kstat structure and locking strategy
|
||||
*
|
||||
* Each kstat consists of a header section (a kstat_t) and a data section.
|
||||
* The system maintains a set of kstats, protected by kstat_chain_lock.
|
||||
* kstat_chain_lock protects all additions to/deletions from this set,
|
||||
* as well as all changes to kstat headers. kstat data sections are
|
||||
* *optionally* protected by the per-kstat ks_lock. If ks_lock is non-NULL,
|
||||
* kstat clients (e.g. /dev/kstat) will acquire this lock for all of their
|
||||
* operations on that kstat. It is up to the kstat provider to decide whether
|
||||
* guaranteeing consistent data to kstat clients is sufficiently important
|
||||
* to justify the locking cost. Note, however, that most statistic updates
|
||||
* already occur under one of the provider's mutexes, so if the provider sets
|
||||
* ks_lock to point to that mutex, then kstat data locking is free.
|
||||
*
|
||||
* NOTE: variable-size kstats MUST employ kstat data locking, to prevent
|
||||
* data-size races with kstat clients.
|
||||
*
|
||||
* NOTE: ks_lock is really of type (kmutex_t *); it is declared as (void *)
|
||||
* in the kstat header so that users don't have to be exposed to all of the
|
||||
* kernel's lock-related data structures.
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
#define KSTAT_ENTER(k) \
|
||||
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_enter(lp); }
|
||||
|
||||
#define KSTAT_EXIT(k) \
|
||||
{ kmutex_t *lp = (k)->ks_lock; if (lp) mutex_exit(lp); }
|
||||
|
||||
#define KSTAT_UPDATE(k, rw) (*(k)->ks_update)((k), (rw))
|
||||
|
||||
#define KSTAT_SNAPSHOT(k, buf, rw) (*(k)->ks_snapshot)((k), (buf), (rw))
|
||||
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
/*
|
||||
* kstat time
|
||||
*
|
||||
* All times associated with kstats (e.g. creation time, snapshot time,
|
||||
* kstat_timer_t and kstat_io_t timestamps, etc.) are 64-bit nanosecond values,
|
||||
* as returned by gethrtime(). The accuracy of these timestamps is machine
|
||||
* dependent, but the precision (units) is the same across all platforms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat identity (KID)
|
||||
*
|
||||
* Each kstat is assigned a unique KID (kstat ID) when it is added to the
|
||||
* global kstat chain. The KID is used as a cookie by /dev/kstat to
|
||||
* request information about the corresponding kstat. There is also
|
||||
* an identity associated with the entire kstat chain, kstat_chain_id,
|
||||
* which is bumped each time a kstat is added or deleted. /dev/kstat uses
|
||||
* the chain ID to detect changes in the kstat chain (e.g., a new disk
|
||||
* coming online) between ioctl()s.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat module, kstat instance
|
||||
*
|
||||
* ks_module and ks_instance contain the name and instance of the module
|
||||
* that created the kstat. In cases where there can only be one instance,
|
||||
* ks_instance is 0. The kernel proper (/kernel/unix) uses "unix" as its
|
||||
* module name.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat name
|
||||
*
|
||||
* ks_name gives a meaningful name to a kstat. The full kstat namespace
|
||||
* is module.instance.name, so the name only need be unique within a
|
||||
* module. kstat_create() will fail if you try to create a kstat with
|
||||
* an already-used (ks_module, ks_instance, ks_name) triplet. Spaces are
|
||||
* allowed in kstat names, but strongly discouraged, since they hinder
|
||||
* awk-style processing at user level.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat type
|
||||
*
|
||||
* The kstat mechanism provides several flavors of kstat data, defined
|
||||
* below. The "raw" kstat type is just treated as an array of bytes; you
|
||||
* can use this to export any kind of data you want.
|
||||
*
|
||||
* Some kstat types allow multiple data structures per kstat, e.g.
|
||||
* KSTAT_TYPE_NAMED; others do not. This is part of the spec for each
|
||||
* kstat data type.
|
||||
*
|
||||
* User-level tools should *not* rely on the #define KSTAT_NUM_TYPES. To
|
||||
* get this information, read out the standard system kstat "kstat_types".
|
||||
*/
|
||||
|
||||
#define KSTAT_TYPE_RAW 0 /* can be anything */
|
||||
/* ks_ndata >= 1 */
|
||||
#define KSTAT_TYPE_NAMED 1 /* name/value pair */
|
||||
/* ks_ndata >= 1 */
|
||||
#define KSTAT_TYPE_INTR 2 /* interrupt statistics */
|
||||
/* ks_ndata == 1 */
|
||||
#define KSTAT_TYPE_IO 3 /* I/O statistics */
|
||||
/* ks_ndata == 1 */
|
||||
#define KSTAT_TYPE_TIMER 4 /* event timer */
|
||||
/* ks_ndata >= 1 */
|
||||
|
||||
#define KSTAT_NUM_TYPES 5
|
||||
|
||||
/*
|
||||
* kstat class
|
||||
*
|
||||
* Each kstat can be characterized as belonging to some broad class
|
||||
* of statistics, e.g. disk, tape, net, vm, streams, etc. This field
|
||||
* can be used as a filter to extract related kstats. The following
|
||||
* values are currently in use: disk, tape, net, controller, vm, kvm,
|
||||
* hat, streams, kstat, and misc. (The kstat class encompasses things
|
||||
* like kstat_types.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* kstat flags
|
||||
*
|
||||
* Any of the following flags may be passed to kstat_create(). They are
|
||||
* all zero by default.
|
||||
*
|
||||
* KSTAT_FLAG_VIRTUAL:
|
||||
*
|
||||
* Tells kstat_create() not to allocate memory for the
|
||||
* kstat data section; instead, you will set the ks_data
|
||||
* field to point to the data you wish to export. This
|
||||
* provides a convenient way to export existing data
|
||||
* structures.
|
||||
*
|
||||
* KSTAT_FLAG_VAR_SIZE:
|
||||
*
|
||||
* The size of the kstat you are creating will vary over time.
|
||||
* For example, you may want to use the kstat mechanism to
|
||||
* export a linked list. NOTE: The kstat framework does not
|
||||
* manage the data section, so all variable-size kstats must be
|
||||
* virtual kstats. Moreover, variable-size kstats MUST employ
|
||||
* kstat data locking to prevent data-size races with kstat
|
||||
* clients. See the section on "kstat snapshot" for details.
|
||||
*
|
||||
* KSTAT_FLAG_WRITABLE:
|
||||
*
|
||||
* Makes the kstat's data section writable by root.
|
||||
* The ks_snapshot routine (see below) does not need to check for
|
||||
* this; permission checking is handled in the kstat driver.
|
||||
*
|
||||
* KSTAT_FLAG_PERSISTENT:
|
||||
*
|
||||
* Indicates that this kstat is to be persistent over time.
|
||||
* For persistent kstats, kstat_delete() simply marks the
|
||||
* kstat as dormant; a subsequent kstat_create() reactivates
|
||||
* the kstat. This feature is provided so that statistics
|
||||
* are not lost across driver close/open (e.g., raw disk I/O
|
||||
* on a disk with no mounted partitions.)
|
||||
* NOTE: Persistent kstats cannot be virtual, since ks_data
|
||||
* points to garbage as soon as the driver goes away.
|
||||
*
|
||||
* The following flags are maintained by the kstat framework:
|
||||
*
|
||||
* KSTAT_FLAG_DORMANT:
|
||||
*
|
||||
* For persistent kstats, indicates that the kstat is in the
|
||||
* dormant state (e.g., the corresponding device is closed).
|
||||
*
|
||||
* KSTAT_FLAG_INVALID:
|
||||
*
|
||||
* This flag is set when a kstat is in a transitional state,
|
||||
* e.g. between kstat_create() and kstat_install().
|
||||
* kstat clients must not attempt to access the kstat's data
|
||||
* if this flag is set.
|
||||
*/
|
||||
#define KSTAT_TYPE_RAW 0
|
||||
#define KSTAT_TYPE_NAMED 1
|
||||
|
||||
#define KSTAT_FLAG_VIRTUAL 0x01
|
||||
#define KSTAT_FLAG_VAR_SIZE 0x02
|
||||
#define KSTAT_FLAG_WRITABLE 0x04
|
||||
#define KSTAT_FLAG_PERSISTENT 0x08
|
||||
#define KSTAT_FLAG_DORMANT 0x10
|
||||
#define KSTAT_FLAG_INVALID 0x20
|
||||
#define KSTAT_FLAG_LONGSTRINGS 0x40
|
||||
#define KSTAT_FLAG_NO_HEADERS 0x80
|
||||
|
||||
/*
|
||||
* Dynamic update support
|
||||
*
|
||||
* The kstat mechanism allows for an optional ks_update function to update
|
||||
* kstat data. This is useful for drivers where the underlying device
|
||||
* keeps cheap hardware stats, but extraction is expensive. Instead of
|
||||
* constantly keeping the kstat data section up to date, you can supply a
|
||||
* ks_update function which updates the kstat's data section on demand.
|
||||
* To take advantage of this feature, simply set the ks_update field before
|
||||
* calling kstat_install().
|
||||
*
|
||||
* The ks_update function, if supplied, must have the following structure:
|
||||
*
|
||||
* int
|
||||
* foo_kstat_update(kstat_t *ksp, int rw)
|
||||
* {
|
||||
* if (rw == KSTAT_WRITE) {
|
||||
* ... update the native stats from ksp->ks_data;
|
||||
* return EACCES if you don't support this
|
||||
* } else {
|
||||
* ... update ksp->ks_data from the native stats
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The ks_update return codes are: 0 for success, EACCES if you don't allow
|
||||
* KSTAT_WRITE, and EIO for any other type of error.
|
||||
*
|
||||
* In general, the ks_update function may need to refer to provider-private
|
||||
* data; for example, it may need a pointer to the provider's raw statistics.
|
||||
* The ks_private field is available for this purpose. Its use is entirely
|
||||
* at the provider's discretion.
|
||||
*
|
||||
* All variable-size kstats MUST supply a ks_update routine, which computes
|
||||
* and sets ks_data_size (and ks_ndata if that is meaningful), since these
|
||||
* are needed to perform kstat snapshots (see below).
|
||||
*
|
||||
* No kstat locking should be done inside the ks_update routine. The caller
|
||||
* will already be holding the kstat's ks_lock (to ensure consistent data).
|
||||
*/
|
||||
|
||||
#define KSTAT_READ 0
|
||||
#define KSTAT_WRITE 1
|
||||
|
||||
/*
|
||||
* Kstat snapshot
|
||||
*
|
||||
* In order to get a consistent view of a kstat's data, clients must obey
|
||||
* the kstat's locking strategy. However, these clients may need to perform
|
||||
* operations on the data which could cause a fault (e.g. copyout()), or
|
||||
* operations which are simply expensive. Doing so could cause deadlock
|
||||
* (e.g. if you're holding a disk's kstat lock which is ultimately required
|
||||
* to resolve a copyout() fault), performance degradation (since the providers'
|
||||
* activity is serialized at the kstat lock), device timing problems, etc.
|
||||
*
|
||||
* To avoid these problems, kstat data is provided via snapshots. Taking
|
||||
* a snapshot is a simple process: allocate a wired-down kernel buffer,
|
||||
* acquire the kstat's data lock, copy the data into the buffer ("take the
|
||||
* snapshot"), and release the lock. This ensures that the kstat's data lock
|
||||
* will be held as briefly as possible, and that no faults will occur while
|
||||
* the lock is held.
|
||||
*
|
||||
* Normally, the snapshot is taken by default_kstat_snapshot(), which
|
||||
* timestamps the data (sets ks_snaptime), copies it, and does a little
|
||||
* massaging to deal with incomplete transactions on i/o kstats. However,
|
||||
* this routine only works for kstats with contiguous data (the typical case).
|
||||
* If you create a kstat whose data is, say, a linked list, you must provide
|
||||
* your own ks_snapshot routine. The routine you supply must have the
|
||||
* following prototype (replace "foo" with something appropriate):
|
||||
*
|
||||
* int foo_kstat_snapshot(kstat_t *ksp, void *buf, int rw);
|
||||
*
|
||||
* The minimal snapshot routine -- one which copies contiguous data that
|
||||
* doesn't need any massaging -- would be this:
|
||||
*
|
||||
* ksp->ks_snaptime = gethrtime();
|
||||
* if (rw == KSTAT_WRITE)
|
||||
* memcpy(ksp->ks_data, buf, ksp->ks_data_size);
|
||||
* else
|
||||
* memcpy(buf, ksp->ks_data, ksp->ks_data_size);
|
||||
* return (0);
|
||||
*
|
||||
* A more illuminating example is taking a snapshot of a linked list:
|
||||
*
|
||||
* ksp->ks_snaptime = gethrtime();
|
||||
* if (rw == KSTAT_WRITE)
|
||||
* return (EACCES); ... See below ...
|
||||
* for (foo = first_foo; foo; foo = foo->next) {
|
||||
* memcpy(buf, foo, sizeof (struct foo));
|
||||
* buf = ((struct foo *) buf) + 1;
|
||||
* }
|
||||
* return (0);
|
||||
*
|
||||
* In the example above, we have decided that we don't want to allow
|
||||
* KSTAT_WRITE access, so we return EACCES if this is attempted.
|
||||
*
|
||||
* The key points are:
|
||||
*
|
||||
* (1) ks_snaptime must be set (via gethrtime()) to timestamp the data.
|
||||
* (2) Data gets copied from the kstat to the buffer on KSTAT_READ,
|
||||
* and from the buffer to the kstat on KSTAT_WRITE.
|
||||
* (3) ks_snapshot return values are: 0 for success, EACCES if you
|
||||
* don't allow KSTAT_WRITE, and EIO for any other type of error.
|
||||
*
|
||||
* Named kstats (see section on "Named statistics" below) containing long
|
||||
* strings (KSTAT_DATA_STRING) need special handling. The kstat driver
|
||||
* assumes that all strings are copied into the buffer after the array of
|
||||
* named kstats, and the pointers (KSTAT_NAMED_STR_PTR()) are updated to point
|
||||
* into the copy within the buffer. The default snapshot routine does this,
|
||||
* but overriding routines should contain at least the following:
|
||||
*
|
||||
* if (rw == KSTAT_READ) {
|
||||
* kstat_named_t *knp = buf;
|
||||
* char *end = knp + ksp->ks_ndata;
|
||||
* uint_t i;
|
||||
*
|
||||
* ... Do the regular copy ...
|
||||
* memcpy(buf, ksp->ks_data, sizeof (kstat_named_t) * ksp->ks_ndata);
|
||||
*
|
||||
* for (i = 0; i < ksp->ks_ndata; i++, knp++) {
|
||||
* if (knp[i].data_type == KSTAT_DATA_STRING &&
|
||||
* KSTAT_NAMED_STR_PTR(knp) != NULL) {
|
||||
* memcpy(end, KSTAT_NAMED_STR_PTR(knp),
|
||||
* KSTAT_NAMED_STR_BUFLEN(knp));
|
||||
* KSTAT_NAMED_STR_PTR(knp) = end;
|
||||
* end += KSTAT_NAMED_STR_BUFLEN(knp);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Named statistics.
|
||||
*
|
||||
* List of arbitrary name=value statistics.
|
||||
*/
|
||||
|
||||
typedef struct kstat_named {
|
||||
char name[KSTAT_STRLEN]; /* name of counter */
|
||||
uchar_t data_type; /* data type */
|
||||
char name[KSTAT_STRLEN];
|
||||
uchar_t data_type;
|
||||
union {
|
||||
char c[16]; /* enough for 128-bit ints */
|
||||
int32_t i32;
|
||||
uint32_t ui32;
|
||||
struct {
|
||||
union {
|
||||
char *ptr; /* NULL-term string */
|
||||
#if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
|
||||
caddr32_t ptr32;
|
||||
#endif
|
||||
char __pad[8]; /* 64-bit padding */
|
||||
char *ptr;
|
||||
char __pad[8];
|
||||
} addr;
|
||||
uint32_t len; /* # bytes for strlen + '\0' */
|
||||
uint32_t len;
|
||||
} str;
|
||||
/*
|
||||
* The int64_t and uint64_t types are not valid for a maximally conformant
|
||||
* 32-bit compilation environment (cc -Xc) using compilers prior to the
|
||||
* introduction of C99 conforming compiler (reference ISO/IEC 9899:1990).
|
||||
* In these cases, the visibility of i64 and ui64 is only permitted for
|
||||
* 64-bit compilation environments or 32-bit non-maximally conformant
|
||||
* C89 or C90 ANSI C compilation environments (cc -Xt and cc -Xa). In the
|
||||
* C99 ANSI C compilation environment, the long long type is supported.
|
||||
* The _INT64_TYPE is defined by the implementation (see sys/inttypes.h).
|
||||
*/
|
||||
#if defined(_INT64_TYPE)
|
||||
int64_t i64;
|
||||
uint64_t ui64;
|
||||
#endif
|
||||
long l;
|
||||
ulong_t ul;
|
||||
|
||||
/* These structure members are obsolete */
|
||||
|
||||
longlong_t ll;
|
||||
u_longlong_t ull;
|
||||
float f;
|
||||
double d;
|
||||
} value; /* value of counter */
|
||||
} value;
|
||||
} kstat_named_t;
|
||||
|
||||
#define KSTAT_DATA_CHAR 0
|
||||
#define KSTAT_DATA_INT32 1
|
||||
#define KSTAT_DATA_UINT32 2
|
||||
#define KSTAT_DATA_INT64 3
|
||||
#define KSTAT_DATA_UINT64 4
|
||||
|
||||
#if !defined(_LP64)
|
||||
#define KSTAT_DATA_LONG KSTAT_DATA_INT32
|
||||
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT32
|
||||
#else
|
||||
#if !defined(_KERNEL)
|
||||
#define KSTAT_DATA_LONG KSTAT_DATA_INT64
|
||||
#define KSTAT_DATA_ULONG KSTAT_DATA_UINT64
|
||||
#else
|
||||
#define KSTAT_DATA_LONG 7 /* only visible to the kernel */
|
||||
#define KSTAT_DATA_ULONG 8 /* only visible to the kernel */
|
||||
#endif /* !_KERNEL */
|
||||
#endif /* !_LP64 */
|
||||
|
||||
/*
|
||||
* Statistics exporting named kstats with long strings (KSTAT_DATA_STRING)
|
||||
* may not make the assumption that ks_data_size is equal to (ks_ndata * sizeof
|
||||
* (kstat_named_t)). ks_data_size in these cases is equal to the sum of the
|
||||
* amount of space required to store the strings (ie, the sum of
|
||||
* KSTAT_NAMED_STR_BUFLEN() for all KSTAT_DATA_STRING statistics) plus the
|
||||
* space required to store the kstat_named_t's.
|
||||
*
|
||||
* The default update routine will update ks_data_size automatically for
|
||||
* variable-length kstats containing long strings (using the default update
|
||||
* routine only makes sense if the string is the only thing that is changing
|
||||
* in size, and ks_ndata is constant). Fixed-length kstats containing long
|
||||
* strings must explicitly change ks_data_size (after creation but before
|
||||
* initialization) to reflect the correct amount of space required for the
|
||||
* long strings and the kstat_named_t's.
|
||||
*/
|
||||
#define KSTAT_DATA_STRING 9
|
||||
|
||||
/* These types are obsolete */
|
||||
|
||||
#define KSTAT_DATA_LONGLONG KSTAT_DATA_INT64
|
||||
#define KSTAT_DATA_ULONGLONG KSTAT_DATA_UINT64
|
||||
#define KSTAT_DATA_FLOAT 5
|
||||
#define KSTAT_DATA_DOUBLE 6
|
||||
|
||||
#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
|
||||
#define KSTAT_NAMED_PTR(kptr) ((kstat_named_t *)(kptr)->ks_data)
|
||||
#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
|
||||
#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len)
|
||||
|
||||
/*
|
||||
* Retrieve the pointer of the string contained in the given named kstat.
|
||||
* kstat creation, installation and deletion
|
||||
*/
|
||||
#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.str.addr.ptr)
|
||||
|
||||
/*
|
||||
* Retrieve the length of the buffer required to store the string in the given
|
||||
* named kstat.
|
||||
*/
|
||||
#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.str.len)
|
||||
|
||||
/*
|
||||
* Interrupt statistics.
|
||||
*
|
||||
* An interrupt is a hard interrupt (sourced from the hardware device
|
||||
* itself), a soft interrupt (induced by the system via the use of
|
||||
* some system interrupt source), a watchdog interrupt (induced by
|
||||
* a periodic timer call), spurious (an interrupt entry point was
|
||||
* entered but there was no interrupt condition to service),
|
||||
* or multiple service (an interrupt condition was detected and
|
||||
* serviced just prior to returning from any of the other types).
|
||||
*
|
||||
* Measurement of the spurious class of interrupts is useful for
|
||||
* autovectored devices in order to pinpoint any interrupt latency
|
||||
* problems in a particular system configuration.
|
||||
*
|
||||
* Devices that have more than one interrupt of the same
|
||||
* type should use multiple structures.
|
||||
*/
|
||||
|
||||
#define KSTAT_INTR_HARD 0
|
||||
#define KSTAT_INTR_SOFT 1
|
||||
#define KSTAT_INTR_WATCHDOG 2
|
||||
#define KSTAT_INTR_SPURIOUS 3
|
||||
#define KSTAT_INTR_MULTSVC 4
|
||||
|
||||
#define KSTAT_NUM_INTRS 5
|
||||
|
||||
typedef struct kstat_intr {
|
||||
uint_t intrs[KSTAT_NUM_INTRS]; /* interrupt counters */
|
||||
} kstat_intr_t;
|
||||
|
||||
#define KSTAT_INTR_PTR(kptr) ((kstat_intr_t *)(kptr)->ks_data)
|
||||
|
||||
/*
|
||||
* I/O statistics.
|
||||
*/
|
||||
|
||||
typedef struct kstat_io {
|
||||
|
||||
/*
|
||||
* Basic counters.
|
||||
*
|
||||
* The counters should be updated at the end of service
|
||||
* (e.g., just prior to calling biodone()).
|
||||
*/
|
||||
|
||||
u_longlong_t nread; /* number of bytes read */
|
||||
u_longlong_t nwritten; /* number of bytes written */
|
||||
uint_t reads; /* number of read operations */
|
||||
uint_t writes; /* number of write operations */
|
||||
|
||||
/*
|
||||
* Accumulated time and queue length statistics.
|
||||
*
|
||||
* Accumulated time statistics are kept as a running sum
|
||||
* of "active" time. Queue length statistics are kept as a
|
||||
* running sum of the product of queue length and elapsed time
|
||||
* at that length -- i.e., a Riemann sum for queue length
|
||||
* integrated against time. (You can also think of the active time
|
||||
* as a Riemann sum, for the boolean function (queue_length > 0)
|
||||
* integrated against time, or you can think of it as the
|
||||
* Lebesgue measure of the set on which queue_length > 0.)
|
||||
*
|
||||
* ^
|
||||
* | _________
|
||||
* 8 | i4 |
|
||||
* | | |
|
||||
* Queue 6 | |
|
||||
* Length | _________ | |
|
||||
* 4 | i2 |_______| |
|
||||
* | | i3 |
|
||||
* 2_______| |
|
||||
* | i1 |
|
||||
* |_______________________________|
|
||||
* Time-> t1 t2 t3 t4
|
||||
*
|
||||
* At each change of state (entry or exit from the queue),
|
||||
* we add the elapsed time (since the previous state change)
|
||||
* to the active time if the queue length was non-zero during
|
||||
* that interval; and we add the product of the elapsed time
|
||||
* times the queue length to the running length*time sum.
|
||||
*
|
||||
* This method is generalizable to measuring residency
|
||||
* in any defined system: instead of queue lengths, think
|
||||
* of "outstanding RPC calls to server X".
|
||||
*
|
||||
* A large number of I/O subsystems have at least two basic
|
||||
* "lists" of transactions they manage: one for transactions
|
||||
* that have been accepted for processing but for which processing
|
||||
* has yet to begin, and one for transactions which are actively
|
||||
* being processed (but not done). For this reason, two cumulative
|
||||
* time statistics are defined here: wait (pre-service) time,
|
||||
* and run (service) time.
|
||||
*
|
||||
* All times are 64-bit nanoseconds (hrtime_t), as returned by
|
||||
* gethrtime().
|
||||
*
|
||||
* The units of cumulative busy time are accumulated nanoseconds.
|
||||
* The units of cumulative length*time products are elapsed time
|
||||
* times queue length.
|
||||
*
|
||||
* Updates to the fields below are performed implicitly by calls to
|
||||
* these five functions:
|
||||
*
|
||||
* kstat_waitq_enter()
|
||||
* kstat_waitq_exit()
|
||||
* kstat_runq_enter()
|
||||
* kstat_runq_exit()
|
||||
*
|
||||
* kstat_waitq_to_runq() (see below)
|
||||
* kstat_runq_back_to_waitq() (see below)
|
||||
*
|
||||
* Since kstat_waitq_exit() is typically followed immediately
|
||||
* by kstat_runq_enter(), there is a single kstat_waitq_to_runq()
|
||||
* function which performs both operations. This is a performance
|
||||
* win since only one timestamp is required.
|
||||
*
|
||||
* In some instances, it may be necessary to move a request from
|
||||
* the run queue back to the wait queue, e.g. for write throttling.
|
||||
* For these situations, call kstat_runq_back_to_waitq().
|
||||
*
|
||||
* These fields should never be updated by any other means.
|
||||
*/
|
||||
|
||||
hrtime_t wtime; /* cumulative wait (pre-service) time */
|
||||
hrtime_t wlentime; /* cumulative wait length*time product */
|
||||
hrtime_t wlastupdate; /* last time wait queue changed */
|
||||
hrtime_t rtime; /* cumulative run (service) time */
|
||||
hrtime_t rlentime; /* cumulative run length*time product */
|
||||
hrtime_t rlastupdate; /* last time run queue changed */
|
||||
|
||||
uint_t wcnt; /* count of elements in wait state */
|
||||
uint_t rcnt; /* count of elements in run state */
|
||||
|
||||
} kstat_io_t;
|
||||
|
||||
#define KSTAT_IO_PTR(kptr) ((kstat_io_t *)(kptr)->ks_data)
|
||||
|
||||
/*
|
||||
* Event timer statistics - cumulative elapsed time and number of events.
|
||||
*
|
||||
* Updates to these fields are performed implicitly by calls to
|
||||
* kstat_timer_start() and kstat_timer_stop().
|
||||
*/
|
||||
|
||||
typedef struct kstat_timer {
|
||||
char name[KSTAT_STRLEN]; /* event name */
|
||||
uchar_t resv; /* reserved */
|
||||
u_longlong_t num_events; /* number of events */
|
||||
hrtime_t elapsed_time; /* cumulative elapsed time */
|
||||
hrtime_t min_time; /* shortest event duration */
|
||||
hrtime_t max_time; /* longest event duration */
|
||||
hrtime_t start_time; /* previous event start time */
|
||||
hrtime_t stop_time; /* previous event stop time */
|
||||
} kstat_timer_t;
|
||||
|
||||
#define KSTAT_TIMER_PTR(kptr) ((kstat_timer_t *)(kptr)->ks_data)
|
||||
|
||||
#if defined(_KERNEL)
|
||||
|
||||
#include <sys/t_lock.h>
|
||||
|
||||
extern kid_t kstat_chain_id; /* bumped at each state change */
|
||||
extern void kstat_init(void); /* initialize kstat framework */
|
||||
|
||||
/*
|
||||
* Adding and deleting kstats.
|
||||
*
|
||||
* The typical sequence to add a kstat is:
|
||||
*
|
||||
* ksp = kstat_create(module, instance, name, class, type, ndata, flags);
|
||||
* if (ksp) {
|
||||
* ... provider initialization, if necessary
|
||||
* kstat_install(ksp);
|
||||
* }
|
||||
*
|
||||
* There are three logically distinct steps here:
|
||||
*
|
||||
* Step 1: System Initialization (kstat_create)
|
||||
*
|
||||
* kstat_create() performs system initialization. kstat_create()
|
||||
* allocates memory for the entire kstat (header plus data), initializes
|
||||
* all header fields, initializes the data section to all zeroes, assigns
|
||||
* a unique KID, and puts the kstat onto the system's kstat chain.
|
||||
* The returned kstat is marked invalid (KSTAT_FLAG_INVALID is set),
|
||||
* because the provider (caller) has not yet had a chance to initialize
|
||||
* the data section.
|
||||
*
|
||||
* By default, kstats are exported to all zones on the system. A kstat may be
|
||||
* created via kstat_create_zone() to specify a zone to which the statistics
|
||||
* should be exported. kstat_zone_add() may be used to specify additional
|
||||
* zones to which the statistics are to be exported.
|
||||
*
|
||||
* Step 2: Provider Initialization
|
||||
*
|
||||
* The provider performs any necessary initialization of the data section,
|
||||
* e.g. setting the name fields in a KSTAT_TYPE_NAMED. Virtual kstats set
|
||||
* the ks_data field at this time. The provider may also set the ks_update,
|
||||
* ks_snapshot, ks_private, and ks_lock fields if necessary.
|
||||
*
|
||||
* Step 3: Installation (kstat_install)
|
||||
*
|
||||
* Once the kstat is completely initialized, kstat_install() clears the
|
||||
* INVALID flag, thus making the kstat accessible to the outside world.
|
||||
* kstat_install() also clears the DORMANT flag for persistent kstats.
|
||||
*
|
||||
* Removing a kstat from the system
|
||||
*
|
||||
* kstat_delete(ksp) removes ksp from the kstat chain and frees all
|
||||
* associated system resources. NOTE: When you call kstat_delete(),
|
||||
* you must NOT be holding that kstat's ks_lock. Otherwise, you may
|
||||
* deadlock with a kstat reader.
|
||||
*
|
||||
* Persistent kstats
|
||||
*
|
||||
* From the provider's point of view, persistence is transparent. The only
|
||||
* difference between ephemeral (normal) kstats and persistent kstats
|
||||
* is that you pass KSTAT_FLAG_PERSISTENT to kstat_create(). Magically,
|
||||
* this has the effect of making your data visible even when you're
|
||||
* not home. Persistence is important to tools like iostat, which want
|
||||
* to get a meaningful picture of disk activity. Without persistence,
|
||||
* raw disk i/o statistics could never accumulate: they would come and
|
||||
* go with each open/close of the raw device.
|
||||
*
|
||||
* The magic of persistence works by slightly altering the behavior of
|
||||
* kstat_create() and kstat_delete(). The first call to kstat_create()
|
||||
* creates a new kstat, as usual. However, kstat_delete() does not
|
||||
* actually delete the kstat: it performs one final update of the data
|
||||
* (i.e., calls the ks_update routine), marks the kstat as dormant, and
|
||||
* sets the ks_lock, ks_update, ks_private, and ks_snapshot fields back
|
||||
* to their default values (since they might otherwise point to garbage,
|
||||
* e.g. if the provider is going away). kstat clients can still access
|
||||
* the dormant kstat just like a live kstat; they just continue to see
|
||||
* the final data values as long as the kstat remains dormant.
|
||||
* All subsequent kstat_create() calls simply find the already-existing,
|
||||
* dormant kstat and return a pointer to it, without altering any fields.
|
||||
* The provider then performs its usual initialization sequence, and
|
||||
* calls kstat_install(). kstat_install() uses the old data values to
|
||||
* initialize the native data (i.e., ks_update is called with KSTAT_WRITE),
|
||||
* thus making it seem like you were never gone.
|
||||
*/
|
||||
|
||||
extern kstat_t *kstat_create(const char *, int, const char *, const char *,
|
||||
uchar_t, uint_t, uchar_t);
|
||||
extern kstat_t *kstat_create_zone(const char *, int, const char *,
|
||||
const char *, uchar_t, uint_t, uchar_t, zoneid_t);
|
||||
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_named_setstr(kstat_named_t *knp, const char *src);
|
||||
extern void kstat_set_string(char *, const char *);
|
||||
extern void kstat_delete_byname(const char *, int, const char *);
|
||||
extern void kstat_delete_byname_zone(const char *, int, const char *, zoneid_t);
|
||||
extern void kstat_named_init(kstat_named_t *, const char *, uchar_t);
|
||||
extern void kstat_timer_init(kstat_timer_t *, const char *);
|
||||
extern void kstat_timer_start(kstat_timer_t *);
|
||||
extern void kstat_timer_stop(kstat_timer_t *);
|
||||
|
||||
extern void kstat_zone_add(kstat_t *, zoneid_t);
|
||||
extern void kstat_zone_remove(kstat_t *, zoneid_t);
|
||||
extern int kstat_zone_find(kstat_t *, zoneid_t);
|
||||
|
||||
extern kstat_t *kstat_hold_bykid(kid_t kid, zoneid_t);
|
||||
extern kstat_t *kstat_hold_byname(const char *, int, const char *, zoneid_t);
|
||||
extern void kstat_rele(kstat_t *);
|
||||
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
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),
|
||||
void *(*addr)(kstat_t *ksp, loff_t index));
|
||||
|
||||
#endif /* _SYS_KSTAT_H */
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_MISC_H
|
||||
#define _LIBSPL_SYS_MISC_H
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
/*
|
||||
* Hostname information
|
||||
*/
|
||||
typedef struct utsname utsname_t;
|
||||
extern utsname_t *utsname(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_MUTEX_H
|
||||
#define _SYS_MUTEX_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* Mutexes
|
||||
*/
|
||||
typedef struct kmutex {
|
||||
pthread_mutex_t m_lock;
|
||||
pthread_t m_owner;
|
||||
} kmutex_t;
|
||||
|
||||
#define MUTEX_DEFAULT 0
|
||||
#define MUTEX_NOLOCKDEP MUTEX_DEFAULT
|
||||
#define MUTEX_HELD(mp) pthread_equal((mp)->m_owner, pthread_self())
|
||||
#define MUTEX_NOT_HELD(mp) !MUTEX_HELD(mp)
|
||||
|
||||
extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
|
||||
extern void mutex_destroy(kmutex_t *mp);
|
||||
extern void mutex_enter(kmutex_t *mp);
|
||||
extern int mutex_enter_check_return(kmutex_t *mp);
|
||||
extern void mutex_exit(kmutex_t *mp);
|
||||
extern int mutex_tryenter(kmutex_t *mp);
|
||||
|
||||
#define NESTED_SINGLE 1
|
||||
#define mutex_enter_nested(mp, class) mutex_enter(mp)
|
||||
#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
|
||||
|
||||
#endif /* _SYS_MUTEX_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PROCFS_LIST_H
|
||||
#define _SYS_PROCFS_LIST_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/list.h>
|
||||
|
||||
/*
|
||||
* procfs list manipulation
|
||||
*/
|
||||
|
||||
typedef struct procfs_list {
|
||||
void *pl_private;
|
||||
kmutex_t pl_lock;
|
||||
list_t pl_list;
|
||||
uint64_t pl_next_id;
|
||||
size_t pl_node_offset;
|
||||
} procfs_list_t;
|
||||
|
||||
struct seq_file { };
|
||||
void seq_printf(struct seq_file *m, const char *fmt, ...);
|
||||
|
||||
typedef struct procfs_list_node {
|
||||
list_node_t pln_link;
|
||||
uint64_t pln_id;
|
||||
} procfs_list_node_t;
|
||||
|
||||
void procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
int (*show)(struct seq_file *f, void *p),
|
||||
int (*show_header)(struct seq_file *f),
|
||||
int (*clear)(procfs_list_t *procfs_list),
|
||||
size_t procfs_list_node_off);
|
||||
void procfs_list_uninstall(procfs_list_t *procfs_list);
|
||||
void procfs_list_destroy(procfs_list_t *procfs_list);
|
||||
void procfs_list_add(procfs_list_t *procfs_list, void *p);
|
||||
|
||||
#endif /* _SYS_PROCFS_LIST_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_RANDOM_H
|
||||
#define _SYS_RANDOM_H
|
||||
|
||||
extern int random_get_bytes(uint8_t *ptr, size_t len);
|
||||
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
|
||||
|
||||
extern void random_force_pseudo(boolean_t onoff);
|
||||
|
||||
static __inline__ uint32_t
|
||||
random_in_range(uint32_t range)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
ASSERT(range != 0);
|
||||
|
||||
if (range == 1)
|
||||
return (0);
|
||||
|
||||
(void) random_get_pseudo_bytes((uint8_t *)&r, sizeof (r));
|
||||
|
||||
return (r % range);
|
||||
}
|
||||
|
||||
#endif /* _SYS_RANDOM_H */
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_RWLOCK_H
|
||||
#define _SYS_RWLOCK_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* RW locks
|
||||
*/
|
||||
typedef struct krwlock {
|
||||
pthread_rwlock_t rw_lock;
|
||||
pthread_t rw_owner;
|
||||
uint_t rw_readers;
|
||||
} krwlock_t;
|
||||
|
||||
typedef int krw_t;
|
||||
|
||||
#define RW_READER 0
|
||||
#define RW_WRITER 1
|
||||
#define RW_DEFAULT RW_READER
|
||||
#define RW_NOLOCKDEP RW_READER
|
||||
|
||||
#define RW_READ_HELD(rw) ((rw)->rw_readers > 0)
|
||||
#define RW_WRITE_HELD(rw) pthread_equal((rw)->rw_owner, pthread_self())
|
||||
#define RW_LOCK_HELD(rw) (RW_READ_HELD(rw) || RW_WRITE_HELD(rw))
|
||||
|
||||
extern void rw_init(krwlock_t *rwlp, char *name, int type, void *arg);
|
||||
extern void rw_destroy(krwlock_t *rwlp);
|
||||
extern void rw_enter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryenter(krwlock_t *rwlp, krw_t rw);
|
||||
extern int rw_tryupgrade(krwlock_t *rwlp);
|
||||
extern void rw_exit(krwlock_t *rwlp);
|
||||
#define rw_downgrade(rwlp) do { } while (0)
|
||||
|
||||
#endif /* _SYS_RWLOCK_H */
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SID_H
|
||||
#define _SYS_SID_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* SID stuff */
|
||||
typedef struct ksiddomain {
|
||||
uint_t kd_ref;
|
||||
uint_t kd_len;
|
||||
char *kd_name;
|
||||
} ksiddomain_t;
|
||||
|
||||
ksiddomain_t *ksid_lookupdomain(const char *);
|
||||
void ksiddomain_rele(ksiddomain_t *);
|
||||
|
||||
#endif
|
||||
@@ -1 +1,4 @@
|
||||
#ifndef _LIBSPL_SYS_STRING_H
|
||||
#define _LIBSPL_SYS_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
@@ -21,10 +21,16 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2008 by Sun Microsystems, Inc.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SUNDDI_H
|
||||
#define _SYS_SUNDDI_H
|
||||
|
||||
extern int ddi_strtoull(const char *str, char **nptr, int base,
|
||||
u_longlong_t *result);
|
||||
|
||||
#endif /* _SYS_SUNDDI_H */
|
||||
|
||||
+33
-10
@@ -3,9 +3,8 @@
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
@@ -21,14 +20,26 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_SYSMACROS_H
|
||||
#define _LIBSPL_SYS_SYSMACROS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* On Linux, we need the system-provided sysmacros.h to get the makedev(),
|
||||
* major() and minor() definitions for makedevice() below. FreeBSD does not
|
||||
* have this header, so include_next won't find it and will abort. So, we
|
||||
* protect it with a platform check.
|
||||
*/
|
||||
#include_next <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
/* common macros */
|
||||
#ifndef MIN
|
||||
@@ -94,10 +105,22 @@
|
||||
#define P2SAMEHIGHBIT_TYPED(x, y, type) \
|
||||
(((type)(x) ^ (type)(y)) < ((type)(x) & (type)(y)))
|
||||
|
||||
#define max_ncpus 64
|
||||
#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
|
||||
|
||||
/* avoid any possibility of clashing with <stddef.h> version */
|
||||
#if defined(_KERNEL) && !defined(_KMEMUSER) && !defined(offsetof)
|
||||
#define offsetof(s, m) ((size_t)(&(((s *)0)->m)))
|
||||
#endif
|
||||
/*
|
||||
* Process priorities as defined by setpriority(2) and getpriority(2).
|
||||
*/
|
||||
#define minclsyspri 19
|
||||
#define defclsyspri 0
|
||||
/* Write issue taskq priority. */
|
||||
#define wtqclsyspri -19
|
||||
#define maxclsyspri -20
|
||||
|
||||
#endif /* _LIBSPL_SYS_SYSMACROS_H */
|
||||
#define CPU_SEQID ((uintptr_t)pthread_self() & (max_ncpus - 1))
|
||||
#define CPU_SEQID_UNSTABLE CPU_SEQID
|
||||
|
||||
extern int lowbit64(uint64_t i);
|
||||
extern int highbit64(uint64_t i);
|
||||
|
||||
#endif /* _SYS_SYSMACROS_H */
|
||||
@@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_SYSTM_H
|
||||
#define _LIBSPL_SYS_SYSTM_H
|
||||
|
||||
uint64_t libspl_physmem(void);
|
||||
|
||||
#define physmem libspl_physmem()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,119 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TASKQ_H
|
||||
#define _SYS_TASKQ_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
/*
|
||||
* Task queues
|
||||
*/
|
||||
|
||||
#define TASKQ_NAMELEN 31
|
||||
|
||||
typedef uintptr_t taskqid_t;
|
||||
typedef void (task_func_t)(void *);
|
||||
|
||||
typedef struct taskq_ent {
|
||||
struct taskq_ent *tqent_next;
|
||||
struct taskq_ent *tqent_prev;
|
||||
task_func_t *tqent_func;
|
||||
void *tqent_arg;
|
||||
uintptr_t tqent_flags;
|
||||
} taskq_ent_t;
|
||||
|
||||
typedef struct taskq {
|
||||
char tq_name[TASKQ_NAMELEN + 1];
|
||||
kmutex_t tq_lock;
|
||||
krwlock_t tq_threadlock;
|
||||
kcondvar_t tq_dispatch_cv;
|
||||
kcondvar_t tq_wait_cv;
|
||||
kthread_t **tq_threadlist;
|
||||
int tq_flags;
|
||||
int tq_active;
|
||||
int tq_nthreads;
|
||||
int tq_nalloc;
|
||||
int tq_minalloc;
|
||||
int tq_maxalloc;
|
||||
kcondvar_t tq_maxalloc_cv;
|
||||
int tq_maxalloc_wait;
|
||||
taskq_ent_t *tq_freelist;
|
||||
taskq_ent_t tq_task;
|
||||
} taskq_t;
|
||||
|
||||
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
|
||||
|
||||
#define TASKQ_PREPOPULATE 0x0001
|
||||
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
||||
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
||||
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
|
||||
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
|
||||
|
||||
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
|
||||
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
|
||||
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
||||
#define TQ_FRONT 0x08 /* Queue in front */
|
||||
|
||||
#define TASKQID_INVALID ((taskqid_t)0)
|
||||
|
||||
extern taskq_t *_system_taskq(void);
|
||||
extern taskq_t *_system_delay_taskq(void);
|
||||
|
||||
#define system_taskq _system_taskq()
|
||||
#define system_delay_taskq _system_delay_taskq()
|
||||
|
||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
|
||||
kthread_t ***);
|
||||
#define taskq_create_proc(a, b, c, d, e, p, f) \
|
||||
(taskq_create(a, b, c, d, e, f))
|
||||
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
||||
((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
|
||||
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
||||
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
|
||||
clock_t);
|
||||
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||
taskq_ent_t *);
|
||||
extern int taskq_empty_ent(taskq_ent_t *);
|
||||
extern void taskq_init_ent(taskq_ent_t *);
|
||||
extern void taskq_destroy(taskq_t *);
|
||||
extern void taskq_wait(taskq_t *);
|
||||
extern void taskq_wait_id(taskq_t *, taskqid_t);
|
||||
extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
|
||||
extern int taskq_member(taskq_t *, kthread_t *);
|
||||
extern taskq_t *taskq_of_curthread(void);
|
||||
extern int taskq_cancel_id(taskq_t *, taskqid_t);
|
||||
extern void system_taskq_init(void);
|
||||
extern void system_taskq_fini(void);
|
||||
|
||||
#endif /* _SYS_TASKQ_H */
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_THREAD_H
|
||||
#define _SYS_THREAD_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* Threads.
|
||||
*/
|
||||
typedef pthread_t kthread_t;
|
||||
|
||||
#define TS_RUN 0x00000002
|
||||
#define TS_JOINABLE 0x00000004
|
||||
|
||||
#define curthread ((void *)(uintptr_t)pthread_self())
|
||||
#define getcomm() "unknown"
|
||||
|
||||
#define thread_create_named(name, stk, stksize, func, arg, len, \
|
||||
pp, state, pri) \
|
||||
zk_thread_create(name, func, arg, stksize, state)
|
||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||
zk_thread_create(#func, func, arg, stksize, state)
|
||||
#define thread_exit() pthread_exit(NULL)
|
||||
#define thread_join(t) pthread_join((pthread_t)(t), NULL)
|
||||
|
||||
#define newproc(f, a, cid, pri, ctp, pid) (ENOSYS)
|
||||
/*
|
||||
* Check if the current thread is a memory reclaim thread.
|
||||
* Always returns false in userspace (no memory reclaim thread).
|
||||
*/
|
||||
#define current_is_reclaim_thread() (0)
|
||||
|
||||
/* in libzpool, p0 exists only to have its address taken */
|
||||
typedef void (proc_t)(void);
|
||||
extern void p0(void);
|
||||
|
||||
#define curproc (&p0)
|
||||
|
||||
#define PS_NONE -1
|
||||
|
||||
extern kthread_t *zk_thread_create(const char *name, void (*func)(void *),
|
||||
void *arg, size_t stksize, int state);
|
||||
|
||||
#define issig() (FALSE)
|
||||
|
||||
#define KPREEMPT_SYNC (-1)
|
||||
|
||||
#define kpreempt(x) sched_yield()
|
||||
#define kpreempt_disable() ((void)0)
|
||||
#define kpreempt_enable() ((void)0)
|
||||
|
||||
#endif /* _SYS_THREAD_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPL_TIMER_H
|
||||
#define _SPL_TIMER_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#define ddi_get_lbolt() (gethrtime() >> 23)
|
||||
#define ddi_get_lbolt64() (gethrtime() >> 23)
|
||||
#define hz 119 /* frequency when using gethrtime() >> 23 for lbolt */
|
||||
|
||||
#define ddi_time_before(a, b) (a < b)
|
||||
#define ddi_time_after(a, b) ddi_time_before(b, a)
|
||||
#define ddi_time_before_eq(a, b) (!ddi_time_after(a, b))
|
||||
#define ddi_time_after_eq(a, b) ddi_time_before_eq(b, a)
|
||||
|
||||
#define ddi_time_before64(a, b) (a < b)
|
||||
#define ddi_time_after64(a, b) ddi_time_before64(b, a)
|
||||
#define ddi_time_before_eq64(a, b) (!ddi_time_after64(a, b))
|
||||
#define ddi_time_after_eq64(a, b) ddi_time_before_eq64(b, a)
|
||||
|
||||
extern void delay(clock_t ticks);
|
||||
|
||||
#define SEC_TO_TICK(sec) ((sec) * hz)
|
||||
#define MSEC_TO_TICK(msec) (howmany((hrtime_t)(msec) * hz, MILLISEC))
|
||||
#define USEC_TO_TICK(usec) (howmany((hrtime_t)(usec) * hz, MICROSEC))
|
||||
#define NSEC_TO_TICK(nsec) (howmany((hrtime_t)(nsec) * hz, NANOSEC))
|
||||
|
||||
#define usleep_range(min, max) \
|
||||
do { \
|
||||
struct timespec ts; \
|
||||
ts.tv_sec = min / MICROSEC; \
|
||||
ts.tv_nsec = USEC2NSEC(min); \
|
||||
(void) nanosleep(&ts, NULL); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _SPL_TIMER_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TRACE_H
|
||||
#define _SYS_TRACE_H
|
||||
|
||||
/*
|
||||
* DTrace SDT probes have different signatures in userland than they do in
|
||||
* the kernel. If they're being used in kernel code, re-define them out of
|
||||
* existence for their counterparts in libzpool.
|
||||
*
|
||||
* Here's an example of how to use the set-error probes in userland:
|
||||
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
|
||||
*
|
||||
* Here's an example of how to use DTRACE_PROBE probes in userland:
|
||||
* If there is a probe declared as follows:
|
||||
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
|
||||
* Then you can use it as follows:
|
||||
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
|
||||
* {printf("%u %p\n", arg1, arg2);}
|
||||
*/
|
||||
|
||||
#ifdef DTRACE_PROBE
|
||||
#undef DTRACE_PROBE
|
||||
#endif /* DTRACE_PROBE */
|
||||
#define DTRACE_PROBE(a)
|
||||
|
||||
#ifdef DTRACE_PROBE1
|
||||
#undef DTRACE_PROBE1
|
||||
#endif /* DTRACE_PROBE1 */
|
||||
#define DTRACE_PROBE1(a, b, c)
|
||||
|
||||
#ifdef DTRACE_PROBE2
|
||||
#undef DTRACE_PROBE2
|
||||
#endif /* DTRACE_PROBE2 */
|
||||
#define DTRACE_PROBE2(a, b, c, d, e)
|
||||
|
||||
#ifdef DTRACE_PROBE3
|
||||
#undef DTRACE_PROBE3
|
||||
#endif /* DTRACE_PROBE3 */
|
||||
#define DTRACE_PROBE3(a, b, c, d, e, f, g)
|
||||
|
||||
#ifdef DTRACE_PROBE4
|
||||
#undef DTRACE_PROBE4
|
||||
#endif /* DTRACE_PROBE4 */
|
||||
#define DTRACE_PROBE4(a, b, c, d, e, f, g, h, i)
|
||||
|
||||
#endif /* _SYS_TRACE_H */
|
||||
@@ -1,24 +0,0 @@
|
||||
/* Here to keep the libspl build happy */
|
||||
|
||||
#ifndef _LIBSPL_SPL_TRACE_H
|
||||
#define _LIBSPL_SPL_TRACE_H
|
||||
|
||||
/*
|
||||
* The set-error SDT probe is extra static, in that we declare its fake
|
||||
* function literally, rather than with the DTRACE_PROBE1() macro. This is
|
||||
* necessary so that SET_ERROR() can evaluate to a value, which wouldn't
|
||||
* be possible if it required multiple statements (to declare the function
|
||||
* and then call it).
|
||||
*
|
||||
* SET_ERROR() uses the comma operator so that it can be used without much
|
||||
* additional code. For example, "return (EINVAL);" becomes
|
||||
* "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
|
||||
* twice, so it should not have side effects (e.g. something like:
|
||||
* "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
|
||||
*/
|
||||
#undef SET_ERROR
|
||||
#define SET_ERROR(err) \
|
||||
(__set_error(__FILE__, __func__, __LINE__, err), err)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
/* Here to keep the libspl build happy */
|
||||
|
||||
#ifndef _LIBSPL_ZFS_TRACE_H
|
||||
#define _LIBSPL_ZFS_TRACE_H
|
||||
|
||||
/*
|
||||
* The set-error SDT probe is extra static, in that we declare its fake
|
||||
* function literally, rather than with the DTRACE_PROBE1() macro. This is
|
||||
* necessary so that SET_ERROR() can evaluate to a value, which wouldn't
|
||||
* be possible if it required multiple statements (to declare the function
|
||||
* and then call it).
|
||||
*
|
||||
* SET_ERROR() uses the comma operator so that it can be used without much
|
||||
* additional code. For example, "return (EINVAL);" becomes
|
||||
* "return (SET_ERROR(EINVAL));". Note that the argument will be evaluated
|
||||
* twice, so it should not have side effects (e.g. something like:
|
||||
* "return (SET_ERROR(log_error(EINVAL, info)));" would log the error twice).
|
||||
*/
|
||||
#undef SET_ERROR
|
||||
#define SET_ERROR(err) \
|
||||
(__set_error(__FILE__, __func__, __LINE__, err), err)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TSD_H
|
||||
#define _SYS_TSD_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* Thread-specific data
|
||||
*/
|
||||
#define tsd_get(k) pthread_getspecific(k)
|
||||
#define tsd_set(k, v) pthread_setspecific(k, v)
|
||||
#define tsd_create(kp, d) pthread_key_create((pthread_key_t *)kp, d)
|
||||
#define tsd_destroy(kp) /* nothing */
|
||||
|
||||
#endif /* _SYS_MUTEX_H */
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TUNABLES_H
|
||||
#define _SYS_TUNABLES_H
|
||||
#define _SYS_TUNABLES_H extern __attribute__((visibility("hidden")))
|
||||
|
||||
typedef enum {
|
||||
ZFS_TUNABLE_TYPE_INT,
|
||||
@@ -49,12 +49,14 @@ typedef struct zfs_tunable {
|
||||
const char *zt_desc;
|
||||
} zfs_tunable_t;
|
||||
|
||||
int zfs_tunable_set(const zfs_tunable_t *tunable, const char *val);
|
||||
int zfs_tunable_get(const zfs_tunable_t *tunable, char *val, size_t valsz);
|
||||
_SYS_TUNABLES_H int zfs_tunable_set(const zfs_tunable_t *tunable,
|
||||
const char *val);
|
||||
_SYS_TUNABLES_H int zfs_tunable_get(const zfs_tunable_t *tunable, char *val,
|
||||
size_t valsz);
|
||||
|
||||
const zfs_tunable_t *zfs_tunable_lookup(const char *name);
|
||||
_SYS_TUNABLES_H const zfs_tunable_t *zfs_tunable_lookup(const char *name);
|
||||
|
||||
typedef int (*zfs_tunable_iter_t)(const zfs_tunable_t *tunable, void *arg);
|
||||
void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
|
||||
_SYS_TUNABLES_H void zfs_tunable_iter(zfs_tunable_iter_t cb, void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,4 +50,8 @@ typedef int projid_t;
|
||||
|
||||
#include <sys/param.h> /* for NBBY */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
typedef off_t loff_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,36 @@
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_VNODE_H
|
||||
#define _LIBSPL_SYS_VNODE_H
|
||||
#ifndef _SYS_VNODE_H
|
||||
#define _SYS_VNODE_H
|
||||
|
||||
#endif /* _LIBSPL_SYS_VNODE_H */
|
||||
typedef struct vattr {
|
||||
uint_t va_mask; /* bit-mask of attributes */
|
||||
u_offset_t va_size; /* file size in bytes */
|
||||
} vattr_t;
|
||||
|
||||
#define AT_MODE 0x00002
|
||||
#define AT_UID 0x00004
|
||||
#define AT_GID 0x00008
|
||||
#define AT_FSID 0x00010
|
||||
#define AT_NODEID 0x00020
|
||||
#define AT_NLINK 0x00040
|
||||
#define AT_SIZE 0x00080
|
||||
#define AT_ATIME 0x00100
|
||||
#define AT_MTIME 0x00200
|
||||
#define AT_CTIME 0x00400
|
||||
#define AT_RDEV 0x00800
|
||||
#define AT_BLKSIZE 0x01000
|
||||
#define AT_NBLOCKS 0x02000
|
||||
#define AT_SEQ 0x08000
|
||||
#define AT_XVATTR 0x10000
|
||||
|
||||
#define ATTR_XVATTR AT_XVATTR
|
||||
|
||||
#define CRCREAT 0
|
||||
|
||||
#define F_FREESP 11
|
||||
#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
|
||||
|
||||
|
||||
#endif /* _SYS_VNODE_H */
|
||||
|
||||
@@ -21,11 +21,19 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_SYS_ZONE_H
|
||||
#define _LIBSPL_SYS_ZONE_H
|
||||
#ifndef _SYS_ZONE_H
|
||||
#define _SYS_ZONE_H
|
||||
|
||||
#endif
|
||||
#define zone_dataset_visible(x, y) (1)
|
||||
|
||||
#define INGLOBALZONE(z) (1)
|
||||
|
||||
extern uint32_t zone_get_hostid(void *zonep);
|
||||
|
||||
#endif /* _SYS_ZONE_H */
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/kmem.h>
|
||||
|
||||
char *
|
||||
kmem_vasprintf(const char *fmt, va_list adx)
|
||||
{
|
||||
char *buf = NULL;
|
||||
va_list adx_copy;
|
||||
|
||||
va_copy(adx_copy, adx);
|
||||
VERIFY(vasprintf(&buf, fmt, adx_copy) != -1);
|
||||
va_end(adx_copy);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
kmem_asprintf(const char *fmt, ...)
|
||||
{
|
||||
char *buf = NULL;
|
||||
va_list adx;
|
||||
|
||||
va_start(adx, fmt);
|
||||
VERIFY(vasprintf(&buf, fmt, adx) != -1);
|
||||
va_end(adx);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* kmem_scnprintf() will return the number of characters that it would have
|
||||
* printed whenever it is limited by value of the size variable, rather than
|
||||
* the number of characters that it did print. This can cause misbehavior on
|
||||
* subsequent uses of the return value, so we define a safe version that will
|
||||
* return the number of characters actually printed, minus the NULL format
|
||||
* character. Subsequent use of this by the safe string functions is safe
|
||||
* whether it is snprintf(), strlcat() or strlcpy().
|
||||
*/
|
||||
int
|
||||
kmem_scnprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
|
||||
/* Make the 0 case a no-op so that we do not return -1 */
|
||||
if (size == 0)
|
||||
return (0);
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(str, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n >= size)
|
||||
n = size - 1;
|
||||
|
||||
return (n);
|
||||
}
|
||||
|
||||
fstrans_cookie_t
|
||||
spl_fstrans_mark(void)
|
||||
{
|
||||
return ((fstrans_cookie_t)0);
|
||||
}
|
||||
|
||||
void
|
||||
spl_fstrans_unmark(fstrans_cookie_t cookie)
|
||||
{
|
||||
(void) cookie;
|
||||
}
|
||||
|
||||
int
|
||||
kmem_cache_reap_active(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/kstat.h>
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* kstats
|
||||
* =========================================================================
|
||||
*/
|
||||
kstat_t *
|
||||
kstat_create(const char *module, int instance, const char *name,
|
||||
const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
|
||||
{
|
||||
(void) module, (void) instance, (void) name, (void) class, (void) type,
|
||||
(void) ndata, (void) ks_flag;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
kstat_install(kstat_t *ksp)
|
||||
{
|
||||
(void) ksp;
|
||||
}
|
||||
|
||||
void
|
||||
kstat_delete(kstat_t *ksp)
|
||||
{
|
||||
(void) ksp;
|
||||
}
|
||||
|
||||
void
|
||||
kstat_set_raw_ops(kstat_t *ksp,
|
||||
int (*headers)(char *buf, size_t size),
|
||||
int (*data)(char *buf, size_t size, void *data),
|
||||
void *(*addr)(kstat_t *ksp, loff_t index))
|
||||
{
|
||||
(void) ksp, (void) headers, (void) data, (void) addr;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#include <libspl.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/misc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/utsname.h>
|
||||
#include "libspl_impl.h"
|
||||
|
||||
static uint64_t hw_physmem = 0;
|
||||
static struct utsname hw_utsname = {};
|
||||
|
||||
uint64_t
|
||||
libspl_physmem(void)
|
||||
{
|
||||
return (hw_physmem);
|
||||
}
|
||||
|
||||
utsname_t *
|
||||
utsname(void)
|
||||
{
|
||||
return (&hw_utsname);
|
||||
}
|
||||
|
||||
void
|
||||
libspl_init(void)
|
||||
{
|
||||
hw_physmem = sysconf(_SC_PHYS_PAGES);
|
||||
|
||||
VERIFY0(uname(&hw_utsname));
|
||||
|
||||
random_init();
|
||||
}
|
||||
|
||||
void
|
||||
libspl_fini(void)
|
||||
{
|
||||
random_fini();
|
||||
}
|
||||
@@ -21,5 +21,12 @@
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
#ifndef _LIBSPL_IMPL_H
|
||||
#define _LIBSPL_IMPL_H
|
||||
|
||||
extern ssize_t getexecname_impl(char *execname);
|
||||
|
||||
extern void random_init(void);
|
||||
extern void random_fini(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* mutexes
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
mutex_init(kmutex_t *mp, char *name, int type, void *cookie)
|
||||
{
|
||||
(void) name, (void) type, (void) cookie;
|
||||
VERIFY0(pthread_mutex_init(&mp->m_lock, NULL));
|
||||
memset(&mp->m_owner, 0, sizeof (pthread_t));
|
||||
}
|
||||
|
||||
void
|
||||
mutex_destroy(kmutex_t *mp)
|
||||
{
|
||||
VERIFY0(pthread_mutex_destroy(&mp->m_lock));
|
||||
}
|
||||
|
||||
void
|
||||
mutex_enter(kmutex_t *mp)
|
||||
{
|
||||
VERIFY0(pthread_mutex_lock(&mp->m_lock));
|
||||
mp->m_owner = pthread_self();
|
||||
}
|
||||
|
||||
int
|
||||
mutex_enter_check_return(kmutex_t *mp)
|
||||
{
|
||||
int error = pthread_mutex_lock(&mp->m_lock);
|
||||
if (error == 0)
|
||||
mp->m_owner = pthread_self();
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
mutex_tryenter(kmutex_t *mp)
|
||||
{
|
||||
int error = pthread_mutex_trylock(&mp->m_lock);
|
||||
if (error == 0) {
|
||||
mp->m_owner = pthread_self();
|
||||
return (1);
|
||||
} else {
|
||||
VERIFY3S(error, ==, EBUSY);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutex_exit(kmutex_t *mp)
|
||||
{
|
||||
memset(&mp->m_owner, 0, sizeof (pthread_t));
|
||||
VERIFY0(pthread_mutex_unlock(&mp->m_lock));
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/procfs_list.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/list.h>
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* procfs list
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
seq_printf(struct seq_file *m, const char *fmt, ...)
|
||||
{
|
||||
(void) m, (void) fmt;
|
||||
}
|
||||
|
||||
void
|
||||
procfs_list_install(const char *module,
|
||||
const char *submodule,
|
||||
const char *name,
|
||||
mode_t mode,
|
||||
procfs_list_t *procfs_list,
|
||||
int (*show)(struct seq_file *f, void *p),
|
||||
int (*show_header)(struct seq_file *f),
|
||||
int (*clear)(procfs_list_t *procfs_list),
|
||||
size_t procfs_list_node_off)
|
||||
{
|
||||
(void) module, (void) submodule, (void) name, (void) mode, (void) show,
|
||||
(void) show_header, (void) clear;
|
||||
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
|
||||
list_create(&procfs_list->pl_list,
|
||||
procfs_list_node_off + sizeof (procfs_list_node_t),
|
||||
procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
|
||||
procfs_list->pl_next_id = 1;
|
||||
procfs_list->pl_node_offset = procfs_list_node_off;
|
||||
}
|
||||
|
||||
void
|
||||
procfs_list_uninstall(procfs_list_t *procfs_list)
|
||||
{
|
||||
(void) procfs_list;
|
||||
}
|
||||
|
||||
void
|
||||
procfs_list_destroy(procfs_list_t *procfs_list)
|
||||
{
|
||||
ASSERT(list_is_empty(&procfs_list->pl_list));
|
||||
list_destroy(&procfs_list->pl_list);
|
||||
mutex_destroy(&procfs_list->pl_lock);
|
||||
}
|
||||
|
||||
#define NODE_ID(procfs_list, obj) \
|
||||
(((procfs_list_node_t *)(((char *)obj) + \
|
||||
(procfs_list)->pl_node_offset))->pln_id)
|
||||
|
||||
void
|
||||
procfs_list_add(procfs_list_t *procfs_list, void *p)
|
||||
{
|
||||
ASSERT(MUTEX_HELD(&procfs_list->pl_lock));
|
||||
NODE_ID(procfs_list, p) = procfs_list->pl_next_id++;
|
||||
list_insert_tail(&procfs_list->pl_list, p);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <sys/random.h>
|
||||
#include "libspl_impl.h"
|
||||
|
||||
#define RANDOM_PATH "/dev/random"
|
||||
#define URANDOM_PATH "/dev/urandom"
|
||||
|
||||
static int random_fd = -1, urandom_fd = -1;
|
||||
|
||||
static boolean_t force_pseudo = B_FALSE;
|
||||
|
||||
void
|
||||
random_init(void)
|
||||
{
|
||||
/* Handle multiple calls. */
|
||||
if (random_fd != -1) {
|
||||
ASSERT3U(urandom_fd, !=, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
VERIFY((random_fd = open(RANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
|
||||
VERIFY((urandom_fd = open(URANDOM_PATH, O_RDONLY | O_CLOEXEC)) != -1);
|
||||
}
|
||||
|
||||
void
|
||||
random_fini(void)
|
||||
{
|
||||
close(random_fd);
|
||||
close(urandom_fd);
|
||||
|
||||
random_fd = -1;
|
||||
urandom_fd = -1;
|
||||
}
|
||||
|
||||
void
|
||||
random_force_pseudo(boolean_t onoff)
|
||||
{
|
||||
force_pseudo = onoff;
|
||||
}
|
||||
|
||||
static int
|
||||
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
|
||||
{
|
||||
size_t resid = len;
|
||||
ssize_t bytes;
|
||||
|
||||
ASSERT(fd != -1);
|
||||
|
||||
while (resid != 0) {
|
||||
bytes = read(fd, ptr, resid);
|
||||
ASSERT3S(bytes, >=, 0);
|
||||
ptr += bytes;
|
||||
resid -= bytes;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
random_get_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
if (force_pseudo)
|
||||
return (random_get_pseudo_bytes(ptr, len));
|
||||
return (random_get_bytes_common(ptr, len, random_fd));
|
||||
}
|
||||
|
||||
int
|
||||
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
||||
{
|
||||
return (random_get_bytes_common(ptr, len, urandom_fd));
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <atomic.h>
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* rwlocks
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
void
|
||||
rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
|
||||
{
|
||||
(void) name, (void) type, (void) arg;
|
||||
VERIFY0(pthread_rwlock_init(&rwlp->rw_lock, NULL));
|
||||
rwlp->rw_readers = 0;
|
||||
rwlp->rw_owner = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rw_destroy(krwlock_t *rwlp)
|
||||
{
|
||||
VERIFY0(pthread_rwlock_destroy(&rwlp->rw_lock));
|
||||
}
|
||||
|
||||
void
|
||||
rw_enter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
if (rw == RW_READER) {
|
||||
VERIFY0(pthread_rwlock_rdlock(&rwlp->rw_lock));
|
||||
atomic_inc_uint(&rwlp->rw_readers);
|
||||
} else {
|
||||
VERIFY0(pthread_rwlock_wrlock(&rwlp->rw_lock));
|
||||
rwlp->rw_owner = pthread_self();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rw_exit(krwlock_t *rwlp)
|
||||
{
|
||||
if (RW_READ_HELD(rwlp))
|
||||
atomic_dec_uint(&rwlp->rw_readers);
|
||||
else
|
||||
rwlp->rw_owner = 0;
|
||||
|
||||
VERIFY0(pthread_rwlock_unlock(&rwlp->rw_lock));
|
||||
}
|
||||
|
||||
int
|
||||
rw_tryenter(krwlock_t *rwlp, krw_t rw)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (rw == RW_READER)
|
||||
error = pthread_rwlock_tryrdlock(&rwlp->rw_lock);
|
||||
else
|
||||
error = pthread_rwlock_trywrlock(&rwlp->rw_lock);
|
||||
|
||||
if (error == 0) {
|
||||
if (rw == RW_READER)
|
||||
atomic_inc_uint(&rwlp->rw_readers);
|
||||
else
|
||||
rwlp->rw_owner = pthread_self();
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
VERIFY3S(error, ==, EBUSY);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rw_tryupgrade(krwlock_t *rwlp)
|
||||
{
|
||||
(void) rwlp;
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/sid.h>
|
||||
#include <umem.h>
|
||||
|
||||
ksiddomain_t *
|
||||
ksid_lookupdomain(const char *dom)
|
||||
{
|
||||
ksiddomain_t *kd;
|
||||
|
||||
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
|
||||
kd->kd_name = strdup(dom);
|
||||
return (kd);
|
||||
}
|
||||
|
||||
void
|
||||
ksiddomain_rele(ksiddomain_t *ksid)
|
||||
{
|
||||
free(ksid->kd_name);
|
||||
umem_free(ksid, sizeof (ksiddomain_t));
|
||||
}
|
||||
@@ -29,11 +29,27 @@
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/timer.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/thread.h>
|
||||
#include <sys/taskq.h>
|
||||
#include <sys/kmem.h>
|
||||
|
||||
int taskq_now;
|
||||
taskq_t *system_taskq;
|
||||
taskq_t *system_delay_taskq;
|
||||
static taskq_t *__system_taskq = NULL;
|
||||
static taskq_t *__system_delay_taskq = NULL;
|
||||
|
||||
taskq_t
|
||||
*_system_taskq(void)
|
||||
{
|
||||
return (__system_taskq);
|
||||
}
|
||||
|
||||
taskq_t
|
||||
*_system_delay_taskq(void)
|
||||
{
|
||||
return (__system_delay_taskq);
|
||||
}
|
||||
|
||||
static pthread_key_t taskq_tsd;
|
||||
|
||||
@@ -106,11 +122,6 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
|
||||
{
|
||||
taskq_ent_t *t;
|
||||
|
||||
if (taskq_now) {
|
||||
func(arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
mutex_enter(&tq->tq_lock);
|
||||
ASSERT(tq->tq_flags & TASKQ_ACTIVE);
|
||||
if ((t = task_alloc(tq, tqflags)) == NULL) {
|
||||
@@ -373,9 +384,6 @@ taskq_member(taskq_t *tq, kthread_t *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (taskq_now)
|
||||
return (1);
|
||||
|
||||
for (i = 0; i < tq->tq_nthreads; i++)
|
||||
if (tq->tq_threadlist[i] == t)
|
||||
return (1);
|
||||
@@ -400,18 +408,18 @@ void
|
||||
system_taskq_init(void)
|
||||
{
|
||||
VERIFY0(pthread_key_create(&taskq_tsd, NULL));
|
||||
system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512,
|
||||
__system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512,
|
||||
TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
|
||||
system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4,
|
||||
__system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4,
|
||||
512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE);
|
||||
}
|
||||
|
||||
void
|
||||
system_taskq_fini(void)
|
||||
{
|
||||
taskq_destroy(system_taskq);
|
||||
system_taskq = NULL; /* defensive */
|
||||
taskq_destroy(system_delay_taskq);
|
||||
system_delay_taskq = NULL;
|
||||
taskq_destroy(__system_taskq);
|
||||
__system_taskq = NULL; /* defensive */
|
||||
taskq_destroy(__system_delay_taskq);
|
||||
__system_delay_taskq = NULL;
|
||||
VERIFY0(pthread_key_delete(taskq_tsd));
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// SPDX-License-Identifier: CDDL-1.0
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <sys/thread.h>
|
||||
|
||||
/* this only exists to have its address taken */
|
||||
void p0(void) {}
|
||||
|
||||
/*
|
||||
* =========================================================================
|
||||
* threads
|
||||
* =========================================================================
|
||||
*
|
||||
* TS_STACK_MIN is dictated by the minimum allowed pthread stack size. While
|
||||
* TS_STACK_MAX is somewhat arbitrary, it was selected to be large enough for
|
||||
* the expected stack depth while small enough to avoid exhausting address
|
||||
* space with high thread counts.
|
||||
*/
|
||||
#define TS_STACK_MIN MAX(PTHREAD_STACK_MIN, 32768)
|
||||
#define TS_STACK_MAX (256 * 1024)
|
||||
|
||||
struct zk_thread_wrapper {
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void *
|
||||
zk_thread_wrapper(void *arg)
|
||||
{
|
||||
struct zk_thread_wrapper ztw;
|
||||
memcpy(&ztw, arg, sizeof (ztw));
|
||||
free(arg);
|
||||
ztw.func(ztw.arg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
kthread_t *
|
||||
zk_thread_create(const char *name, void (*func)(void *), void *arg,
|
||||
size_t stksize, int state)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_t tid;
|
||||
char *stkstr;
|
||||
struct zk_thread_wrapper *ztw;
|
||||
int detachstate = PTHREAD_CREATE_DETACHED;
|
||||
|
||||
VERIFY0(pthread_attr_init(&attr));
|
||||
|
||||
if (state & TS_JOINABLE)
|
||||
detachstate = PTHREAD_CREATE_JOINABLE;
|
||||
|
||||
VERIFY0(pthread_attr_setdetachstate(&attr, detachstate));
|
||||
|
||||
/*
|
||||
* We allow the default stack size in user space to be specified by
|
||||
* setting the ZFS_STACK_SIZE environment variable. This allows us
|
||||
* the convenience of observing and debugging stack overruns in
|
||||
* user space. Explicitly specified stack sizes will be honored.
|
||||
* The usage of ZFS_STACK_SIZE is discussed further in the
|
||||
* ENVIRONMENT VARIABLES sections of the ztest(1) man page.
|
||||
*/
|
||||
if (stksize == 0) {
|
||||
stkstr = getenv("ZFS_STACK_SIZE");
|
||||
|
||||
if (stkstr == NULL)
|
||||
stksize = TS_STACK_MAX;
|
||||
else
|
||||
stksize = MAX(atoi(stkstr), TS_STACK_MIN);
|
||||
}
|
||||
|
||||
VERIFY3S(stksize, >, 0);
|
||||
stksize = P2ROUNDUP(MAX(stksize, TS_STACK_MIN), PAGESIZE);
|
||||
|
||||
/*
|
||||
* If this ever fails, it may be because the stack size is not a
|
||||
* multiple of system page size.
|
||||
*/
|
||||
VERIFY0(pthread_attr_setstacksize(&attr, stksize));
|
||||
VERIFY0(pthread_attr_setguardsize(&attr, PAGESIZE));
|
||||
|
||||
VERIFY(ztw = malloc(sizeof (*ztw)));
|
||||
ztw->func = func;
|
||||
ztw->arg = arg;
|
||||
VERIFY0(pthread_create(&tid, &attr, zk_thread_wrapper, ztw));
|
||||
VERIFY0(pthread_attr_destroy(&attr));
|
||||
|
||||
pthread_setname_np(tid, name);
|
||||
|
||||
return ((void *)(uintptr_t)tid);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,7 +70,7 @@ if BUILD_FREEBSD
|
||||
libzfs_la_LIBADD += -lutil -lgeom
|
||||
endif
|
||||
|
||||
libzfs_la_LDFLAGS += -version-info 6:0:0
|
||||
libzfs_la_LDFLAGS += -version-info 7:0:0
|
||||
|
||||
pkgconfig_DATA += %D%/libzfs.pc
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user