summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-03-07 15:33:55 +0100
committerKarolin Seeger <kseeger@samba.org>2017-03-14 12:49:24 +0100
commit5e94b38e14ea8090f904cc2d270ebdbb2f583e16 (patch)
tree586432e9a92efb42b1a93c8f33ae84541d90968d
parent621abab71fd9457bc6586b7e7111e465cdbbe369 (diff)
downloadsamba-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.c42
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");
+ }
}
/****************************************************************************