1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3
Ralph Boehme b35a296a27 s3/smbd: fix deferred open with streams and kernel oplocks
I noticed smbd can get stuck in an open() call with kernel oplocks
enabled and named streams (provided by vfs_streams_xattr):

- client opens a file and with an exclusive oplock

- client starts writing to the file

- client opens an existing stream of the file

- the smbd process gets stuck in an open()

What happens is:

we had setup a locking.tdb record watch in defer_open(), the watch was
triggered, we reattempted the open and got stuck in a blocking open
because the oplock holder (ourselves) hadn't given up the oplock yet.

Cf e576bf5310 for the commit that added
the kernel oplock retry logic. tldr: with kernel oplocks the first open
is non-blocking, but the second one is blocking.

Detailed analysis follows.

When opening a named stream of a file, Samba internally opens the
underlying "base" file first. This internal open of the basefile suceeds
and does *not* trigger an oplock break (because it is an internal open
that doesn't call open() at all) but it is added as an entry to the
locking.tdb record of the file.

Next, the stream open ends up in streams_xattr where a non-blocking
open() on the base file is called. This open fails with EWOULDBLOCK
because we have another fd with a kernel oplock on the file.

So we call defer_open() which sets up a watch on the locking.tdb record.

In the subsequent error unwinding code in open_file_ntcreate() and
callers we close the internal open file handle of the basefile which
also removes the entry from the locking.tdb record and so *changes the
record*.

This fires the record watch and in the callback defer_open_done() we
don't check whether the condition (oplock gone) we're interested in is
actually met. The callback blindly reschedules the open request with
schedule_deferred_open_message_smb().

schedule_deferred_open_message_smb() schedules an immediate tevent event
which has precedence over the IPC fd events in messaging, so the open is
always (!) reattempted before processing the oplock break message.

As explained above, this second open will be a blocking one so we get
stuck in a blocking open.

It doesn't help to make all opens non-blocking, that would just result
in a busy loop failing the open, as we never process the oplock break
message (remember, schedule_deferred_open_message_smb() used immediate
tevent events).

To fix this we must add some logic to the record watch callback to check
whether the record watch was done for a kernel oplock file and if yes,
check if the oplock state changed. If not, simply reschedule the
deferred open and keep waiting.

This logic is only needed for kernel oplocks, not for Samba-level
oplocks, because there's no risk of deadlocking, the worst that can
happen is a rescheduled open that fails again in the oplock checks and
gets deferred again.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=7537

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
2017-03-10 03:28:26 +01:00
..
auth auth3: Simplify auth_check_ntlm_password logic with a "goto fail" 2017-03-09 02:01:35 +01:00
build
client Modify smbspool_krb5_wrapper to just fall through to smbspool if AUTH_INFO_REQUIRED is not set or is not "negotiate". 2017-02-17 04:27:26 +01:00
exports
groupdb Correct "errror" typos. 2017-02-22 08:26:22 +01:00
include s3/includes: add FinderInfo offset define to MacExtensions.h 2017-03-02 00:32:20 +01:00
intl lang_tdb: don't leak lock_path or data_path onto talloc tos 2014-11-03 23:46:05 +01:00
lib lib: Make gencache hash size configurable, default to 10000 2017-03-03 21:55:26 +01:00
libads libads: convert to use smb_gss_krb5_import_cred 2017-03-08 18:00:12 +01:00
libgpo libgpo: apply some const. 2017-01-06 12:28:19 +01:00
libnet s3:libnet_join: make use of trust_pw_new_value() 2017-02-21 16:09:22 +01:00
librpc s3-gse: move krb5 fallback to smb_gss_krb5_import_cred wrapper 2017-03-08 22:00:24 +01:00
libsmb libcli/smb: add max_credits arg to smbXcli_negprot_send() 2017-03-03 21:55:27 +01:00
locale Correct "descriptior" typos. 2017-02-22 08:26:22 +01:00
locking s3/locking: Avoid a talloc for nonexisting fetch_share_mode_unlocked 2017-01-22 18:30:11 +01:00
modules vfs_fruit: enabling AAPL extensions must be a global switch 2017-03-02 04:34:10 +01:00
nmbd Correct "errror" typos. 2017-02-22 08:26:22 +01:00
param rpc_server: Allow to configure the port range for RPC services 2017-01-27 08:09:15 +01:00
passdb s3:passdb: use cli_credentials_set_kerberos_state() for trusts in pdb_get_trust_credentials() 2017-02-24 18:40:14 +01:00
printing Correct "somthing" typos. 2017-02-22 08:26:23 +01:00
profile s3-profile: reduce dependencies of smbprofile.h 2016-03-28 20:45:16 +02:00
registry Correct "existence" typos. 2017-02-22 08:26:22 +01:00
rpc_client cli_netlogon: Add return parms to rpccli_netlogon_password_logon 2017-03-07 09:15:17 +01:00
rpc_server Correct "Openened" typos. 2017-02-22 08:26:24 +01:00
rpcclient cli_netlogon: Add return parms to rpccli_netlogon_password_logon 2017-03-07 09:15:17 +01:00
script Correct "follwing" typos. 2017-02-22 08:26:22 +01:00
selftest selftest: add shares without vfs_fruit for the vfs_fruit tests 2017-03-02 00:32:23 +01:00
services Update smbrun to allow for settings environment variables. 2016-10-13 04:26:26 +02:00
smbd s3/smbd: fix deferred open with streams and kernel oplocks 2017-03-10 03:28:26 +01:00
torture libcli/smb: add max_credits arg to smbXcli_negprot_send() 2017-03-03 21:55:27 +01:00
utils testparm: remove check for "ea support" in fruit shares 2017-03-02 22:30:23 +01:00
web
winbindd winbindd: Remove an unused #define 2017-03-10 00:00:15 +01:00
.clang_complete lib: Remove tdb_compat 2015-03-17 11:30:52 +01:00
.dmallocrc
.indent.pro
change-log Correct "existence" typos. 2017-02-22 08:26:22 +01:00
Doxyfile
mainpage.dox
smbadduser.in
wscript s3/wscript: fix Linux kernel oplock detection 2017-03-10 03:28:25 +01:00
wscript_build s3:wscript_build: remove unused bld.RECURSE('lib/pthreadpool') 2017-02-23 23:58:21 +01:00
wscript_configure_system_ncurses Transition to waf 1.8: wrapped conf.check_cfg 2015-03-16 03:00:07 +01:00