Make dbufstat work on FreeBSD

With procfs_list kstats implemented for FreeBSD, dbufs are now exposed
as kstat.zfs.misc.dbufs.

On FreeBSD, dbufstats can use the sysctl instead of procfs when no
input file has been given.

Enable the dbufstats tests on FreeBSD.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org>
Closes #11008
This commit is contained in:
Ryan Moeller 2020-10-08 12:40:23 -04:00 committed by Brian Behlendorf
parent 718d20ed93
commit 25e44a17ff
7 changed files with 56 additions and 16 deletions

View File

@ -113,6 +113,21 @@ cmd = ("Usage: dbufstat [-bdhnrtvx] [-i file] [-f fields] [-o file] "
raw = 0 raw = 0
if sys.platform.startswith("freebsd"):
import io
# Requires py-sysctl on FreeBSD
import sysctl
def default_ifile():
dbufs = sysctl.filter("kstat.zfs.misc.dbufs")[0].value
sys.stdin = io.StringIO(dbufs)
return "-"
elif sys.platform.startswith("linux"):
def default_ifile():
return "/proc/spl/kstat/zfs/dbufs"
def print_incompat_helper(incompat): def print_incompat_helper(incompat):
cnt = 0 cnt = 0
for key in sorted(incompat): for key in sorted(incompat):
@ -645,7 +660,7 @@ def main():
sys.exit(1) sys.exit(1)
if not ifile: if not ifile:
ifile = '/proc/spl/kstat/zfs/dbufs' ifile = default_ifile()
if ifile is not "-": if ifile is not "-":
try: try:

View File

@ -231,6 +231,7 @@ restart:
} }
free(ksp->ks_raw_buf, M_TEMP); free(ksp->ks_raw_buf, M_TEMP);
mutex_exit(ksp->ks_lock); mutex_exit(ksp->ks_lock);
sbuf_trim(sb);
rc = sbuf_finish(sb); rc = sbuf_finish(sb);
if (rc == 0) if (rc == 0)
rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb)); rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));

View File

@ -30,6 +30,11 @@ tests = ['alloc_class_001_pos', 'alloc_class_002_neg', 'alloc_class_003_pos',
'alloc_class_013_pos'] 'alloc_class_013_pos']
tags = ['functional', 'alloc_class'] tags = ['functional', 'alloc_class']
[tests/functional/arc]
tests = ['dbufstats_001_pos', 'dbufstats_002_pos', 'dbufstats_003_pos',
'arcstats_runtime_tuning']
tags = ['functional', 'arc']
[tests/functional/atime] [tests/functional/atime]
tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on'] tests = ['atime_001_pos', 'atime_002_neg', 'root_atime_off', 'root_atime_on']
tags = ['functional', 'atime'] tags = ['functional', 'atime']

View File

@ -26,11 +26,6 @@ tags = ['functional']
tests = ['posix_001_pos', 'posix_002_pos', 'posix_003_pos'] tests = ['posix_001_pos', 'posix_002_pos', 'posix_003_pos']
tags = ['functional', 'acl', 'posix'] tags = ['functional', 'acl', 'posix']
[tests/functional/arc:Linux]
tests = ['dbufstats_001_pos', 'dbufstats_002_pos', 'dbufstats_003_pos',
'arcstats_runtime_tuning']
tags = ['functional', 'arc']
[tests/functional/atime:Linux] [tests/functional/atime:Linux]
tests = ['atime_003_pos', 'root_relatime_on'] tests = ['atime_003_pos', 'root_relatime_on']
tags = ['functional', 'atime'] tags = ['functional', 'atime']

View File

@ -4154,18 +4154,36 @@ function ls_xattr # path
esac esac
} }
function kstat # stat flags?
{
typeset stat=$1
typeset flags=${2-"-n"}
case $(uname) in
FreeBSD)
sysctl $flags kstat.zfs.misc.$stat
;;
Linux)
typeset zfs_kstat="/proc/spl/kstat/zfs/$stat"
[[ -f "$zfs_kstat" ]] || return 1
cat $zfs_kstat
;;
*)
false
;;
esac
}
function get_arcstat # stat function get_arcstat # stat
{ {
typeset stat=$1 typeset stat=$1
case $(uname) in case $(uname) in
FreeBSD) FreeBSD)
sysctl -n kstat.zfs.misc.arcstats.$stat kstat arcstats.$stat
;; ;;
Linux) Linux)
typeset zfs_arcstats="/proc/spl/kstat/zfs/arcstats" kstat arcstats | awk "/$stat/ { print \$3 }"
[[ -f "$zfs_arcstats" ]] || return 1
grep $stat $zfs_arcstats | awk '{print $3}'
;; ;;
*) *)
false false

View File

@ -55,7 +55,13 @@ function testdbufstat # stat_name dbufstat_filter
[[ -n "$2" ]] && filter="-F $2" [[ -n "$2" ]] && filter="-F $2"
from_dbufstat=$(grep -w "$name" "$DBUFSTATS_FILE" | awk '{ print $3 }') if is_linux; then
from_dbufstat=$(grep -w "$name" "$DBUFSTATS_FILE" |
awk '{ print $3 }')
else
from_dbufstat=$(awk "/dbufstats\.$name:/ { print \$2 }" \
"$DBUFSTATS_FILE")
fi
from_dbufs=$(dbufstat -bxn -i "$DBUFS_FILE" "$filter" | wc -l) from_dbufs=$(dbufstat -bxn -i "$DBUFS_FILE" "$filter" | wc -l)
within_tolerance $from_dbufstat $from_dbufs 15 \ within_tolerance $from_dbufstat $from_dbufs 15 \
@ -71,8 +77,8 @@ log_onexit cleanup
log_must file_write -o create -f "$TESTDIR/file" -b 1048576 -c 20 -d R log_must file_write -o create -f "$TESTDIR/file" -b 1048576 -c 20 -d R
log_must zpool sync log_must zpool sync
log_must eval "cat /proc/spl/kstat/zfs/dbufs > $DBUFS_FILE" log_must eval "kstat dbufs > $DBUFS_FILE"
log_must eval "cat /proc/spl/kstat/zfs/dbufstats > $DBUFSTATS_FILE" log_must eval "kstat dbufstats '' > $DBUFSTATS_FILE"
for level in {0..11}; do for level in {0..11}; do
testdbufstat "cache_level_$level" "dbc=1,level=$level" testdbufstat "cache_level_$level" "dbc=1,level=$level"

View File

@ -58,10 +58,10 @@ log_onexit cleanup
log_must file_write -o create -f "$TESTDIR/file" -b 1048576 -c 1 -d R log_must file_write -o create -f "$TESTDIR/file" -b 1048576 -c 1 -d R
log_must zpool sync log_must zpool sync
objid=$(stat --format="%i" "$TESTDIR/file") objid=$(get_objnum "$TESTDIR/file")
log_note "Object ID for $TESTDIR/file is $objid" log_note "Object ID for $TESTDIR/file is $objid"
log_must eval "cat /proc/spl/kstat/zfs/dbufs > $DBUFS_FILE" log_must eval "kstat dbufs > $DBUFS_FILE"
dbuf=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid" | wc -l) dbuf=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid" | wc -l)
mru=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=1" | wc -l) mru=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=1" | wc -l)
mfu=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=3" | wc -l) mfu=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=3" | wc -l)
@ -70,7 +70,7 @@ verify_ne "0" "$mru" "mru count"
verify_eq "0" "$mfu" "mfu count" verify_eq "0" "$mfu" "mfu count"
log_must eval "cat $TESTDIR/file > /dev/null" log_must eval "cat $TESTDIR/file > /dev/null"
log_must eval "cat /proc/spl/kstat/zfs/dbufs > $DBUFS_FILE" log_must eval "kstat dbufs > $DBUFS_FILE"
dbuf=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid" | wc -l) dbuf=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid" | wc -l)
mru=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=1" | wc -l) mru=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=1" | wc -l)
mfu=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=3" | wc -l) mfu=$(dbufstat -bxn -i "$DBUFS_FILE" -F "object=$objid,list=3" | wc -l)