diff options
| author | Gordon Ross <gwr@nexenta.com> | 2017-07-21 16:37:02 -0400 |
|---|---|---|
| committer | Gordon Ross <gwr@nexenta.com> | 2019-06-08 20:48:57 -0400 |
| commit | 94047d49916b669576decf2f622a1ee718646882 (patch) | |
| tree | 6b446f44e97da3deccef4504c5f8bd82f14a35c8 /usr/src/cmd/smbsrv | |
| parent | 148d1a4158dc830f7b293a2ceb62ee54c2ebd72f (diff) | |
| download | illumos-joyent-94047d49916b669576decf2f622a1ee718646882.tar.gz | |
11016 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/cmd/smbsrv')
36 files changed, 2145 insertions, 2 deletions
diff --git a/usr/src/cmd/smbsrv/Makefile b/usr/src/cmd/smbsrv/Makefile index 193ce84c88..8e7699c252 100644 --- a/usr/src/cmd/smbsrv/Makefile +++ b/usr/src/cmd/smbsrv/Makefile @@ -22,11 +22,11 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2013 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. # SUBDIRS = smbadm smbd smbstat dtrace fksmbd bind-helper \ - test-msgbuf + test-msgbuf testoplock MSGSUBDIRS = smbadm smbstat include ../Makefile.cmd diff --git a/usr/src/cmd/smbsrv/testoplock/.dbxrc b/usr/src/cmd/smbsrv/testoplock/.dbxrc new file mode 100644 index 0000000000..92f30a38f7 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/.dbxrc @@ -0,0 +1,23 @@ + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. +# + +set -o emacs + +# testoplock is always 32-bit +setenv LD_LIBRARY_PATH ${ROOT}/usr/lib/smbsrv:${ROOT}/usr/lib:${ROOT}/lib + +echo 'Do one of: attach ${PID}' +echo 'or: debug ${ROOT}/usr/lib/smbsrv/testoplock' diff --git a/usr/src/cmd/smbsrv/testoplock/Makefile b/usr/src/cmd/smbsrv/testoplock/Makefile new file mode 100644 index 0000000000..12fcbd0ac9 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/Makefile @@ -0,0 +1,121 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2018 Nexenta Systems, Inc. All rights reserved. +# + + +PROG= testoplock + +OBJS_LOCAL= tol_main.o tol_misc.o +OBJS_SMBSRV= smb_cmn_oplock.o +OBJS_LIBSMB= smb_status_tbl.o + +OBJS= ${OBJS_LOCAL} ${OBJS_SMBSRV} ${OBJS_LIBSMB} + +SMBSRV_SRCDIR=../../../uts/common/fs/smbsrv +SRCS= ${OBJS_LOCAL:.o=.c} \ + ${OBJS_SMBSRV:%.o=${SMBSRV_SRCDIR}/%.c} + +include ../../Makefile.cmd +include ../../Makefile.ctf + +# Note: need our sys includes _before_ ENVCPPFLAGS, proto etc. +CPPFLAGS.first += -I. +CPPFLAGS.first += -I../../../lib/libfakekernel/common +CPPFLAGS.first += -I../../../lib/smbsrv/libfksmbsrv/common + +INCS += -I../../../uts/common + +CSTD= $(CSTD_GNU99) + +CFLAGS += $(CCVERBOSE) +CFLAGS64 += $(CCVERBOSE) + +CPPFLAGS.master=$(DTEXTDOM) $(DTS_ERRNO) + +# CPPFLAGS is deliberatly set with a "=" and not a "+="... +CPPFLAGS= $(CPPFLAGS.first) $(CPPFLAGS.master) + +CPPFLAGS += -D_REENTRANT +CPPFLAGS += -DTESTJIG +CPPFLAGS += -Dsyslog=smb_syslog +CPPFLAGS += -D_LARGEFILE64_SOURCE=1 +# Always debug here +CPPFLAGS += -DDEBUG +CPPFLAGS += $(INCS) + +LDFLAGS += $(ZNOLAZYLOAD) +LDFLAGS += '-R$$ORIGIN/..' +LDLIBS += -lfakekernel -lcmdutils + +LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 +LINTFLAGS += -xerroff=E_NAME_USED_NOT_DEF2 +LINTFLAGS += -xerroff=E_INCONS_ARG_DECL2 +LINTFLAGS += -xerroff=E_INCONS_VAL_TYPE_DECL2 + +ROOTSMBDDIR = $(ROOTLIB)/smbsrv +ROOTSMBDFILE = $(PROG:%=$(ROOTSMBDDIR)/%) + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +clean: + -$(RM) $(OBJS) + +lint: # lint_SRCS + +include ../../Makefile.targ + +install: all $(ROOTSMBDFILE) + + +tol_main.o : tol_main.c + $(CC) $(CFLAGS) $(CPPFLAGS) -D_KMEMUSER -c tol_main.c + $(POST_PROCESS_O) + +tol_misc.o : tol_misc.c + $(CC) $(CFLAGS) $(CPPFLAGS) -D_FAKE_KERNEL \ + -I../../../uts/common/smbsrv \ + -I../../../common/smbsrv -c tol_misc.c + $(POST_PROCESS_O) + +# OBJS_SMBSRV +%.o: ../../../uts/common/fs/smbsrv/%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -D_FAKE_KERNEL \ + -I../../../uts/common/smbsrv \ + -I../../../common/smbsrv -c $< + $(POST_PROCESS_O) + +# OBJS_LIBSMB +%.o: ../../../lib/smbsrv/libsmb/common/%.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + $(POST_PROCESS_O) + + +$(ROOTSMBDDIR)/%: % + $(INS.file) diff --git a/usr/src/cmd/smbsrv/testoplock/Run-cmd.sh b/usr/src/cmd/smbsrv/testoplock/Run-cmd.sh new file mode 100755 index 0000000000..fa34046936 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/Run-cmd.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. +# + +# Helper program to run fksmbd (user-space smbd for debugging) +# using binaries from the proto area. + +[ -n "$ROOT" ] || { + echo "Need a bldenv to set ROOT=..." + exit 1; +} + +# OK, setup env. to run it. + +LD_LIBRARY_PATH=$ROOT/usr/lib:$ROOT/lib +export LD_LIBRARY_PATH + +# run with the passed options +exec $ROOT/usr/lib/smbsrv/testoplock "$@" diff --git a/usr/src/cmd/smbsrv/testoplock/Run-tests.sh b/usr/src/cmd/smbsrv/testoplock/Run-tests.sh new file mode 100755 index 0000000000..aa5174095b --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/Run-tests.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. +# + +# Helper program to run fksmbd (user-space smbd for debugging) +# using binaries from the proto area. + +[ -n "$ROOT" ] || { + echo "Need a bldenv to set ROOT=..." + exit 1; +} + +# OK, setup env. to run it. + +LD_LIBRARY_PATH=$ROOT/usr/lib:$ROOT/lib +export LD_LIBRARY_PATH + +TOL=$ROOT/usr/lib/smbsrv/testoplock + +TESTS=${@:-case??.txt} + +# run the test cases +for t in $TESTS +do + name=${t%.txt} + $TOL < $name.txt > $name.tmp + if diff -u $name.tmp $name.ref >/dev/null 2>&1 ; then + echo "$name PASS" + rm $name.tmp + else + echo "$name FAIL" + diff -u $name.tmp $name.ref + fi +done diff --git a/usr/src/cmd/smbsrv/testoplock/case01.ref b/usr/src/cmd/smbsrv/testoplock/case01.ref new file mode 100644 index 0000000000..6327c46b7e --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case01.ref @@ -0,0 +1,29 @@ +open 1 + open 1 OK +req 1 + req oplock fid=1 ret oplock=0x400 status=0x0 (SUCCESS) +show + ol_state=0x410 ( BATCH_OPLOCK EXCLUSIVE ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x400 Brk=0x0 Excl=Y onlist: +brk-open 2 +*smb_oplock_ind_break fid=1 NewLevel=0x100, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 2 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +show + ol_state=0x100410 ( BREAK_TO_TWO BATCH_OPLOCK EXCLUSIVE ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x400 Brk=0x100000 Excl=Y onlist: +ack 1 + ack: break fid=1, newstate=0x100, status=0x0 (SUCCESS) +open 2 + open 2 OK +req 2 0x100 + req oplock fid=2 ret oplock=0x100 status=0x0 (SUCCESS) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=2 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II + fid=2 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II diff --git a/usr/src/cmd/smbsrv/testoplock/case01.txt b/usr/src/cmd/smbsrv/testoplock/case01.txt new file mode 100644 index 0000000000..58eaa7f4b1 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case01.txt @@ -0,0 +1,10 @@ +# Input for testoplock, case 01 +open 1 +req 1 +show +brk-open 2 +show +ack 1 +open 2 +req 2 0x100 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case02.ref b/usr/src/cmd/smbsrv/testoplock/case02.ref new file mode 100644 index 0000000000..73488cbf27 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case02.ref @@ -0,0 +1,29 @@ +open 1 + open 1 OK +req 1 0x807 + req oplock fid=1 ret oplock=0x807 status=0x0 (SUCCESS) +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x807 Brk=0x0 Excl=Y onlist: +brk-open 2 +*smb_oplock_ind_break fid=1 NewLevel=0x3, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 2 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +show + ol_state=0x30017 ( BREAK_TO_HANDLE_CACHING BREAK_TO_READ_CACHING EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x807 Brk=0x30000 Excl=Y onlist: +ack 1 + ack: break fid=1, newstate=0x803, status=0x0 (SUCCESS) +open 2 + open 2 OK +req 2 0x803 + req oplock fid=2 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=2 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=2 Lease= OgState=0x803 Brk=0x0 Excl=N onlist: RH diff --git a/usr/src/cmd/smbsrv/testoplock/case02.txt b/usr/src/cmd/smbsrv/testoplock/case02.txt new file mode 100644 index 0000000000..996d41e75f --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case02.txt @@ -0,0 +1,10 @@ +# Input for testoplock, case 02 +open 1 +req 1 0x807 +show +brk-open 2 +show +ack 1 +open 2 +req 2 0x803 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case03.ref b/usr/src/cmd/smbsrv/testoplock/case03.ref new file mode 100644 index 0000000000..cdc7fe0089 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case03.ref @@ -0,0 +1,20 @@ +open 1 3 + open 1 OK +req 1 0x803 + req oplock fid=1 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=3 OgState=0x803 Brk=0x0 Excl=N onlist: RH +open 2 3 + open 2 OK +req 2 0x803 +*smb_oplock_ind_break fid=1 NewLevel=0x3, AckReq=0, ComplStatus=0x215 (OPLOCK_SWITCHED_TO_NEW_HANDLE) + req oplock fid=2 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=3 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=2 Lease=3 OgState=0x803 Brk=0x0 Excl=N onlist: RH diff --git a/usr/src/cmd/smbsrv/testoplock/case03.txt b/usr/src/cmd/smbsrv/testoplock/case03.txt new file mode 100644 index 0000000000..096936e0c7 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case03.txt @@ -0,0 +1,7 @@ +# Input for testoplock, case 03 +open 1 3 +req 1 0x803 +show +open 2 3 +req 2 0x803 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case04.ref b/usr/src/cmd/smbsrv/testoplock/case04.ref new file mode 100644 index 0000000000..32df3767a9 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case04.ref @@ -0,0 +1,20 @@ +open 1 3 + open 1 OK +req 1 0x801 + req oplock fid=1 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=3 OgState=0x801 Brk=0x0 Excl=N onlist: R +open 2 3 + open 2 OK +req 2 0x801 +*smb_oplock_ind_break fid=1 NewLevel=0x1, AckReq=0, ComplStatus=0x215 (OPLOCK_SWITCHED_TO_NEW_HANDLE) + req oplock fid=2 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=3 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=2 Lease=3 OgState=0x801 Brk=0x0 Excl=N onlist: R diff --git a/usr/src/cmd/smbsrv/testoplock/case04.txt b/usr/src/cmd/smbsrv/testoplock/case04.txt new file mode 100644 index 0000000000..c8316ea2d1 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case04.txt @@ -0,0 +1,7 @@ +# Input for testoplock, case 04 +open 1 3 +req 1 0x801 +show +open 2 3 +req 2 0x801 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case05.ref b/usr/src/cmd/smbsrv/testoplock/case05.ref new file mode 100644 index 0000000000..639bf0023b --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case05.ref @@ -0,0 +1,65 @@ +open 2 4 + open 2 OK +req 2 0x803 + req oplock fid=2 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=1 + fid=2 Lease=4 OgState=0x803 Brk=0x0 Excl=N onlist: RH +open 3 4 + open 3 OK +req 3 0x803 +*smb_oplock_ind_break fid=2 NewLevel=0x3, AckReq=0, ComplStatus=0x215 (OPLOCK_SWITCHED_TO_NEW_HANDLE) + req oplock fid=3 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=2 Lease=4 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease=4 OgState=0x803 Brk=0x0 Excl=N onlist: RH +open 1 + open 1 OK +brk-write 1 +*smb_oplock_ind_break fid=3 NewLevel=0x0, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-write 1 ret status=0x0 (SUCCESS) +show + ol_state=0x80003 ( BREAK_TO_NO_CACHING HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=1 + ofile_cnt=3 + fid=2 Lease=4 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease=4 OgState=0x803 Brk=0x80000 Excl=N onlist: RHBQ(to none) + fid=1 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +ack 3 + ack: break fid=3, newstate=0x800, status=0x0 (SUCCESS) +show + ol_state=0x10000000 ( NO_OPLOCK ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=3 + fid=2 Lease=4 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease=4 OgState=0x800 Brk=0x0 Excl=N onlist: + fid=1 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +open 4 4 + open 4 OK +req 4 0x803 + req oplock fid=4 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=4 + fid=2 Lease=4 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease=4 OgState=0x800 Brk=0x0 Excl=N onlist: + fid=1 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: + fid=4 Lease=4 OgState=0x803 Brk=0x0 Excl=N onlist: RH +close 4 +*smb_oplock_ind_break fid=4 NewLevel=0x0, AckReq=0, ComplStatus=0x216 (OPLOCK_HANDLE_CLOSED) + close OK +req 3 0x803 + req oplock fid=3 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=3 + fid=2 Lease=4 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease=4 OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=1 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case05.txt b/usr/src/cmd/smbsrv/testoplock/case05.txt new file mode 100644 index 0000000000..f22f67abea --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case05.txt @@ -0,0 +1,18 @@ +# Input for testoplock, case 05 +open 2 4 +req 2 0x803 +show +open 3 4 +req 3 0x803 +show +open 1 +brk-write 1 +show +ack 3 +show +open 4 4 +req 4 0x803 +show +close 4 +req 3 0x803 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case06.ref b/usr/src/cmd/smbsrv/testoplock/case06.ref new file mode 100644 index 0000000000..daa69c3dd1 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case06.ref @@ -0,0 +1,56 @@ +open 1 1 + open 1 OK +req 1 0x801 + req oplock fid=1 ret oplock=0x801 status=0x0 (SUCCESS) +open 2 2 + open 2 OK +req 2 0x801 + req oplock fid=2 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=2 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + fid=2 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R +brk-write 1 +*smb_oplock_ind_break fid=2 NewLevel=0x0, AckReq=0, ComplStatus=0x0 (SUCCESS) + brk-write 1 ret status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + fid=2 Lease=2 OgState=0x800 Brk=0x0 Excl=N onlist: +open 3 2 + open 3 OK +req 3 0x801 + req oplock fid=3 ret oplock=0x801 status=0x0 (SUCCESS) +close 3 +*smb_oplock_ind_break fid=3 NewLevel=0x0, AckReq=0, ComplStatus=0x216 (OPLOCK_HANDLE_CLOSED) + close OK +req 2 0x801 + req oplock fid=2 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=2 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + fid=2 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R +brk-write 2 +*smb_oplock_ind_break fid=1 NewLevel=0x0, AckReq=0, ComplStatus=0x0 (SUCCESS) + brk-write 2 ret status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x800 Brk=0x0 Excl=N onlist: + fid=2 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R +brk-write 1 +*smb_oplock_ind_break fid=2 NewLevel=0x0, AckReq=0, ComplStatus=0x0 (SUCCESS) + brk-write 1 ret status=0x0 (SUCCESS) +show + ol_state=0x10000000 ( NO_OPLOCK ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x800 Brk=0x0 Excl=N onlist: + fid=2 Lease=2 OgState=0x800 Brk=0x0 Excl=N onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case06.txt b/usr/src/cmd/smbsrv/testoplock/case06.txt new file mode 100644 index 0000000000..c4af8377d0 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case06.txt @@ -0,0 +1,24 @@ +# Input for testoplock, case 06 +# Modeled after smbtorture smb2.lease.nobreakself +open 1 1 +req 1 0x801 +open 2 2 +req 2 0x801 +# both 1,2 should have R +show +# write 1 should leave 1:R 2:none +brk-write 1 +show +# upgrade 2 back to R +open 3 2 +req 3 0x801 +close 3 +# ind_break will "move" the lease to h2 (1:R 2:R) +req 2 0x801 +show +# write 2 should leave 1:none 2:R +brk-write 2 +show +# write 1 should leave 1:none 2:none +brk-write 1 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case07.ref b/usr/src/cmd/smbsrv/testoplock/case07.ref new file mode 100644 index 0000000000..11b1fa415d --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case07.ref @@ -0,0 +1,20 @@ +open 1 3 + open 1 OK +req 1 0x803 + req oplock fid=1 ret oplock=0x803 status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=3 OgState=0x803 Brk=0x0 Excl=N onlist: RH +open 2 3 + open 2 OK +req 2 0x807 +*smb_oplock_ind_break fid=1 NewLevel=0x7, AckReq=0, ComplStatus=0x215 (OPLOCK_SWITCHED_TO_NEW_HANDLE) + req oplock fid=2 ret oplock=0x807 status=0x0 (SUCCESS) +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=2) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=3 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=2 Lease=3 OgState=0x807 Brk=0x0 Excl=Y onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case07.txt b/usr/src/cmd/smbsrv/testoplock/case07.txt new file mode 100644 index 0000000000..56d90a0d7a --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case07.txt @@ -0,0 +1,8 @@ +# Input for testoplock, case 07 +# Modeled after smbtorture smb2.lease.upgrade +open 1 3 +req 1 0x803 +show +open 2 3 +req 2 0x807 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case08.ref b/usr/src/cmd/smbsrv/testoplock/case08.ref new file mode 100644 index 0000000000..7f28032990 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case08.ref @@ -0,0 +1,36 @@ +open 1 1 + open 1 OK +req 1 0x805 + req oplock fid=1 ret oplock=0x805 status=0x0 (SUCCESS) +show + ol_state=0x15 ( EXCLUSIVE WRITE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=1 OgState=0x805 Brk=0x0 Excl=Y onlist: +open 2 2 + open 2 OK +brk-open 2 +*smb_oplock_ind_break fid=1 NewLevel=0x1, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 2 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +show + ol_state=0x10015 ( BREAK_TO_READ_CACHING EXCLUSIVE WRITE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x805 Brk=0x10000 Excl=Y onlist: + fid=2 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: +ack 1 + ack: break fid=1, newstate=0x801, status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + fid=2 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: +req 2 0x801 + req oplock fid=2 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=2 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + fid=2 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R diff --git a/usr/src/cmd/smbsrv/testoplock/case08.txt b/usr/src/cmd/smbsrv/testoplock/case08.txt new file mode 100644 index 0000000000..ccc8f48711 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case08.txt @@ -0,0 +1,13 @@ +# Input for testoplock, case 08 +# Modeled after smbtorture smb2.lease.upgrade3 +# sub-case: "R" "RH" "RW" "R" +open 1 1 +req 1 0x805 +show +open 2 2 +brk-open 2 +show +ack 1 +show +req 2 0x801 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case09.ref b/usr/src/cmd/smbsrv/testoplock/case09.ref new file mode 100644 index 0000000000..4003b133db --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case09.ref @@ -0,0 +1,27 @@ +open 1 + open 1 OK +req 1 0x100 + req oplock fid=1 ret oplock=0x100 status=0x0 (SUCCESS) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=1 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II +open 2 2 + open 2 OK +brk-open 2 + brk-open 2 ret status=0x0 (SUCCESS) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=1 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II + fid=2 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: +req 2 0x803 + req oplock fid=2 ret oplock=0x0 status=0xc00000e2 (OPLOCK_NOT_GRANTED) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=1 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II + fid=2 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case09.txt b/usr/src/cmd/smbsrv/testoplock/case09.txt new file mode 100644 index 0000000000..3683d3d83f --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case09.txt @@ -0,0 +1,10 @@ +# Input for testoplock, case 09 +# Modeled after smbtorture smb2.lease.oplock +open 1 +req 1 0x100 +show +open 2 2 +brk-open 2 +show +req 2 0x803 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case10.ref b/usr/src/cmd/smbsrv/testoplock/case10.ref new file mode 100644 index 0000000000..9e0275d258 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case10.ref @@ -0,0 +1,31 @@ +open 1 + open 1 OK +req 1 0x100 + req oplock fid=1 ret oplock=0x100 status=0x0 (SUCCESS) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=1 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II +open 2 2 + open 2 OK +brk-open 2 + brk-open 2 ret status=0x0 (SUCCESS) +show + ol_state=0x100 ( LEVEL_TWO_OPLOCK ) + Excl=n cnt_II=1 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II + fid=2 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: +req 2 0x807 + req oplock fid=2 ret oplock=0x0 status=0xc00000e2 (OPLOCK_NOT_GRANTED) +req 2 0x803 + req oplock fid=2 ret oplock=0x0 status=0xc00000e2 (OPLOCK_NOT_GRANTED) +req 2 0x801 + req oplock fid=2 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x101 ( LEVEL_TWO_OPLOCK READ_CACHING ) + Excl=n cnt_II=1 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease= OgState=0x100 Brk=0x0 Excl=N onlist: II + fid=2 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R diff --git a/usr/src/cmd/smbsrv/testoplock/case10.txt b/usr/src/cmd/smbsrv/testoplock/case10.txt new file mode 100644 index 0000000000..10da33e970 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case10.txt @@ -0,0 +1,12 @@ +# Input for testoplock, case 10 +# Modeled after smbtorture smb2.lease.oplock +open 1 +req 1 0x100 +show +open 2 2 +brk-open 2 +show +req 2 0x807 +req 2 0x803 +req 2 0x801 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case11.ref b/usr/src/cmd/smbsrv/testoplock/case11.ref new file mode 100644 index 0000000000..05bae87e04 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case11.ref @@ -0,0 +1,30 @@ +open 1 1 + open 1 OK +req 1 0x807 + req oplock fid=1 ret oplock=0x807 status=0x0 (SUCCESS) +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=1 OgState=0x807 Brk=0x0 Excl=Y onlist: +open 2 + open 2 OK +brk-open 2 +*smb_oplock_ind_break fid=1 NewLevel=0x3, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 2 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +ack 1 + ack: break fid=1, newstate=0x803, status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +req 2 0x100 + req oplock fid=2 ret oplock=0x0 status=0xc00000e2 (OPLOCK_NOT_GRANTED) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case11.txt b/usr/src/cmd/smbsrv/testoplock/case11.txt new file mode 100644 index 0000000000..7e09c98d73 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case11.txt @@ -0,0 +1,11 @@ +# Input for testoplock, case 11 +# Modeled after smbtorture smb2.lease.break2 +open 1 1 +req 1 0x807 +show +open 2 +brk-open 2 +ack 1 +show +req 2 0x100 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case12.ref b/usr/src/cmd/smbsrv/testoplock/case12.ref new file mode 100644 index 0000000000..bc36b7b6de --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case12.ref @@ -0,0 +1,54 @@ +open 1 1 + open 1 OK +req 1 0x807 + req oplock fid=1 ret oplock=0x807 status=0x0 (SUCCESS) +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=1 OgState=0x807 Brk=0x0 Excl=Y onlist: +open 2 + open 2 OK +brk-open 2 +*smb_oplock_ind_break fid=1 NewLevel=0x3, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 2 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +waiters 2 1 + waiters 0 -> 1 +show + ol_state=0x30017 ( BREAK_TO_HANDLE_CACHING BREAK_TO_READ_CACHING EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x807 Brk=0x30000 Excl=Y onlist: + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +open 3 + open 3 OK +brk-open 3 4 + brk-open 3 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +waiters 3 2 + waiters 1 -> 2 +show + ol_state=0x80017 ( BREAK_TO_NO_CACHING EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=3 + fid=1 Lease=1 OgState=0x807 Brk=0x30000 Excl=Y onlist: + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +ack 1 0x803 +*smb_oplock_ind_break fid=1 NewLevel=0x0, AckReq=1, ComplStatus=0x8000002e (CANNOT_GRANT_REQUESTED_OPLOCK) + ack: break fid=1, newstate=0x803, status=0x0 (SUCCESS) +show + ol_state=0x80003 ( BREAK_TO_NO_CACHING HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=1 + ofile_cnt=3 + fid=1 Lease=1 OgState=0x803 Brk=0x80000 Excl=N onlist: RHBQ(to none) + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: +ack 1 0x800 + ack: break fid=1, newstate=0x800, status=0x0 (SUCCESS) +show + ol_state=0x10000000 ( NO_OPLOCK ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=3 + fid=1 Lease=1 OgState=0x800 Brk=0x0 Excl=N onlist: + fid=2 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: + fid=3 Lease= OgState=0x0 Brk=0x0 Excl=N onlist: diff --git a/usr/src/cmd/smbsrv/testoplock/case12.txt b/usr/src/cmd/smbsrv/testoplock/case12.txt new file mode 100644 index 0000000000..23b4f63092 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case12.txt @@ -0,0 +1,28 @@ +# Input for testoplock, case 12 +# simulate smbtorture smb2.lease.breaking3 +# +open 1 1 +req 1 0x807 +show +# +# a conflicting open (no oplock) is blocked until lease break ack +open 2 +brk-open 2 +waiters 2 1 +show +# should see lease break RWH to RH, and brk-open would block. +# now a conflicting open with disp=overwrite(4), no oplock +open 3 +brk-open 3 4 +waiters 3 2 +show +# should see break_to_none pending (but no break ind yet) +# and brk-open shoud block (break in progress) +# +# ack the first lease break above (RWH to RH) +# should get a new break ind. (RH to none) +ack 1 0x803 +show +# got break ind? +ack 1 0x800 +show diff --git a/usr/src/cmd/smbsrv/testoplock/case13.ref b/usr/src/cmd/smbsrv/testoplock/case13.ref new file mode 100644 index 0000000000..a35a5992ce --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case13.ref @@ -0,0 +1,56 @@ +open 1 1 + open 1 OK +req 1 0x801 + req oplock fid=1 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x1 ( READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=1 OgState=0x801 Brk=0x0 Excl=N onlist: R + +open 2 1 + open 2 OK +brk-open 2 + brk-open 2 ret status=0x0 (SUCCESS) +req 2 0x807 +*smb_oplock_ind_break fid=1 NewLevel=0x7, AckReq=0, ComplStatus=0x215 (OPLOCK_SWITCHED_TO_NEW_HANDLE) + req oplock fid=2 ret oplock=0x807 status=0x0 (SUCCESS) +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=2) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x0 Brk=0x0 Excl=N onlist: + fid=2 Lease=1 OgState=0x807 Brk=0x0 Excl=Y onlist: + +move 2 1 + move 2 1 +close 2 + close OK +show + ol_state=0x17 ( EXCLUSIVE WRITE_CACHING HANDLE_CACHING READ_CACHING ) + Excl=Y (FID=1) cnt_II=0 cnt_R=0 cnt_RH=0 cnt_RHBQ=0 + ofile_cnt=1 + fid=1 Lease=1 OgState=0x807 Brk=0x0 Excl=Y onlist: + +open 3 2 + open 3 OK +brk-open 3 +*smb_oplock_ind_break fid=1 NewLevel=0x3, AckReq=1, ComplStatus=0x0 (SUCCESS) + brk-open 3 ret status=0x108 (OPLOCK_BREAK_IN_PROGRESS) +ack 1 + ack: break fid=1, newstate=0x803, status=0x0 (SUCCESS) +show + ol_state=0x3 ( HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=0 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=3 Lease=2 OgState=0x0 Brk=0x0 Excl=N onlist: + +req 3 0x801 + req oplock fid=3 ret oplock=0x801 status=0x0 (SUCCESS) +show + ol_state=0x23 ( MIXED_R_AND_RH HANDLE_CACHING READ_CACHING ) + Excl=n cnt_II=0 cnt_R=1 cnt_RH=1 cnt_RHBQ=0 + ofile_cnt=2 + fid=1 Lease=1 OgState=0x803 Brk=0x0 Excl=N onlist: RH + fid=3 Lease=2 OgState=0x801 Brk=0x0 Excl=N onlist: R diff --git a/usr/src/cmd/smbsrv/testoplock/case13.txt b/usr/src/cmd/smbsrv/testoplock/case13.txt new file mode 100644 index 0000000000..c8d012690d --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/case13.txt @@ -0,0 +1,25 @@ +# Input for testoplock, case 13 +# simulate smbtorture smb2.lease.complex1 +# +open 1 1 +req 1 0x801 +show + +# upgrade lease 1 +open 2 1 +brk-open 2 +req 2 0x807 +show + +move 2 1 +close 2 +show + +# contend via lease2 +open 3 2 +brk-open 3 +ack 1 +show + +req 3 0x801 +show diff --git a/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h new file mode 100644 index 0000000000..4ccf839f51 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h @@ -0,0 +1,111 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * Function prototypes needed by the "testoplock" program + * (a small subset of what the SMB server uses) + */ + +#ifndef _SMB_KPROTO_H_ +#define _SMB_KPROTO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/varargs.h> +#include <sys/cmn_err.h> +#include <smbsrv/smb.h> +#include <smbsrv/smb_ktypes.h> + +boolean_t smb_ofile_is_open(smb_ofile_t *); +boolean_t smb_node_is_file(smb_node_t *); + +/* + * SMB locked list function prototypes + */ +void smb_llist_init(void); +void smb_llist_fini(void); +void smb_llist_constructor(smb_llist_t *, size_t, size_t); +void smb_llist_destructor(smb_llist_t *); +void smb_llist_enter(smb_llist_t *ll, krw_t); +void smb_llist_exit(smb_llist_t *); +void smb_llist_post(smb_llist_t *, void *, smb_dtorproc_t); +void smb_llist_flush(smb_llist_t *); +void smb_llist_insert_head(smb_llist_t *ll, void *obj); +void smb_llist_insert_tail(smb_llist_t *ll, void *obj); +void smb_llist_remove(smb_llist_t *ll, void *obj); +int smb_llist_upgrade(smb_llist_t *ll); +uint32_t smb_llist_get_count(smb_llist_t *ll); +#define smb_llist_head(ll) list_head(&(ll)->ll_list) +#define smb_llist_next(ll, obj) list_next(&(ll)->ll_list, obj) +int smb_account_connected(smb_user_t *user); + +/* + * Common oplock functions + */ +uint32_t smb_oplock_request(smb_request_t *, smb_ofile_t *, uint32_t *); +uint32_t smb_oplock_ack_break(smb_request_t *, smb_ofile_t *, uint32_t *); +uint32_t smb_oplock_break_PARENT(smb_node_t *, smb_ofile_t *); +uint32_t smb_oplock_break_OPEN(smb_node_t *, smb_ofile_t *, + uint32_t DesiredAccess, uint32_t CreateDisposition); +uint32_t smb_oplock_break_BATCH(smb_node_t *, smb_ofile_t *, + uint32_t DesiredAccess, uint32_t CreateDisposition); +uint32_t smb_oplock_break_HANDLE(smb_node_t *, smb_ofile_t *); +void smb_oplock_break_CLOSE(smb_node_t *, smb_ofile_t *); +uint32_t smb_oplock_break_READ(smb_node_t *, smb_ofile_t *); +uint32_t smb_oplock_break_WRITE(smb_node_t *, smb_ofile_t *); +uint32_t smb_oplock_break_SETINFO(smb_node_t *, + smb_ofile_t *ofile, uint32_t InfoClass); +uint32_t smb_oplock_break_DELETE(smb_node_t *, smb_ofile_t *); + +void smb_oplock_move(smb_node_t *, smb_ofile_t *, smb_ofile_t *); + +/* + * Protocol-specific oplock functions + * (and "server-level" functions) + */ +void smb1_oplock_acquire(smb_request_t *, boolean_t); +void smb1_oplock_break_notification(smb_request_t *, uint32_t); +void smb2_oplock_break_notification(smb_request_t *, uint32_t); +void smb2_lease_break_notification(smb_request_t *, uint32_t, boolean_t); +void smb_oplock_ind_break(smb_ofile_t *, uint32_t, boolean_t, uint32_t); +void smb_oplock_ind_break_in_ack(smb_request_t *, smb_ofile_t *, + uint32_t, boolean_t); +void smb_oplock_send_brk(smb_request_t *); +uint32_t smb_oplock_wait_break(smb_node_t *, int); + +int smb_lock_range_access(smb_request_t *, smb_node_t *, + uint64_t, uint64_t, boolean_t); + + +#ifdef __cplusplus +} +#endif + +#endif /* _SMB_KPROTO_H_ */ diff --git a/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_ktypes.h b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_ktypes.h new file mode 100644 index 0000000000..16c770ef1d --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_ktypes.h @@ -0,0 +1,227 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * Structures and type definitions needed by the "testoplock" program + * (a small subset of what the SMB server uses) + */ + +#ifndef _SMB_KTYPES_H +#define _SMB_KTYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> +#include <sys/debug.h> +#include <sys/systm.h> +#include <sys/cred.h> +#include <sys/list.h> +#include <sys/sdt.h> + +typedef struct smb_session smb_session_t; +typedef struct smb_user smb_user_t; +typedef struct smb_tree smb_tree_t; + + +/* + * Destructor object used in the locked-list delete queue. + */ +#define SMB_DTOR_MAGIC 0x44544F52 /* DTOR */ +#define SMB_DTOR_VALID(d) \ + ASSERT(((d) != NULL) && ((d)->dt_magic == SMB_DTOR_MAGIC)) + +typedef void (*smb_dtorproc_t)(void *); + +typedef struct smb_dtor { + list_node_t dt_lnd; + uint32_t dt_magic; + void *dt_object; + smb_dtorproc_t dt_proc; +} smb_dtor_t; + +typedef struct smb_llist { + krwlock_t ll_lock; + list_t ll_list; + uint32_t ll_count; + uint64_t ll_wrop; + kmutex_t ll_mutex; + list_t ll_deleteq; + uint32_t ll_deleteq_count; + boolean_t ll_flushing; +} smb_llist_t; + +/* + * Per smb_node oplock state + */ +typedef struct smb_oplock { + kmutex_t ol_mutex; + boolean_t ol_fem; /* fem monitor installed? */ + struct smb_ofile *excl_open; + uint32_t ol_state; + int32_t cnt_II; + int32_t cnt_R; + int32_t cnt_RH; + int32_t cnt_RHBQ; + int32_t waiters; + kcondvar_t WaitingOpenCV; +} smb_oplock_t; + +/* + * Per smb_ofile oplock state + */ +typedef struct smb_oplock_grant { + /* smb protocol-level state */ + uint32_t og_state; /* latest sent to client */ + uint32_t og_breaking; /* BREAK_TO... flags */ + uint16_t og_dialect; /* how to send breaks */ + /* File-system level state */ + uint8_t onlist_II; + uint8_t onlist_R; + uint8_t onlist_RH; + uint8_t onlist_RHBQ; + uint8_t BreakingToRead; +} smb_oplock_grant_t; + +#define SMB_LEASE_KEY_SZ 16 + +#define SMB_NODE_MAGIC 0x4E4F4445 /* 'NODE' */ +#define SMB_NODE_VALID(p) ASSERT((p)->n_magic == SMB_NODE_MAGIC) + +typedef enum { + SMB_NODE_STATE_AVAILABLE = 0, + SMB_NODE_STATE_DESTROYING +} smb_node_state_t; + +/* + * waiting_event # of clients requesting FCN + * n_timestamps cached timestamps + * n_allocsz cached file allocation size + * n_dnode directory node + * n_unode unnamed stream node + * delete_on_close_cred credentials for delayed delete + */ +typedef struct smb_node { + list_node_t n_lnd; + uint32_t n_magic; + krwlock_t n_lock; + kmutex_t n_mutex; + smb_node_state_t n_state; + uint32_t n_refcnt; + uint32_t n_open_count; + volatile int flags; + + smb_llist_t n_ofile_list; + smb_oplock_t n_oplock; +} smb_node_t; + +#define NODE_FLAGS_WRITE_THROUGH 0x00100000 +#define NODE_FLAGS_DELETE_COMMITTED 0x20000000 +#define NODE_FLAGS_DELETE_ON_CLOSE 0x40000000 + +/* + * Some flags for ofile structure + * + * SMB_OFLAGS_SET_DELETE_ON_CLOSE + * Set this flag when the corresponding open operation whose + * DELETE_ON_CLOSE bit of the CreateOptions is set. If any + * open file instance has this bit set, the NODE_FLAGS_DELETE_ON_CLOSE + * will be set for the file node upon close. + */ + +/* SMB_OFLAGS_READONLY 0x0001 (obsolete) */ +#define SMB_OFLAGS_EXECONLY 0x0002 +#define SMB_OFLAGS_SET_DELETE_ON_CLOSE 0x0004 +#define SMB_OFLAGS_LLF_POS_VALID 0x0008 + +#define SMB_OFILE_MAGIC 0x4F464C45 /* 'OFLE' */ +#define SMB_OFILE_VALID(p) \ + ASSERT((p != NULL) && ((p)->f_magic == SMB_OFILE_MAGIC)) + +/* + * This is the size of the per-handle "Lock Sequence" array. + * See LockSequenceIndex in [MS-SMB2] 2.2.26, and smb2_lock.c + */ +#define SMB_OFILE_LSEQ_MAX 64 + +/* {arg_open,ofile}->dh_vers values */ +typedef enum { + SMB2_NOT_DURABLE = 0, + SMB2_DURABLE_V1, + SMB2_DURABLE_V2, + SMB2_RESILIENT, +} smb_dh_vers_t; + +/* + * See the long "Ofile State Machine" comment in smb_ofile.c + */ +typedef enum { + SMB_OFILE_STATE_ALLOC = 0, + SMB_OFILE_STATE_OPEN, + SMB_OFILE_STATE_SAVE_DH, + SMB_OFILE_STATE_SAVING, + SMB_OFILE_STATE_CLOSING, + SMB_OFILE_STATE_CLOSED, + SMB_OFILE_STATE_ORPHANED, + SMB_OFILE_STATE_RECONNECT, + SMB_OFILE_STATE_EXPIRED, + SMB_OFILE_STATE_SENTINEL +} smb_ofile_state_t; + +typedef struct smb_ofile { + list_node_t f_tree_lnd; /* t_ofile_list */ + list_node_t f_node_lnd; /* n_ofile_list */ + list_node_t f_dh_lnd; /* sv_persistid_ht */ + uint32_t f_magic; + kmutex_t f_mutex; + smb_ofile_state_t f_state; + + uint16_t f_fid; + uint16_t f_ftype; + uint32_t f_refcnt; + uint32_t f_granted_access; + uint32_t f_share_access; + + smb_node_t *f_node; + + smb_oplock_grant_t f_oplock; + uint8_t TargetOplockKey[SMB_LEASE_KEY_SZ]; + uint8_t ParentOplockKey[SMB_LEASE_KEY_SZ]; + struct smb_lease *f_lease; + +} smb_ofile_t; + +typedef struct smb_request { + list_node_t sr_session_lnd; + uint32_t sr_magic; + kmutex_t sr_mutex; +} smb_request_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _SMB_KTYPES_H */ diff --git a/usr/src/cmd/smbsrv/testoplock/tol_all.d b/usr/src/cmd/smbsrv/testoplock/tol_all.d new file mode 100644 index 0000000000..3a8f2aef84 --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/tol_all.d @@ -0,0 +1,106 @@ +#!/usr/sbin/dtrace -s +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * User-level dtrace for testoplock + * Usage: dtrace -s tol.d -c ./testoplock + */ + +#pragma D option flowindent + +self int trace; +self int mask; + +/* + * Trace almost everything + */ +pid$target:testoplock::entry +{ + self->trace++; +} + +/* + * If traced and not masked, print entry/return + */ +pid$target:testoplock::entry +/self->trace > 0 && self->mask == 0/ +{ + printf("\t0x%x", arg0); + printf("\t0x%x", arg1); + printf("\t0x%x", arg2); + printf("\t0x%x", arg3); + printf("\t0x%x", arg4); + printf("\t0x%x", arg5); +} + +/* Skip the bsearch calls. */ +pid$target:testoplock:xlate_nt_status:entry +{ + self->mask++; +} + +pid$target:testoplock:xlate_nt_status:return +{ + self->mask--; +} + +pid$target:testoplock::return +/self->trace > 0 && self->mask == 0/ +{ + printf("\t0x%x", arg1); +} + +pid$target:testoplock::return +{ + self->trace--; +} + +/* ---------------------- */ + +pid$target::smb_oplock_request:entry +{ + self->sr = arg0; + self->of = arg1; + self->statep = arg2; + this->state = *(uint32_t *)copyin(self->statep, 4); + printf(" entry state=0x%x\n", this->state); +} + +pid$target::smb_oplock_request:return +{ + this->sr = (userland pid`smb_request_t *)self->sr; + this->state = *(uint32_t *)copyin(self->statep, 4); + printf(" return state=0x%x\n", this->state); + printf("\nsr->arg.open = "); + print(this->sr->arg.open); +} + +pid$target::smb_oplock_break_cmn:entry +{ + this->node = (userland pid`smb_node_t *)arg0; + this->ofile = (userland pid`smb_ofile_t *)arg1; + printf("\nnode->n_oplock = "); + print(this->node->n_oplock); + printf("\nofile->f_oplock = "); + print(this->ofile->f_oplock); +} + +pid$target::smb_oplock_ind_break:entry +{ + this->ofile = (userland pid`smb_ofile_t *)arg0; + printf("\nofile->f_oplock = "); + print(this->ofile->f_oplock); +} diff --git a/usr/src/cmd/smbsrv/testoplock/tol_main.c b/usr/src/cmd/smbsrv/testoplock/tol_main.c new file mode 100644 index 0000000000..575c1f44fd --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/tol_main.c @@ -0,0 +1,641 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * Test & debug program for oplocks + * + * This implements a simple command reader which accepts + * commands to simulate oplock events, and prints the + * state changes and actions that would happen after + * each event. + */ + +#include <sys/types.h> +#include <sys/debug.h> +#include <sys/stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +#include <smbsrv/smb_kproto.h> +#include <smbsrv/smb_oplock.h> + +#define OPLOCK_CACHE_RWH (READ_CACHING | HANDLE_CACHING | WRITE_CACHING) +#define OPLOCK_TYPE (LEVEL_TWO_OPLOCK | LEVEL_ONE_OPLOCK |\ + BATCH_OPLOCK | OPLOCK_LEVEL_GRANULAR) + +#define MAXFID 10 + +smb_node_t root_node, test_node; +smb_ofile_t ofile_array[MAXFID]; +smb_request_t test_sr; +uint32_t last_ind_break_level; +char cmdbuf[100]; + +extern const char *xlate_nt_status(uint32_t); + +#define BIT_DEF(name) { name, #name } + +struct bit_defs { + uint32_t mask; + const char *name; +} state_bits[] = { + BIT_DEF(NO_OPLOCK), + BIT_DEF(BREAK_TO_NO_CACHING), + BIT_DEF(BREAK_TO_WRITE_CACHING), + BIT_DEF(BREAK_TO_HANDLE_CACHING), + BIT_DEF(BREAK_TO_READ_CACHING), + BIT_DEF(BREAK_TO_TWO_TO_NONE), + BIT_DEF(BREAK_TO_NONE), + BIT_DEF(BREAK_TO_TWO), + BIT_DEF(BATCH_OPLOCK), + BIT_DEF(LEVEL_ONE_OPLOCK), + BIT_DEF(LEVEL_TWO_OPLOCK), + BIT_DEF(MIXED_R_AND_RH), + BIT_DEF(EXCLUSIVE), + BIT_DEF(WRITE_CACHING), + BIT_DEF(HANDLE_CACHING), + BIT_DEF(READ_CACHING), + { 0, NULL } +}; + +/* + * Helper to print flags fields + */ +static void +print_bits32(char *label, struct bit_defs *bit, uint32_t state) +{ + printf("%s0x%x (", label, state); + while (bit->mask != 0) { + if ((state & bit->mask) != 0) + printf(" %s", bit->name); + bit++; + } + printf(" )\n"); +} + +/* + * Command language: + * + */ +const char helpstr[] = "Commands:\n" + "help\t\tList commands\n" + "show\t\tShow OpLock state etc.\n" + "open FID\n" + "close FID\n" + "req FID [OplockLevel]\n" + "ack FID [OplockLevel]\n" + "brk-parent FID\n" + "brk-open [OverWrite]\n" + "brk-handle FID\n" + "brk-read FID\n" + "brk-write FID\n" + "brk-setinfo FID [InfoClass]\n" + "move FID1 FID2\n" + "waiters FID [count]\n"; + +/* + * Command handlers + */ + +static void +do_show(void) +{ + smb_node_t *node = &test_node; + smb_oplock_t *ol = &node->n_oplock; + uint32_t state = ol->ol_state; + smb_ofile_t *f; + + print_bits32(" ol_state=", state_bits, state); + + if (ol->excl_open != NULL) + printf(" Excl=Y (FID=%d)", ol->excl_open->f_fid); + else + printf(" Excl=n"); + printf(" cnt_II=%d cnt_R=%d cnt_RH=%d cnt_RHBQ=%d\n", + ol->cnt_II, ol->cnt_R, ol->cnt_RH, ol->cnt_RHBQ); + + printf(" ofile_cnt=%d\n", node->n_ofile_list.ll_count); + FOREACH_NODE_OFILE(node, f) { + smb_oplock_grant_t *og = &f->f_oplock; + printf(" fid=%d Lease=%s OgState=0x%x Brk=0x%x", + f->f_fid, + f->TargetOplockKey, /* lease */ + f->f_oplock.og_state, + f->f_oplock.og_breaking); + printf(" Excl=%s onlist: %s %s %s", + (ol->excl_open == f) ? "Y" : "N", + og->onlist_II ? "II" : "", + og->onlist_R ? "R" : "", + og->onlist_RH ? "RH" : ""); + if (og->onlist_RHBQ) { + printf(" RHBQ(to %s)", + og->BreakingToRead ? + "read" : "none"); + } + printf("\n"); + } +} + +static void +do_open(int fid, char *arg2) +{ + smb_node_t *node = &test_node; + smb_ofile_t *ofile = &ofile_array[fid]; + + /* + * Simulate an open (minimal init) + */ + if (ofile->f_refcnt) { + printf("open fid %d already opened\n"); + return; + } + + if (arg2 != NULL) + strlcpy((char *)ofile->TargetOplockKey, arg2, + SMB_LEASE_KEY_SZ); + + ofile->f_refcnt++; + node->n_open_count++; + smb_llist_insert_tail(&node->n_ofile_list, ofile); + printf(" open %d OK\n", fid); +} + +static void +do_close(int fid) +{ + smb_node_t *node = &test_node; + smb_ofile_t *ofile = &ofile_array[fid]; + + /* + * Simulate an close + */ + if (ofile->f_refcnt <= 0) { + printf(" close fid %d already closed\n"); + return; + } + smb_oplock_break_CLOSE(ofile->f_node, ofile); + + smb_llist_remove(&node->n_ofile_list, ofile); + node->n_open_count--; + ofile->f_refcnt--; + + bzero(ofile->TargetOplockKey, SMB_LEASE_KEY_SZ); + + printf(" close OK\n"); +} + +static void +do_req(int fid, char *arg2) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t oplock = BATCH_OPLOCK; + uint32_t status; + + if (arg2 != NULL) + oplock = strtol(arg2, NULL, 16); + + /* + * Request an oplock + */ + status = smb_oplock_request(&test_sr, ofile, &oplock); + if (status == 0) + ofile->f_oplock.og_state = oplock; + printf(" req oplock fid=%d ret oplock=0x%x status=0x%x (%s)\n", + fid, oplock, status, xlate_nt_status(status)); +} + + +static void +do_ack(int fid, char *arg2) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t oplock; + uint32_t status; + + /* Default to level in last smb_oplock_ind_break() */ + oplock = last_ind_break_level; + if (arg2 != NULL) + oplock = strtol(arg2, NULL, 16); + + ofile->f_oplock.og_breaking = 0; + status = smb_oplock_ack_break(&test_sr, ofile, &oplock); + if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) { + printf(" ack: break fid=%d, break-in-progress\n", fid); + ofile->f_oplock.og_state = oplock; + } + if (status == 0) + ofile->f_oplock.og_state = oplock; + + printf(" ack: break fid=%d, newstate=0x%x, status=0x%x (%s)\n", + fid, oplock, status, xlate_nt_status(status)); +} + +static void +do_brk_parent(int fid) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + + status = smb_oplock_break_PARENT(&test_node, ofile); + printf(" brk-parent %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); +} + +static void +do_brk_open(int fid, char *arg2) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + int disp = FILE_OPEN; + + if (arg2 != NULL) + disp = strtol(arg2, NULL, 16); + + status = smb_oplock_break_OPEN(&test_node, ofile, 7, disp); + printf(" brk-open %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); +} + +static void +do_brk_handle(int fid) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + + status = smb_oplock_break_HANDLE(&test_node, ofile); + printf(" brk-handle %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); + +} + +static void +do_brk_read(int fid) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + + status = smb_oplock_break_READ(ofile->f_node, ofile); + printf(" brk-read %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); +} + +static void +do_brk_write(int fid) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + + status = smb_oplock_break_WRITE(ofile->f_node, ofile); + printf(" brk-write %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); +} + +static void +do_brk_setinfo(int fid, char *arg2) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + uint32_t status; + int infoclass = FileEndOfFileInformation; /* 20 */ + + if (arg2 != NULL) + infoclass = strtol(arg2, NULL, 16); + + status = smb_oplock_break_SETINFO( + &test_node, ofile, infoclass); + printf(" brk-setinfo %d ret status=0x%x (%s)\n", + fid, status, xlate_nt_status(status)); + +} + +/* + * Move oplock to another FD, as specified, + * or any other available open + */ +static void +do_move(int fid, char *arg2) +{ + smb_ofile_t *ofile = &ofile_array[fid]; + smb_ofile_t *of2; + int fid2; + + if (arg2 == NULL) { + fprintf(stderr, "move: FID2 required\n"); + return; + } + fid2 = atoi(arg2); + if (fid2 <= 0 || fid2 >= MAXFID) { + fprintf(stderr, "move: bad FID2 %d\n", fid2); + return; + } + of2 = &ofile_array[fid2]; + + smb_oplock_move(&test_node, ofile, of2); + printf(" move %d %d\n", fid, fid2); +} + +/* + * Set/clear oplock.waiters, which affects ack-break + */ +static void +do_waiters(int fid, char *arg2) +{ + smb_node_t *node = &test_node; + smb_oplock_t *ol = &node->n_oplock; + int old, new = 0; + + if (arg2 != NULL) + new = atoi(arg2); + + old = ol->waiters; + ol->waiters = new; + + printf(" waiters %d -> %d\n", old, new); +} + +int +main(int argc, char *argv[]) +{ + smb_node_t *node = &test_node; + char *cmd; + char *arg1; + char *arg2; + char *savep; + char *sep = " \t\n"; + char *prompt = NULL; + int fid; + + if (isatty(0)) + prompt = "> "; + + smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t), + offsetof(smb_ofile_t, f_node_lnd)); + + for (fid = 0; fid < MAXFID; fid++) { + smb_ofile_t *f = &ofile_array[fid]; + + f->f_magic = SMB_OFILE_MAGIC; + mutex_init(&f->f_mutex, NULL, MUTEX_DEFAULT, NULL); + f->f_fid = fid; + f->f_ftype = SMB_FTYPE_DISK; + f->f_node = &test_node; + } + + for (;;) { + if (prompt) { + fputs(prompt, stdout); + fflush(stdout); + } + + cmd = fgets(cmdbuf, sizeof (cmdbuf), stdin); + if (cmd == NULL) + break; + if (cmd[0] == '#') + continue; + + if (prompt == NULL) { + /* Put commands in the output too. */ + fputs(cmdbuf, stdout); + } + cmd = strtok_r(cmd, sep, &savep); + if (cmd == NULL) + continue; + + /* + * Commands with no args + */ + if (0 == strcmp(cmd, "help")) { + fputs(helpstr, stdout); + continue; + } + + if (0 == strcmp(cmd, "show")) { + do_show(); + continue; + } + + /* + * Commands with one arg (the FID) + */ + arg1 = strtok_r(NULL, sep, &savep); + if (arg1 == NULL) { + fprintf(stderr, "%s missing arg1\n", cmd); + continue; + } + fid = atoi(arg1); + if (fid <= 0 || fid >= MAXFID) { + fprintf(stderr, "%s bad FID %d\n", cmd, fid); + continue; + } + + if (0 == strcmp(cmd, "close")) { + do_close(fid); + continue; + } + if (0 == strcmp(cmd, "brk-parent")) { + do_brk_parent(fid); + continue; + } + if (0 == strcmp(cmd, "brk-handle")) { + do_brk_handle(fid); + continue; + } + if (0 == strcmp(cmd, "brk-read")) { + do_brk_read(fid); + continue; + } + if (0 == strcmp(cmd, "brk-write")) { + do_brk_write(fid); + continue; + } + + /* + * Commands with an (optional) arg2. + */ + arg2 = strtok_r(NULL, sep, &savep); + + if (0 == strcmp(cmd, "open")) { + do_open(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "req")) { + do_req(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "ack")) { + do_ack(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "brk-open")) { + do_brk_open(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "brk-setinfo")) { + do_brk_setinfo(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "move")) { + do_move(fid, arg2); + continue; + } + if (0 == strcmp(cmd, "waiters")) { + do_waiters(fid, arg2); + continue; + } + + fprintf(stderr, "%s unknown command. Try help\n", cmd); + } + return (0); +} + +/* + * A few functions called by the oplock code + * Stubbed out, and/or just print a message. + */ + +boolean_t +smb_node_is_file(smb_node_t *node) +{ + return (B_TRUE); +} + +boolean_t +smb_ofile_is_open(smb_ofile_t *ofile) +{ + return (ofile->f_refcnt != 0); +} + +int +smb_lock_range_access( + smb_request_t *sr, + smb_node_t *node, + uint64_t start, + uint64_t length, + boolean_t will_write) +{ + return (0); +} + +/* + * Test code replacement for: smb_oplock_send_brk() + */ +static void +test_oplock_send_brk(smb_ofile_t *ofile, + uint32_t NewLevel, boolean_t AckReq) +{ + smb_oplock_grant_t *og = &ofile->f_oplock; + + /* Skip building a message. */ + + if ((og->og_state & OPLOCK_LEVEL_GRANULAR) != 0) + NewLevel |= OPLOCK_LEVEL_GRANULAR; + + /* + * In a real server, we would send a break to the client, + * and keep track (at the SMB level) whether this oplock + * was obtained via a lease or an old-style oplock. + */ + if (AckReq) { + uint32_t BreakTo; + + if ((og->og_state & OPLOCK_LEVEL_GRANULAR) != 0) { + + BreakTo = (NewLevel & CACHE_RWH) << BREAK_SHIFT; + if (BreakTo == 0) + BreakTo = BREAK_TO_NO_CACHING; + } else { + if ((NewLevel & LEVEL_TWO_OPLOCK) != 0) + BreakTo = BREAK_TO_TWO; + else + BreakTo = BREAK_TO_NONE; + } + og->og_breaking = BreakTo; + last_ind_break_level = NewLevel; + /* Set og_state in do_ack */ + } else { + og->og_state = NewLevel; + /* Clear og_breaking in do_ack */ + } +} + +/* + * Simplified version of what's in smb_srv_oplock.c + */ +void +smb_oplock_ind_break(smb_ofile_t *ofile, uint32_t NewLevel, + boolean_t AckReq, uint32_t status) +{ + smb_oplock_grant_t *og = &ofile->f_oplock; + + printf("*smb_oplock_ind_break fid=%d NewLevel=0x%x," + " AckReq=%d, ComplStatus=0x%x (%s)\n", + ofile->f_fid, NewLevel, AckReq, + status, xlate_nt_status(status)); + + /* + * Note that the CompletionStatus from the FS level + * (smb_cmn_oplock.c) encodes what kind of action we + * need to take at the SMB level. + */ + switch (status) { + + case NT_STATUS_SUCCESS: + case NT_STATUS_CANNOT_GRANT_REQUESTED_OPLOCK: + test_oplock_send_brk(ofile, NewLevel, AckReq); + break; + + case NT_STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE: + case NT_STATUS_OPLOCK_HANDLE_CLOSED: + og->og_state = OPLOCK_LEVEL_NONE; + break; + + default: + /* Checked by caller. */ + ASSERT(0); + break; + } +} + +void +smb_oplock_ind_break_in_ack(smb_request_t *sr, smb_ofile_t *ofile, + uint32_t NewLevel, boolean_t AckRequired) +{ + ASSERT(sr == &test_sr); + smb_oplock_ind_break(ofile, NewLevel, AckRequired, STATUS_CANT_GRANT); +} + +uint32_t +smb_oplock_wait_break(smb_node_t *node, int timeout) +{ + printf("*smb_oplock_wait_break (state=0x%x)\n", + node->n_oplock.ol_state); + return (0); +} + +/* + * There are a couple DTRACE_PROBE* in smb_cmn_oplock.c but we're + * not linking with the user-level dtrace support, so just + * stub these out. + */ +void +__dtrace_fksmb___probe1(char *n, unsigned long a) +{ +} +void +__dtrace_fksmb___probe2(char *n, unsigned long a, unsigned long b) +{ +} diff --git a/usr/src/cmd/smbsrv/testoplock/tol_misc.c b/usr/src/cmd/smbsrv/testoplock/tol_misc.c new file mode 100644 index 0000000000..55a36433ef --- /dev/null +++ b/usr/src/cmd/smbsrv/testoplock/tol_misc.c @@ -0,0 +1,179 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. + */ + +/* + * A few excerpts from smb_kutil.c + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/atomic.h> +#include <sys/debug.h> +#include <sys/time.h> +#include <sys/stddef.h> +#include <smbsrv/smb_kproto.h> + + +/* + * smb_llist_constructor + * + * This function initializes a locked list. + */ +void +smb_llist_constructor( + smb_llist_t *ll, + size_t size, + size_t offset) +{ + rw_init(&ll->ll_lock, NULL, RW_DEFAULT, NULL); + mutex_init(&ll->ll_mutex, NULL, MUTEX_DEFAULT, NULL); + list_create(&ll->ll_list, size, offset); + list_create(&ll->ll_deleteq, sizeof (smb_dtor_t), + offsetof(smb_dtor_t, dt_lnd)); + ll->ll_count = 0; + ll->ll_wrop = 0; + ll->ll_deleteq_count = 0; + ll->ll_flushing = B_FALSE; +} + +/* + * Flush the delete queue and destroy a locked list. + */ +void +smb_llist_destructor( + smb_llist_t *ll) +{ + /* smb_llist_flush(ll); */ + + ASSERT(ll->ll_count == 0); + ASSERT(ll->ll_deleteq_count == 0); + + rw_destroy(&ll->ll_lock); + list_destroy(&ll->ll_list); + list_destroy(&ll->ll_deleteq); + mutex_destroy(&ll->ll_mutex); +} + +void +smb_llist_enter(smb_llist_t *ll, krw_t mode) +{ + rw_enter(&ll->ll_lock, mode); +} + +/* + * Exit the list lock and process the delete queue. + */ +void +smb_llist_exit(smb_llist_t *ll) +{ + rw_exit(&ll->ll_lock); + /* smb_llist_flush(ll); */ +} + +/* + * smb_llist_upgrade + * + * This function tries to upgrade the lock of the locked list. It assumes the + * locked has already been entered in RW_READER mode. It first tries using the + * Solaris function rw_tryupgrade(). If that call fails the lock is released + * and reentered in RW_WRITER mode. In that last case a window is opened during + * which the contents of the list may have changed. The return code indicates + * whether or not the list was modified when the lock was exited. + */ +int smb_llist_upgrade( + smb_llist_t *ll) +{ + uint64_t wrop; + + if (rw_tryupgrade(&ll->ll_lock) != 0) { + return (0); + } + wrop = ll->ll_wrop; + rw_exit(&ll->ll_lock); + rw_enter(&ll->ll_lock, RW_WRITER); + return (wrop != ll->ll_wrop); +} + +/* + * smb_llist_insert_head + * + * This function inserts the object passed a the beginning of the list. This + * function assumes the lock of the list has already been entered. + */ +void +smb_llist_insert_head( + smb_llist_t *ll, + void *obj) +{ + list_insert_head(&ll->ll_list, obj); + ++ll->ll_wrop; + ++ll->ll_count; +} + +/* + * smb_llist_insert_tail + * + * This function appends to the object passed to the list. This function assumes + * the lock of the list has already been entered. + * + */ +void +smb_llist_insert_tail( + smb_llist_t *ll, + void *obj) +{ + list_insert_tail(&ll->ll_list, obj); + ++ll->ll_wrop; + ++ll->ll_count; +} + +/* + * smb_llist_remove + * + * This function removes the object passed from the list. This function assumes + * the lock of the list has already been entered. + */ +void +smb_llist_remove( + smb_llist_t *ll, + void *obj) +{ + list_remove(&ll->ll_list, obj); + ++ll->ll_wrop; + --ll->ll_count; +} + +/* + * smb_llist_get_count + * + * This function returns the number of elements in the specified list. + */ +uint32_t +smb_llist_get_count( + smb_llist_t *ll) +{ + return (ll->ll_count); +} |
