From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 2/2] session: fix box.session.sync() Date: Sat, 9 Jun 2018 20:49:49 +0300 [thread overview] Message-ID: <5bba142da513a6224262993a473b57f54e0c8bc3.1528566238.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1528566238.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1528566238.git.v.shpilevoy@tarantool.org> Before the patch box.session.sync() is global for the session and is updated on each new iproto request. When the connection is multiplexed, box.session.sync() can be changed with no finishing a current request, if a new one arrives. The patch makes box.session.push() local for the request, protecting it from multiplexing mess. Box.session.sync() after the patch can be safely used inside a request. Closes #3450 @TarantoolBot document Title: box.session.sync() became request local Box.session.sync() was global for a session, so it was unusable when the connection behind the session is multiplexed. Now box.session.sync() is request local and can be safely used inside the request processor. --- src/box/iproto.cc | 11 +++++++---- src/box/session.h | 17 ++++++----------- src/fiber.h | 27 ++++++++++++++++++--------- test/box-tap/session.test.lua | 29 ++++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 0102aec4b..759945278 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1171,7 +1171,8 @@ error: static void tx_fiber_init(struct session *session, uint64_t sync) { - session->meta.sync = sync; + struct fiber *f = fiber(); + f->storage.net.sync = sync; /* * We do not cleanup fiber keys at the end of each request. * This does not lead to privilege escalation as long as @@ -1182,8 +1183,8 @@ tx_fiber_init(struct session *session, uint64_t sync) * background tasks clean up their session in on_stop * trigger as well. */ - fiber_set_session(fiber(), session); - fiber_set_user(fiber(), &session->credentials); + fiber_set_session(f, session); + fiber_set_user(f, &session->credentials); } /** @@ -1818,7 +1819,9 @@ iproto_session_fd(struct session *session) int64_t iproto_session_sync(struct session *session) { - return session->meta.sync; + (void) session; + assert(session == fiber()->storage.session); + return fiber()->storage.net.sync; } /** {{{ IPROTO_PUSH implementation. */ diff --git a/src/box/session.h b/src/box/session.h index 17190ab47..6ed97dc46 100644 --- a/src/box/session.h +++ b/src/box/session.h @@ -66,16 +66,11 @@ extern const char *session_type_strs[]; * types, and allows to do not store attributes in struct session, * that are used only by a session of particular type. */ -struct session_meta { - union { - /** IProto connection meta. */ - struct { - uint64_t sync; - void *connection; - }; - /** Only by console is used. */ - int fd; - }; +union session_meta { + /** IProto connection. */ + void *connection; + /** Console file/socket descriptor. */ + int fd; }; /** @@ -92,7 +87,7 @@ struct session { uint64_t id; enum session_type type; /** Session metadata. */ - struct session_meta meta; + union session_meta meta; /** Session user id and global grants */ struct credentials credentials; /** Trigger for fiber on_stop to cleanup created on-demand session */ diff --git a/src/fiber.h b/src/fiber.h index b7003aeb6..021929822 100644 --- a/src/fiber.h +++ b/src/fiber.h @@ -393,15 +393,24 @@ struct fiber { struct session *session; struct credentials *credentials; struct txn *txn; - /** - * Fields used by a fiber created in Lua: Lua - * stack and the optional fiber.storage Lua - * reference. - */ - struct { - struct lua_State *stack; - int ref; - } lua; + union { + /** + * Fields used by a fiber created in Lua: + * Lua stack and the optional + * fiber.storage Lua reference. + */ + struct { + struct lua_State *stack; + int ref; + } lua; + /** + * Fields used by a fiber created to + * process an iproto request. + */ + struct { + uint64_t sync; + } net; + }; } storage; /** An object to wait for incoming message or a reader. */ struct ipc_wait_pad *wait_pad; diff --git a/test/box-tap/session.test.lua b/test/box-tap/session.test.lua index 6fddced3c..c3c07a67c 100755 --- a/test/box-tap/session.test.lua +++ b/test/box-tap/session.test.lua @@ -15,7 +15,7 @@ session = box.session space = box.schema.space.create('tweedledum') index = space:create_index('primary', { type = 'hash' }) -test:plan(53) +test:plan(55) --- --- Check that Tarantool creates ADMIN session for #! script @@ -183,6 +183,33 @@ local sp = conn:eval("return box.space._space.index.name:get{\"sp1\"}[2]") test:is(sp, 1, "effective ddl owner") conn:close() +-- +-- gh-3450: box.session.sync() becomes request local. +-- +cond = fiber.cond() +local sync1, sync2 +local started = 0 +function f1() + started = started + 1 + cond:wait() + sync1 = box.session.sync() +end +function f2() + started = started + 1 + sync2 = box.session.sync() + cond:signal() +end +box.schema.user.grant('guest', 'read,write,execute', 'universe') +conn = net.box.connect(box.cfg.listen) +test:ok(conn:ping(), 'connect to self') +_ = fiber.create(function() conn:call('f1') end) +while started ~= 1 do fiber.sleep(0.01) end +_ = fiber.create(function() conn:call('f2') end) +while started ~= 2 do fiber.sleep(0.01) end +test:isnt(sync1, sync2, 'session.sync() is request local') +conn:close() +box.schema.user.revoke('guest', 'read,write,execute', 'universe') + inspector:cmd('stop server session with cleanup=1') session = nil os.exit(test:check() == true and 0 or -1) -- 2.15.1 (Apple Git-101)
next prev parent reply other threads:[~2018-06-09 17:49 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-09 17:49 [tarantool-patches] [PATCH 0/2] Box.session.sync Vladislav Shpilevoy 2018-06-09 17:49 ` [tarantool-patches] [PATCH 1/2] fiber: remove fiber local storage Vladislav Shpilevoy 2018-06-13 21:11 ` [tarantool-patches] " Konstantin Osipov 2018-06-14 17:33 ` Vladislav Shpilevoy 2018-06-09 17:49 ` Vladislav Shpilevoy [this message] 2018-06-13 21:13 ` [tarantool-patches] Re: [PATCH 2/2] session: fix box.session.sync() Konstantin Osipov 2018-06-09 17:58 ` [tarantool-patches] Re: [PATCH 0/2] Box.session.sync Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=5bba142da513a6224262993a473b57f54e0c8bc3.1528566238.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 2/2] session: fix box.session.sync()' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox