MXS-2196: Always allocate a session
Whenever a client DCB is accepted, a session for it is allocated. This simplifies the handling of shared data between DCBs by allowing it to be placed inside the session object. Currently, the data is stashed away in the client DCB.
This commit is contained in:
@ -282,27 +282,16 @@ bool session_route_reply(MXS_SESSION* session, GWBUF* buffer);
|
|||||||
/**
|
/**
|
||||||
* Allocate a new session for a new client of the specified service.
|
* Allocate a new session for a new client of the specified service.
|
||||||
*
|
*
|
||||||
* Create the link to the router session by calling the newSession
|
* The start_session function needs to be called after the user authentication is done. This will
|
||||||
* entry point of the router using the router instance of the
|
* trigger the creation of router and filter sessions.
|
||||||
* service this session is part of.
|
|
||||||
*
|
*
|
||||||
* @param service The service this connection was established by
|
* @param service The service this connection was established by
|
||||||
* @param client_dcb The client side DCB
|
* @param client_dcb The client side DCB
|
||||||
|
*
|
||||||
* @return The newly created session or NULL if an error occurred
|
* @return The newly created session or NULL if an error occurred
|
||||||
*/
|
*/
|
||||||
MXS_SESSION* session_alloc(SERVICE*, DCB*);
|
MXS_SESSION* session_alloc(SERVICE*, DCB*);
|
||||||
|
|
||||||
/**
|
|
||||||
* A version of session_alloc() which takes the session id number as parameter.
|
|
||||||
* The id should have been generated with session_get_next_id().
|
|
||||||
*
|
|
||||||
* @param service The service this connection was established by
|
|
||||||
* @param client_dcb The client side DCB
|
|
||||||
* @param id Id for the new session.
|
|
||||||
* @return The newly created session or NULL if an error occurred
|
|
||||||
*/
|
|
||||||
MXS_SESSION* session_alloc_with_id(SERVICE*, DCB*, uint64_t);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the session
|
* Start the session
|
||||||
*
|
*
|
||||||
@ -310,11 +299,10 @@ MXS_SESSION* session_alloc_with_id(SERVICE*, DCB*, uint64_t);
|
|||||||
* sessions.
|
* sessions.
|
||||||
*
|
*
|
||||||
* @param session Session to start
|
* @param session Session to start
|
||||||
* @param service The service where the session is started
|
|
||||||
*
|
*
|
||||||
* @return True if session was started successfully
|
* @return True if session was started successfully
|
||||||
*/
|
*/
|
||||||
bool session_start(MXS_SESSION* session, SERVICE* service);
|
bool session_start(MXS_SESSION* session);
|
||||||
|
|
||||||
MXS_SESSION* session_set_dummy(DCB*);
|
MXS_SESSION* session_set_dummy(DCB*);
|
||||||
|
|
||||||
|
@ -874,6 +874,7 @@ DCB* Listener::accept_one_dcb()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
client_dcb->fd = c_sock;
|
client_dcb->fd = c_sock;
|
||||||
|
client_dcb->session = session_alloc(m_service, client_dcb);
|
||||||
|
|
||||||
// get client address
|
// get client address
|
||||||
if (client_conn.ss_family == AF_UNIX)
|
if (client_conn.ss_family == AF_UNIX)
|
||||||
|
@ -87,10 +87,6 @@ static void session_simple_free(MXS_SESSION* session, DCB* dcb);
|
|||||||
static void session_add_to_all_list(MXS_SESSION* session);
|
static void session_add_to_all_list(MXS_SESSION* session);
|
||||||
static MXS_SESSION* session_find_free();
|
static MXS_SESSION* session_find_free();
|
||||||
static void session_final_free(MXS_SESSION* session);
|
static void session_final_free(MXS_SESSION* session);
|
||||||
static MXS_SESSION* session_alloc_body(SERVICE* service,
|
|
||||||
DCB* client_dcb,
|
|
||||||
MXS_SESSION* session,
|
|
||||||
uint64_t id);
|
|
||||||
static void session_deliver_response(MXS_SESSION* session);
|
static void session_deliver_response(MXS_SESSION* session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,11 +99,6 @@ static void session_deliver_response(MXS_SESSION* session);
|
|||||||
static int session_reply(MXS_FILTER* inst, MXS_FILTER_SESSION* session, GWBUF* data);
|
static int session_reply(MXS_FILTER* inst, MXS_FILTER_SESSION* session, GWBUF* data);
|
||||||
|
|
||||||
MXS_SESSION* session_alloc(SERVICE* service, DCB* client_dcb)
|
MXS_SESSION* session_alloc(SERVICE* service, DCB* client_dcb)
|
||||||
{
|
|
||||||
return session_alloc_with_id(service, client_dcb, session_get_next_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
MXS_SESSION* session_alloc_with_id(SERVICE* service, DCB* client_dcb, uint64_t id)
|
|
||||||
{
|
{
|
||||||
Session* session = new (std::nothrow) Session(service);
|
Session* session = new (std::nothrow) Session(service);
|
||||||
|
|
||||||
@ -116,16 +107,8 @@ MXS_SESSION* session_alloc_with_id(SERVICE* service, DCB* client_dcb, uint64_t i
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return session_alloc_body(service, client_dcb, session, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MXS_SESSION* session_alloc_body(SERVICE* service,
|
|
||||||
DCB* client_dcb,
|
|
||||||
MXS_SESSION* session,
|
|
||||||
uint64_t id)
|
|
||||||
{
|
|
||||||
session->state = SESSION_STATE_READY;
|
session->state = SESSION_STATE_READY;
|
||||||
session->ses_id = id;
|
session->ses_id = session_get_next_id();
|
||||||
session->client_dcb = client_dcb;
|
session->client_dcb = client_dcb;
|
||||||
session->router_session = NULL;
|
session->router_session = NULL;
|
||||||
session->stats.connect = time(0);
|
session->stats.connect = time(0);
|
||||||
@ -158,24 +141,19 @@ static MXS_SESSION* session_alloc_body(SERVICE* service,
|
|||||||
memset(&session->response, 0, sizeof(session->response));
|
memset(&session->response, 0, sizeof(session->response));
|
||||||
session->close_reason = SESSION_CLOSE_NONE;
|
session->close_reason = SESSION_CLOSE_NONE;
|
||||||
|
|
||||||
if (client_dcb->dcb_role != DCB_ROLE_INTERNAL && !session_start(session, service))
|
|
||||||
{
|
|
||||||
// The session will be freed when the client DCB is freed
|
|
||||||
session = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool session_start(MXS_SESSION* session, SERVICE* service)
|
bool session_start(MXS_SESSION* session)
|
||||||
{
|
{
|
||||||
session->router_session = service->router->newSession(service->router_instance, session);
|
session->router_session = session->service->router->newSession(session->service->router_instance,
|
||||||
|
session);
|
||||||
|
|
||||||
if (session->router_session == NULL)
|
if (session->router_session == NULL)
|
||||||
{
|
{
|
||||||
session->state = SESSION_STATE_TO_BE_FREED;
|
session->state = SESSION_STATE_TO_BE_FREED;
|
||||||
MXS_ERROR("Failed to create new router session for service '%s'. "
|
MXS_ERROR("Failed to create new router session for service '%s'. "
|
||||||
"See previous errors for more details.", service->name);
|
"See previous errors for more details.", session->service->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,11 +189,11 @@ bool session_start(MXS_SESSION* session, SERVICE* service)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session->state = SESSION_STATE_ROUTER_READY;
|
session->state = SESSION_STATE_ROUTER_READY;
|
||||||
mxb::atomic::add(&service->stats.n_sessions, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&session->service->stats.n_sessions, 1, mxb::atomic::RELAXED);
|
||||||
mxb::atomic::add(&service->stats.n_current, 1, mxb::atomic::RELAXED);
|
mxb::atomic::add(&session->service->stats.n_current, 1, mxb::atomic::RELAXED);
|
||||||
|
|
||||||
MXS_INFO("Started %s client session [%" PRIu64 "] for '%s' from %s",
|
MXS_INFO("Started %s client session [%" PRIu64 "] for '%s' from %s",
|
||||||
service->name, session->ses_id,
|
session->service->name, session->ses_id,
|
||||||
session->client_dcb->user ? session->client_dcb->user : "<no user>",
|
session->client_dcb->user ? session->client_dcb->user : "<no user>",
|
||||||
session->client_dcb->remote);
|
session->client_dcb->remote);
|
||||||
|
|
||||||
|
@ -144,10 +144,7 @@ static int cdc_read_event(DCB* dcb)
|
|||||||
|
|
||||||
if (auth_val == CDC_STATE_AUTH_OK)
|
if (auth_val == CDC_STATE_AUTH_OK)
|
||||||
{
|
{
|
||||||
/* start a real session */
|
if (session_start(dcb->session))
|
||||||
session = session_alloc(dcb->service, dcb);
|
|
||||||
|
|
||||||
if (session != NULL)
|
|
||||||
{
|
{
|
||||||
protocol->state = CDC_STATE_HANDLE_REQUEST;
|
protocol->state = CDC_STATE_HANDLE_REQUEST;
|
||||||
|
|
||||||
|
@ -370,8 +370,7 @@ static int httpd_accept(DCB* client_dcb)
|
|||||||
}
|
}
|
||||||
client_dcb->data = client_data;
|
client_dcb->data = client_data;
|
||||||
|
|
||||||
client_dcb->session = session_alloc(client_dcb->service, client_dcb);
|
if (!session_start(client_dcb->session) || poll_add_dcb(client_dcb) == -1)
|
||||||
if (NULL == client_dcb->session || poll_add_dcb(client_dcb) == -1)
|
|
||||||
{
|
{
|
||||||
dcb_close(client_dcb);
|
dcb_close(client_dcb);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -293,7 +293,7 @@ int MySQLSendHandshake(DCB* dcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the equivalent of the server thread id.
|
// Get the equivalent of the server thread id.
|
||||||
protocol->thread_id = session_get_next_id();
|
protocol->thread_id = dcb->session->ses_id;
|
||||||
// Send only the low 32bits in the handshake.
|
// Send only the low 32bits in the handshake.
|
||||||
gw_mysql_set_byte4(mysql_thread_id_num, (uint32_t)(protocol->thread_id));
|
gw_mysql_set_byte4(mysql_thread_id_num, (uint32_t)(protocol->thread_id));
|
||||||
memcpy(mysql_scramble_buf, server_scramble, 8);
|
memcpy(mysql_scramble_buf, server_scramble, 8);
|
||||||
@ -766,23 +766,20 @@ static int gw_read_do_authentication(DCB* dcb, GWBUF* read_buffer, int nbytes_re
|
|||||||
|
|
||||||
protocol->protocol_auth_state = MXS_AUTH_STATE_RESPONSE_SENT;
|
protocol->protocol_auth_state = MXS_AUTH_STATE_RESPONSE_SENT;
|
||||||
/**
|
/**
|
||||||
* Create session, and a router session for it.
|
* Start session, and a router session for it.
|
||||||
* If successful, there will be backend connection(s)
|
* If successful, there will be backend connection(s)
|
||||||
* after this point. The protocol authentication state
|
* after this point. The protocol authentication state
|
||||||
* is changed so that future data will go through the
|
* is changed so that future data will go through the
|
||||||
* normal data handling function instead of this one.
|
* normal data handling function instead of this one.
|
||||||
*/
|
*/
|
||||||
MXS_SESSION* session =
|
if (session_start(dcb->session))
|
||||||
session_alloc_with_id(dcb->service, dcb, protocol->thread_id);
|
|
||||||
|
|
||||||
if (session != NULL)
|
|
||||||
{
|
{
|
||||||
mxb_assert(session->state != SESSION_STATE_ALLOC
|
mxb_assert(dcb->session->state != SESSION_STATE_ALLOC
|
||||||
&& session->state != SESSION_STATE_DUMMY);
|
&& dcb->session->state != SESSION_STATE_DUMMY);
|
||||||
// For the time being only the sql_mode is stored in MXS_SESSION::client_protocol_data.
|
// For the time being only the sql_mode is stored in MXS_SESSION::client_protocol_data.
|
||||||
session->client_protocol_data = QC_SQL_MODE_DEFAULT;
|
dcb->session->client_protocol_data = QC_SQL_MODE_DEFAULT;
|
||||||
protocol->protocol_auth_state = MXS_AUTH_STATE_COMPLETE;
|
protocol->protocol_auth_state = MXS_AUTH_STATE_COMPLETE;
|
||||||
MXB_AT_DEBUG(bool check = ) mxs_rworker_register_session(session);
|
MXB_AT_DEBUG(bool check = ) mxs_rworker_register_session(dcb->session);
|
||||||
mxb_assert(check);
|
mxb_assert(check);
|
||||||
mxs_mysql_send_ok(dcb, next_sequence, 0, NULL);
|
mxs_mysql_send_ok(dcb, next_sequence, 0, NULL);
|
||||||
|
|
||||||
|
@ -373,9 +373,7 @@ static int maxscaled_accept(DCB* client_dcb)
|
|||||||
pthread_mutex_init(&maxscaled_protocol->lock, NULL);
|
pthread_mutex_init(&maxscaled_protocol->lock, NULL);
|
||||||
client_dcb->protocol = (void*)maxscaled_protocol;
|
client_dcb->protocol = (void*)maxscaled_protocol;
|
||||||
|
|
||||||
client_dcb->session = session_alloc(client_dcb->service, client_dcb);
|
if (!session_start(client_dcb->session) || poll_add_dcb(client_dcb))
|
||||||
|
|
||||||
if (NULL == client_dcb->session || poll_add_dcb(client_dcb))
|
|
||||||
{
|
{
|
||||||
dcb_close(client_dcb);
|
dcb_close(client_dcb);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -289,8 +289,7 @@ static int telnetd_accept(DCB* client_dcb)
|
|||||||
telnetd_protocol->username = NULL;
|
telnetd_protocol->username = NULL;
|
||||||
client_dcb->protocol = (void*)telnetd_protocol;
|
client_dcb->protocol = (void*)telnetd_protocol;
|
||||||
|
|
||||||
client_dcb->session = session_alloc(client_dcb->service, client_dcb);
|
if (!session_start(client_dcb->session) || poll_add_dcb(client_dcb))
|
||||||
if (NULL == client_dcb->session || poll_add_dcb(client_dcb))
|
|
||||||
{
|
{
|
||||||
dcb_close(client_dcb);
|
dcb_close(client_dcb);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -201,14 +201,15 @@ static void blr_start_master(void* data)
|
|||||||
|
|
||||||
/* Create MySQL Athentication from configured user/passwd */
|
/* Create MySQL Athentication from configured user/passwd */
|
||||||
client->data = CreateMySQLAuthData(router->user, router->password, "");
|
client->data = CreateMySQLAuthData(router->user, router->password, "");
|
||||||
|
client->session = session_alloc(router->service, client);
|
||||||
|
router->session = client->session;
|
||||||
|
|
||||||
/* Create a session for dummy client DCB */
|
/* Create a session for dummy client DCB */
|
||||||
if ((router->session = session_alloc(router->service, client)) == NULL)
|
if (router->session == NULL || session_start(router->session))
|
||||||
{
|
{
|
||||||
MXS_ERROR("failed to create session for connection to master");
|
MXS_ERROR("failed to create session for connection to master");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
client->session = router->session;
|
|
||||||
client->service = router->service;
|
client->service = router->service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user