oplock errors

Nicolas Williams Nicolas.Williams at wdr.com
Fri Nov 5 17:21:38 GMT 1999

[NOTE: I don't subscribe to any of the Samba lists but follow them on
       the Samba list arvhices. It would be nice if the archives web
       sites included e-mail reference IDs so I can use then when
       "replying" to messages on these lists so that I don't break
       threading for others who do subscribe.]

I've posted about this problem before. I should probably make the damn
time and reproduce the bug (it's so easy to do it) and send
snoop/truss/sotruss/pstack output to the list. But as it is I won't be
able to do this for a few weeks.

Now, we've speculated here before that the oplock problem on Solaris has
to do with the FIN/ACK/data bugs in client TCP/IP stacks as well as in
the Solaris TCP/IP stack.  The Solaris bug ID is 4083814 and the Solaris
patch ID is 105529-04 (the current patch version is -07).

Now, I've also stated that I have a workaround. I include the script I
use in conjunction with root preexec/root postexec below. This
workaround works fine.

I've also stated the procedures needed to reproduce the bug:

 - make an SMB connection from an NT client to a Solaris Samba server
 - open some file on the Samba share with Word or some other program
   that'll use oplocks
 - yank the network from the Samba server
 - attempt to save the file you had opened
 - wait 45 seconds + a few seconds
 - restore the network
 - wait a bit

That's it. At that point there will be two smbd processes for the same
NT client on the Samba server: one is "stale", should die and holds the
oplock and is sleeping; the other is new and is waiting for the old smbd
to release the oplock.

If you want to read more about this problem or how to use the script
included below, search the list archives for posts from me. One Subject:
under which this has been discussed before is

"Stale smbd processes (was: DOS: Clients can freeze other clients smbd)"

You may want to read those as the script I include below is not the only
proposed solution. It's just the one I use.


-DISCLAIMER: an automatically appended disclaimer may follow. By posting-
-to a public e-mail mailing list I hereby grant permission to distribute-
-and copy this message.-

# This script is meant to be run by Samba SMBdaemons as specified in
# per-share 'root preexec' and 'root postexec' parameters. The purpose
# of this script is to clean up stale smbds; this is accomplish by
# creating a PID file named after the given share connection parameters.
# Such pidfiles are removed when called by smbd as a result of the 'root
# postexec' parameter. Such pidfiles are created when called by smbd as
# a result of the 'root preexec'; if one already exists, then the script
# checks for a stale smbd and kills it if there is any.
# Examples:
# root preexec = /usr/local/samba/libexec/chkStaleSession preexec %d %I %h %S %U
# root postexec = /usr/local/samba/libexec/chkStaleSession postexec %d %I %h %S %U
# (c) Perot Systems Inc.
# Nicolas.Williams at wdr.com
##       @(#) chkStaleSession 1.3     09/02/99, WDR

## Globals
: ${SMB_LOCK_DIR:=/var/smb/locks}
: ${SMB_LOG_DIR:=/var/smb/log}

## concat - concatenate argument strings with given separator character
#	    $1 --> separator character
#	    $2, $3, ..., $n --> strings to concatenate
concat ()
	typeset OIFS
	print -- "$*"
	return 0

## noclobber, see below
set -o noclobber

exec 2>> $SMB_LOG_DIR/staleSessions.log


## Log our script name, pid and arguments
print -u2 "$SELF[$$]: $@"



## Remaining argument strings identify an SMB share connection/mount
SHARE_ID="$(concat '-' "$@")"


# This script uses /usr/proc/bin/ptree and /usr/proc/bin/pwait.
# For platforms other than Solaris you may have to modify it to use
# something else (e.g., ps can replace ptree).

case $OP in
		# Skip IPC$ connections
		for i in "$@"
			[[ "$i" = 'IPC$' || "$i" = 'IPC$nobody' ]] && exit 0

		## The 'noclobber' option comes into play here,
		## preventing the print command from being executed
		## if $PID_FILE exists. 'noclobber' is equivalent to
		## using open(2) with O_CREAT|O_EXCL.

		until ( print -- "$SMBPID" > "$PID_FILE" ) 2> /dev/null
			OPID=$(cat "$PID_FILE")

			# Syntax check PID
			if [[ -z "$OPID" || "$OPID" != +([0-9]) ]]
				print -u2 "$SELF[$$]: could not obtain old PID for $SHARE_ID"
				set +o noclobber
				print -- "$SMBPID" > "$PID_FILE"

			# Check that process still exists and is an smbd
			/usr/proc/bin/ptree "$OPID"|grep smb > /dev/null 2>&1 || {
				rm "$PID_FILE" || status=rmfail
			print -u2 "$SELF[$$]: sending SIGTERM to $OPID on behalf of $SHARE_ID"
			kill -TERM "$OPID"
			/usr/proc/bin/pwait "$OPID"
		# Skip IPC$ connections
		for i in "$@"
			[[ "$i" = 'IPC$' || "$i" = 'IPC$nobody' ]] && exit 0

		if [[ -f  "$PID_FILE" ]]
			OPID=$(cat "$PID_FILE")
			if [[ "$OPID" = "$SMBPID" ]]
				rm "$PID_FILE" || status=rmfail

case $status in
	success) exit 0

print -u2 -- "$SELF[$$]: Error: ($1) pid file $PID_FILE has not been removed!"

exit 0

This message contains confidential information and is intended only 
for the individual named.  If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail.  Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free 
as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete, or contain viruses.  The sender therefore 
does not accept liability for any errors or omissions in the contents 
of this message which arise as a result of e-mail transmission.  If 
verification is required please request a hard-copy version.  This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities or 
related financial instruments.

More information about the samba-technical mailing list