diff options
author | Ralph Boehme <slow@samba.org> | 2017-03-07 15:33:55 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2017-03-14 12:49:24 +0100 |
commit | 5e94b38e14ea8090f904cc2d270ebdbb2f583e16 (patch) | |
tree | 586432e9a92efb42b1a93c8f33ae84541d90968d | |
parent | 621abab71fd9457bc6586b7e7111e465cdbbe369 (diff) | |
download | samba-5e94b38e14ea8090f904cc2d270ebdbb2f583e16.tar.gz |
s3/smbd: fix schedule_async_open() timer
schedule_async_open() was calling defer_open with sharemode lock = NULL,
as a result there was never an active 20 s timeout.
This has been broken since the commits in
$ git log --reverse -p -10 8283fd0e0090ed12b0b12d5acb550642d621b026
Just roll our own deferred record instead of calling defer_open() and
also set up timer that, as a last resort, catches stuck opens and just
exits for now.
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>
(cherry picked from commit ad8c36125f72e0d5f9ebfc94037a4ae9e7608aad)
-rw-r--r-- | source3/smbd/open.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9ffae48963d..e76395d54e3 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -44,6 +44,13 @@ struct deferred_open_record { bool delayed_for_oplocks; bool async_open; struct file_id id; + + /* + * Timer for async opens, needed because they don't use a watch on + * a locking.tdb record. This is currently only used for real async + * opens and just terminates smbd if the async open times out. + */ + struct tevent_timer *te; }; /**************************************************************************** @@ -2216,19 +2223,44 @@ static void schedule_defer_open(struct share_mode_lock *lck, Reschedule an open call that went asynchronous. ****************************************************************************/ +static void schedule_async_open_timer(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + exit_server("async open timeout"); +} + static void schedule_async_open(struct timeval request_time, struct smb_request *req) { - struct timeval timeout; - - timeout = timeval_set(20, 0); + struct deferred_open_record *open_rec = NULL; + struct timeval timeout = timeval_set(20, 0); + bool ok; if (request_timed_out(request_time, timeout)) { return; } - defer_open(NULL, request_time, timeout, req, - false, true, (struct file_id){0}); + open_rec = deferred_open_record_create(false, true, (struct file_id){0}); + if (open_rec == NULL) { + exit_server("deferred_open_record_create failed"); + } + + ok = push_deferred_open_message_smb(req, request_time, timeout, + (struct file_id){0}, open_rec); + if (!ok) { + exit_server("push_deferred_open_message_smb failed"); + } + + open_rec->te = tevent_add_timer(req->sconn->ev_ctx, + req, + timeval_current_ofs(20, 0), + schedule_async_open_timer, + open_rec); + if (open_rec->te == NULL) { + exit_server("tevent_add_timer failed"); + } } /**************************************************************************** |