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.
Enjoy,
Nico
-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.-
#!/bin/ksh
#
# 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
OIFS="$IFS"
IFS="$1"
shift
print -- "$*"
IFS="$OIFS"
return 0
}
## noclobber, see below
set -o noclobber
exec 2>> $SMB_LOG_DIR/staleSessions.log
SELF=${0##*/}
## Log our script name, pid and arguments
print -u2 "$SELF[$$]: $@"
OP=$1
shift
SMBPID=$1
shift
## Remaining argument strings identify an SMB share connection/mount
SHARE_ID="$(concat '-' "$@")"
PID_FILE="$SMB_LOCK_DIR/$SHARE_ID.pid"
status=fail
# 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
preexec)
# Skip IPC$ connections
for i in "$@"
do
[[ "$i" = 'IPC$' || "$i" = 'IPC$nobody' ]] && exit 0
done
## 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
do
OPID=$(cat "$PID_FILE")
# Syntax check PID
if [[ -z "$OPID" || "$OPID" != +([0-9]) ]]
then
print -u2 "$SELF[$$]: could not obtain old PID for $SHARE_ID"
set +o noclobber
print -- "$SMBPID" > "$PID_FILE"
break
fi
# 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
continue
}
print -u2 "$SELF[$$]: sending SIGTERM to $OPID on behalf of $SHARE_ID"
kill -TERM "$OPID"
/usr/proc/bin/pwait "$OPID"
done
status=success
;;
postexec)
# Skip IPC$ connections
for i in "$@"
do
[[ "$i" = 'IPC$' || "$i" = 'IPC$nobody' ]] && exit 0
done
if [[ -f "$PID_FILE" ]]
then
OPID=$(cat "$PID_FILE")
if [[ "$OPID" = "$SMBPID" ]]
then
rm "$PID_FILE" || status=rmfail
fi
fi
status=success
;;
esac
case $status in
success) exit 0
;;
esac
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