Simplify handling of "client data" by having a pointer to it only in DCB and not in session structure. Change name of session->client to session->client_dcb for greater clarity. Temporary free of client data in DCB, to be moved to authenticator when it becomes a module. Fix incorrect name of listener_alloc.
This commit is contained in:
parent
ef8a20cceb
commit
395cbdc103
@ -126,6 +126,8 @@ static int gw_write(DCB *dcb, bool *stop_writing);
|
||||
static int gw_write_SSL(DCB *dcb, bool *stop_writing);
|
||||
static void dcb_log_errors_SSL (DCB *dcb, const char *called_by, int ret);
|
||||
|
||||
static void mysql_auth_free_client_data(DCB *dcb);
|
||||
|
||||
size_t dcb_get_session_id(
|
||||
DCB *dcb)
|
||||
{
|
||||
@ -373,10 +375,10 @@ dcb_final_free(DCB *dcb)
|
||||
* won't try to call dcb_close for client DCB
|
||||
* after this call.
|
||||
*/
|
||||
if (local_session->client == dcb)
|
||||
if (local_session->client_dcb == dcb)
|
||||
{
|
||||
spinlock_acquire(&local_session->ses_lock);
|
||||
local_session->client = NULL;
|
||||
local_session->client_dcb = NULL;
|
||||
spinlock_release(&local_session->ses_lock);
|
||||
}
|
||||
if (SESSION_STATE_DUMMY != local_session->state)
|
||||
@ -385,6 +387,8 @@ dcb_final_free(DCB *dcb)
|
||||
}
|
||||
}
|
||||
|
||||
mysql_auth_free_client_data(dcb);
|
||||
|
||||
if (dcb->protocol && (!DCB_IS_CLONE(dcb)))
|
||||
{
|
||||
free(dcb->protocol);
|
||||
@ -779,8 +783,8 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol)
|
||||
server->name,
|
||||
server->port,
|
||||
dcb,
|
||||
session->client,
|
||||
session->client->fd);
|
||||
session->client_dcb,
|
||||
session->client_dcb->fd);
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
dcb_final_free(dcb);
|
||||
return NULL;
|
||||
@ -793,8 +797,8 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol)
|
||||
server->name,
|
||||
server->port,
|
||||
dcb,
|
||||
session->client,
|
||||
session->client->fd);
|
||||
session->client_dcb,
|
||||
session->client_dcb->fd);
|
||||
}
|
||||
/**
|
||||
* Successfully connected to backend. Assign file descriptor to dcb
|
||||
@ -2132,9 +2136,9 @@ dcb_isclient(DCB *dcb)
|
||||
{
|
||||
if (dcb->state != DCB_STATE_LISTENING && dcb->session)
|
||||
{
|
||||
if (dcb->session->client)
|
||||
if (dcb->session->client_dcb)
|
||||
{
|
||||
return (dcb->session && dcb == dcb->session->client);
|
||||
return (dcb->session && dcb == dcb->session->client_dcb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3020,3 +3024,21 @@ dcb_role_name(DCB *dcb)
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the client data pointed to by the passed DCB.
|
||||
*
|
||||
* Currently all that is required is to free the storage pointed to by
|
||||
* dcb->data. But this is intended to be implemented as part of the
|
||||
* authentication API at which time this code will be moved into the
|
||||
* MySQL authenticator. If the data structure were to become more complex
|
||||
* the mechanism would still work and be the responsibility of the authenticator.
|
||||
* The DCB should not know authenticator implementation details.
|
||||
*
|
||||
* @param dcb Request handler DCB connected to the client
|
||||
*/
|
||||
static void
|
||||
mysql_auth_free_client_data(DCB *dcb)
|
||||
{
|
||||
free(dcb->data);
|
||||
}
|
@ -56,7 +56,7 @@ static RSA *tmp_rsa_callback(SSL *s, int is_export, int keylength);
|
||||
* @return New listener object or NULL if unable to allocate
|
||||
*/
|
||||
SERV_LISTENER *
|
||||
alloc_listener(char *protocol, char *address, unsigned short port, char *authenticator, SSL_LISTENER *ssl)
|
||||
listener_alloc(char *protocol, char *address, unsigned short port, char *authenticator, SSL_LISTENER *ssl)
|
||||
{
|
||||
SERV_LISTENER *proto = NULL;
|
||||
if ((proto = (SERV_LISTENER *)malloc(sizeof(SERV_LISTENER))) != NULL)
|
||||
|
@ -689,7 +689,7 @@ serviceAddProtocol(SERVICE *service, char *protocol, char *address, unsigned sho
|
||||
{
|
||||
SERV_LISTENER *proto;
|
||||
|
||||
if ((proto = alloc_listener(protocol, address, port, authenticator, ssl)) != NULL)
|
||||
if ((proto = listener_alloc(protocol, address, port, authenticator, ssl)) != NULL)
|
||||
{
|
||||
spinlock_acquire(&service->spin);
|
||||
proto->next = service->ports;
|
||||
|
@ -117,7 +117,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
session->ses_is_child = (bool) DCB_IS_CLONE(client_dcb);
|
||||
spinlock_init(&session->ses_lock);
|
||||
session->service = service;
|
||||
session->client = client_dcb;
|
||||
session->client_dcb = client_dcb;
|
||||
session->n_filters = 0;
|
||||
memset(&session->stats, 0, sizeof(SESSION_STATS));
|
||||
session->stats.connect = time(0);
|
||||
@ -129,7 +129,6 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
* session has not been made available to the other threads at this
|
||||
* point.
|
||||
*/
|
||||
session->data = client_dcb->data;
|
||||
session->refcount = 1;
|
||||
/*<
|
||||
* This indicates that session is ready to be shared with backend
|
||||
@ -194,7 +193,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
{
|
||||
session->state = SESSION_STATE_ROUTER_READY;
|
||||
|
||||
if (session->client->user == NULL)
|
||||
if (session->client_dcb->user == NULL)
|
||||
{
|
||||
MXS_INFO("Started session [%lu] for %s service ",
|
||||
session->ses_id,
|
||||
@ -205,8 +204,8 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
MXS_INFO("Started %s client session [%lu] for '%s' from %s",
|
||||
service->name,
|
||||
session->ses_id,
|
||||
session->client->user,
|
||||
session->client->remote);
|
||||
session->client_dcb->user,
|
||||
session->client_dcb->remote);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -215,8 +214,8 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
"closed as soon as all related DCBs have been closed.",
|
||||
service->name,
|
||||
session->ses_id,
|
||||
session->client->user,
|
||||
session->client->remote);
|
||||
session->client_dcb->user,
|
||||
session->client_dcb->remote);
|
||||
}
|
||||
spinlock_acquire(&session_spin);
|
||||
/** Assign a session id and increase, insert session into list */
|
||||
@ -253,12 +252,11 @@ session_set_dummy(DCB *client_dcb)
|
||||
session->ses_is_child = false;
|
||||
spinlock_init(&session->ses_lock);
|
||||
session->service = NULL;
|
||||
session->client = NULL;
|
||||
session->client_dcb = NULL;
|
||||
session->n_filters = 0;
|
||||
memset(&session->stats, 0, sizeof(SESSION_STATS));
|
||||
session->stats.connect = 0;
|
||||
session->state = SESSION_STATE_DUMMY;
|
||||
session->data = NULL;
|
||||
session->refcount = 1;
|
||||
session->ses_id = 0;
|
||||
session->next = NULL;
|
||||
@ -272,12 +270,12 @@ session_set_dummy(DCB *client_dcb)
|
||||
* counter.
|
||||
* Generic logging setting has precedence over session-specific setting.
|
||||
*
|
||||
* @param ses session
|
||||
* @param session session
|
||||
* @param priority syslog priority
|
||||
*/
|
||||
void session_enable_log_priority(SESSION* ses, int priority)
|
||||
void session_enable_log_priority(SESSION* session, int priority)
|
||||
{
|
||||
ses->enabled_log_priorities |= (1 << priority);
|
||||
session->enabled_log_priorities |= (1 << priority);
|
||||
atomic_add((int *)&mxs_log_session_count[priority], 1);
|
||||
}
|
||||
|
||||
@ -286,14 +284,14 @@ void session_enable_log_priority(SESSION* ses, int priority)
|
||||
* counter.
|
||||
* Generic logging setting has precedence over session-specific setting.
|
||||
*
|
||||
* @param ses session
|
||||
* @param session session
|
||||
* @param priority syslog priority
|
||||
*/
|
||||
void session_disable_log_priority(SESSION* ses, int priority)
|
||||
void session_disable_log_priority(SESSION* session, int priority)
|
||||
{
|
||||
if (ses->enabled_log_priorities & (1 << priority))
|
||||
if (session->enabled_log_priorities & (1 << priority))
|
||||
{
|
||||
ses->enabled_log_priorities &= ~(1 << priority);
|
||||
session->enabled_log_priorities &= ~(1 << priority);
|
||||
atomic_add((int *)&mxs_log_session_count[priority], -1);
|
||||
}
|
||||
}
|
||||
@ -345,9 +343,9 @@ int session_unlink_dcb(SESSION* session,
|
||||
|
||||
if (dcb != NULL)
|
||||
{
|
||||
if (session->client == dcb)
|
||||
if (session->client_dcb == dcb)
|
||||
{
|
||||
session->client = NULL;
|
||||
session->client_dcb = NULL;
|
||||
}
|
||||
dcb->session = NULL;
|
||||
}
|
||||
@ -481,11 +479,6 @@ session_free(SESSION *session)
|
||||
if (!session->ses_is_child)
|
||||
{
|
||||
session->state = SESSION_STATE_FREE;
|
||||
|
||||
if (session->data)
|
||||
{
|
||||
free(session->data);
|
||||
}
|
||||
free(session);
|
||||
}
|
||||
return true;
|
||||
@ -500,19 +493,19 @@ session_free(SESSION *session)
|
||||
int
|
||||
session_isvalid(SESSION *session)
|
||||
{
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
int rval = 0;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
while (ptr)
|
||||
list_session = allSessions;
|
||||
while (list_session)
|
||||
{
|
||||
if (ptr == session)
|
||||
if (list_session == session)
|
||||
{
|
||||
rval = 1;
|
||||
break;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
|
||||
@ -533,7 +526,7 @@ printSession(SESSION *session)
|
||||
printf("Session %p\n", session);
|
||||
printf("\tState: %s\n", session_state(session->state));
|
||||
printf("\tService: %s (%p)\n", session->service->name, session->service);
|
||||
printf("\tClient DCB: %p\n", session->client);
|
||||
printf("\tClient DCB: %p\n", session->client_dcb);
|
||||
printf("\tConnected: %s",
|
||||
asctime_r(localtime_r(&session->stats.connect, &result), timebuf));
|
||||
}
|
||||
@ -547,14 +540,14 @@ printSession(SESSION *session)
|
||||
void
|
||||
printAllSessions()
|
||||
{
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
while (ptr)
|
||||
list_session = allSessions;
|
||||
while (list_session)
|
||||
{
|
||||
printSession(ptr);
|
||||
ptr = ptr->next;
|
||||
printSession(list_session);
|
||||
list_session = list_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
}
|
||||
@ -569,29 +562,29 @@ printAllSessions()
|
||||
void
|
||||
CheckSessions()
|
||||
{
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
int noclients = 0;
|
||||
int norouter = 0;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
while (ptr)
|
||||
list_session = allSessions;
|
||||
while (list_session)
|
||||
{
|
||||
if (ptr->state != SESSION_STATE_LISTENER ||
|
||||
ptr->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
if (list_session->state != SESSION_STATE_LISTENER ||
|
||||
list_session->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
{
|
||||
if (ptr->client == NULL && ptr->refcount)
|
||||
if (list_session->client_dcb == NULL && list_session->refcount)
|
||||
{
|
||||
if (noclients == 0)
|
||||
{
|
||||
printf("Sessions without a client DCB.\n");
|
||||
printf("==============================\n");
|
||||
}
|
||||
printSession(ptr);
|
||||
printSession(list_session);
|
||||
noclients++;
|
||||
}
|
||||
}
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
if (noclients)
|
||||
@ -599,24 +592,24 @@ CheckSessions()
|
||||
printf("%d Sessions have no clients\n", noclients);
|
||||
}
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
while (ptr)
|
||||
list_session = allSessions;
|
||||
while (list_session)
|
||||
{
|
||||
if (ptr->state != SESSION_STATE_LISTENER ||
|
||||
ptr->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
if (list_session->state != SESSION_STATE_LISTENER ||
|
||||
list_session->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
{
|
||||
if (ptr->router_session == NULL && ptr->refcount)
|
||||
if (list_session->router_session == NULL && list_session->refcount)
|
||||
{
|
||||
if (norouter == 0)
|
||||
{
|
||||
printf("Sessions without a router session.\n");
|
||||
printf("==================================\n");
|
||||
}
|
||||
printSession(ptr);
|
||||
printSession(list_session);
|
||||
norouter++;
|
||||
}
|
||||
}
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
if (norouter)
|
||||
@ -638,36 +631,36 @@ dprintAllSessions(DCB *dcb)
|
||||
{
|
||||
struct tm result;
|
||||
char timebuf[40];
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
while (ptr)
|
||||
list_session = allSessions;
|
||||
while (list_session)
|
||||
{
|
||||
dcb_printf(dcb, "Session %d (%p)\n",ptr->ses_id, ptr);
|
||||
dcb_printf(dcb, "\tState: %s\n", session_state(ptr->state));
|
||||
dcb_printf(dcb, "\tService: %s (%p)\n", ptr->service->name, ptr->service);
|
||||
dcb_printf(dcb, "\tClient DCB: %p\n", ptr->client);
|
||||
dcb_printf(dcb, "Session %d (%p)\n",list_session->ses_id, list_session);
|
||||
dcb_printf(dcb, "\tState: %s\n", session_state(list_session->state));
|
||||
dcb_printf(dcb, "\tService: %s (%p)\n", list_session->service->name, list_session->service);
|
||||
dcb_printf(dcb, "\tClient DCB: %p\n", list_session->client_dcb);
|
||||
|
||||
if (ptr->client && ptr->client->remote)
|
||||
if (list_session->client_dcb && list_session->client_dcb->remote)
|
||||
{
|
||||
dcb_printf(dcb, "\tClient Address: %s%s%s\n",
|
||||
ptr->client->user?ptr->client->user:"",
|
||||
ptr->client->user?"@":"",
|
||||
ptr->client->remote);
|
||||
list_session->client_dcb->user?list_session->client_dcb->user:"",
|
||||
list_session->client_dcb->user?"@":"",
|
||||
list_session->client_dcb->remote);
|
||||
}
|
||||
|
||||
dcb_printf(dcb, "\tConnected: %s",
|
||||
asctime_r(localtime_r(&ptr->stats.connect, &result), timebuf));
|
||||
asctime_r(localtime_r(&list_session->stats.connect, &result), timebuf));
|
||||
|
||||
if (ptr->client && ptr->client->state == DCB_STATE_POLLING)
|
||||
if (list_session->client_dcb && list_session->client_dcb->state == DCB_STATE_POLLING)
|
||||
{
|
||||
double idle = (hkheartbeat - ptr->client->last_read);
|
||||
double idle = (hkheartbeat - list_session->client_dcb->last_read);
|
||||
idle = idle > 0 ? idle/10.0:0;
|
||||
dcb_printf(dcb, "\tIdle: %.0f seconds\n",idle);
|
||||
}
|
||||
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
}
|
||||
@ -679,43 +672,43 @@ dprintAllSessions(DCB *dcb)
|
||||
* to display all active sessions within the gateway
|
||||
*
|
||||
* @param dcb The DCB to print to
|
||||
* @param ptr The session to print
|
||||
* @param print_session The session to print
|
||||
*/
|
||||
void
|
||||
dprintSession(DCB *dcb, SESSION *ptr)
|
||||
dprintSession(DCB *dcb, SESSION *print_session)
|
||||
{
|
||||
struct tm result;
|
||||
char buf[30];
|
||||
int i;
|
||||
|
||||
dcb_printf(dcb, "Session %d (%p)\n",ptr->ses_id, ptr);
|
||||
dcb_printf(dcb, "\tState: %s\n", session_state(ptr->state));
|
||||
dcb_printf(dcb, "\tService: %s (%p)\n", ptr->service->name, ptr->service);
|
||||
dcb_printf(dcb, "\tClient DCB: %p\n", ptr->client);
|
||||
if (ptr->client && ptr->client->remote)
|
||||
dcb_printf(dcb, "Session %d (%p)\n",print_session->ses_id, print_session);
|
||||
dcb_printf(dcb, "\tState: %s\n", session_state(print_session->state));
|
||||
dcb_printf(dcb, "\tService: %s (%p)\n", print_session->service->name, print_session->service);
|
||||
dcb_printf(dcb, "\tClient DCB: %p\n", print_session->client_dcb);
|
||||
if (print_session->client_dcb && print_session->client_dcb->remote)
|
||||
{
|
||||
double idle = (hkheartbeat - ptr->client->last_read);
|
||||
double idle = (hkheartbeat - print_session->client_dcb->last_read);
|
||||
idle = idle > 0 ? idle/10.f : 0;
|
||||
dcb_printf(dcb, "\tClient Address: %s%s%s\n",
|
||||
ptr->client->user?ptr->client->user:"",
|
||||
ptr->client->user?"@":"",
|
||||
ptr->client->remote);
|
||||
print_session->client_dcb->user?print_session->client_dcb->user:"",
|
||||
print_session->client_dcb->user?"@":"",
|
||||
print_session->client_dcb->remote);
|
||||
dcb_printf(dcb, "\tConnected: %s\n",
|
||||
asctime_r(localtime_r(&ptr->stats.connect, &result), buf));
|
||||
if (ptr->client->state == DCB_STATE_POLLING)
|
||||
asctime_r(localtime_r(&print_session->stats.connect, &result), buf));
|
||||
if (print_session->client_dcb->state == DCB_STATE_POLLING)
|
||||
{
|
||||
dcb_printf(dcb, "\tIdle: %.0f seconds\n",idle);
|
||||
}
|
||||
|
||||
}
|
||||
if (ptr->n_filters)
|
||||
if (print_session->n_filters)
|
||||
{
|
||||
for (i = 0; i < ptr->n_filters; i++)
|
||||
for (i = 0; i < print_session->n_filters; i++)
|
||||
{
|
||||
dcb_printf(dcb, "\tFilter: %s\n",
|
||||
ptr->filters[i].filter->name);
|
||||
ptr->filters[i].filter->obj->diagnostics(ptr->filters[i].instance,
|
||||
ptr->filters[i].session,
|
||||
print_session->filters[i].filter->name);
|
||||
print_session->filters[i].filter->obj->diagnostics(print_session->filters[i].instance,
|
||||
print_session->filters[i].session,
|
||||
dcb);
|
||||
}
|
||||
}
|
||||
@ -732,26 +725,26 @@ dprintSession(DCB *dcb, SESSION *ptr)
|
||||
void
|
||||
dListSessions(DCB *dcb)
|
||||
{
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
if (ptr)
|
||||
list_session = allSessions;
|
||||
if (list_session)
|
||||
{
|
||||
dcb_printf(dcb, "Sessions.\n");
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
dcb_printf(dcb, "Session | Client | Service | State\n");
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
}
|
||||
while (ptr)
|
||||
while (list_session)
|
||||
{
|
||||
dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", ptr,
|
||||
((ptr->client && ptr->client->remote)
|
||||
? ptr->client->remote : ""),
|
||||
(ptr->service && ptr->service->name ? ptr->service->name
|
||||
dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", list_session,
|
||||
((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""),
|
||||
(list_session->service && list_session->service->name ? list_session->service->name
|
||||
: ""),
|
||||
session_state(ptr->state));
|
||||
ptr = ptr->next;
|
||||
session_state(list_session->state));
|
||||
list_session = list_session->next;
|
||||
}
|
||||
if (allSessions)
|
||||
{
|
||||
@ -905,7 +898,7 @@ session_reply(void *instance, void *session, GWBUF *data)
|
||||
{
|
||||
SESSION *the_session = (SESSION *)session;
|
||||
|
||||
return the_session->client->func.write(the_session->client, data);
|
||||
return the_session->client_dcb->func.write(the_session->client_dcb, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -916,9 +909,9 @@ session_reply(void *instance, void *session, GWBUF *data)
|
||||
char *
|
||||
session_get_remote(SESSION *session)
|
||||
{
|
||||
if (session && session->client)
|
||||
if (session && session->client_dcb)
|
||||
{
|
||||
return session->client->remote;
|
||||
return session->client_dcb->remote;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -958,7 +951,7 @@ return_succp:
|
||||
char *
|
||||
session_getUser(SESSION *session)
|
||||
{
|
||||
return (session && session->client) ? session->client->user : NULL;
|
||||
return (session && session->client_dcb) ? session->client_dcb->user : NULL;
|
||||
}
|
||||
/**
|
||||
* Return the pointer to the list of all sessions.
|
||||
@ -996,17 +989,17 @@ void process_idle_sessions()
|
||||
* check for it once per second. One heartbeat is 100 milliseconds. */
|
||||
next_timeout_check = hkheartbeat + 10;
|
||||
spinlock_acquire(&session_spin);
|
||||
SESSION *ses = get_all_sessions();
|
||||
SESSION *all_session = get_all_sessions();
|
||||
|
||||
while (ses)
|
||||
while (all_session)
|
||||
{
|
||||
if (ses->service && ses->client && ses->client->state == DCB_STATE_POLLING &&
|
||||
hkheartbeat - ses->client->last_read > ses->service->conn_idle_timeout * 10)
|
||||
if (all_session->service && all_session->client_dcb && all_session->client_dcb->state == DCB_STATE_POLLING &&
|
||||
hkheartbeat - all_session->client_dcb->last_read > all_session->service->conn_idle_timeout * 10)
|
||||
{
|
||||
dcb_close(ses->client);
|
||||
dcb_close(all_session->client_dcb);
|
||||
}
|
||||
|
||||
ses = ses->next;
|
||||
all_session = all_session->next;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
}
|
||||
@ -1037,20 +1030,20 @@ sessionRowCallback(RESULTSET *set, void *data)
|
||||
int i = 0;
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
SESSION *ptr;
|
||||
SESSION *list_session;
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
ptr = allSessions;
|
||||
list_session = allSessions;
|
||||
/* Skip to the first non-listener if not showing listeners */
|
||||
while (ptr && cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
ptr->state == SESSION_STATE_LISTENER)
|
||||
while (list_session && cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
list_session->state == SESSION_STATE_LISTENER)
|
||||
{
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
while (i < cbdata->index && ptr)
|
||||
while (i < cbdata->index && list_session)
|
||||
{
|
||||
if (cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
ptr->state != SESSION_STATE_LISTENER)
|
||||
list_session->state != SESSION_STATE_LISTENER)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
@ -1058,15 +1051,15 @@ sessionRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
/* Skip to the next non-listener if not showing listeners */
|
||||
while (ptr && cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
ptr->state == SESSION_STATE_LISTENER)
|
||||
while (list_session && cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
list_session->state == SESSION_STATE_LISTENER)
|
||||
{
|
||||
ptr = ptr->next;
|
||||
list_session = list_session->next;
|
||||
}
|
||||
if (ptr == NULL)
|
||||
if (list_session == NULL)
|
||||
{
|
||||
spinlock_release(&session_spin);
|
||||
free(data);
|
||||
@ -1074,14 +1067,14 @@ sessionRowCallback(RESULTSET *set, void *data)
|
||||
}
|
||||
cbdata->index++;
|
||||
row = resultset_make_row(set);
|
||||
snprintf(buf,19, "%p", ptr);
|
||||
snprintf(buf,19, "%p", list_session);
|
||||
buf[19] = '\0';
|
||||
resultset_row_set(row, 0, buf);
|
||||
resultset_row_set(row, 1, ((ptr->client && ptr->client->remote)
|
||||
? ptr->client->remote : ""));
|
||||
resultset_row_set(row, 2, (ptr->service && ptr->service->name
|
||||
? ptr->service->name : ""));
|
||||
resultset_row_set(row, 3, session_state(ptr->state));
|
||||
resultset_row_set(row, 1, ((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""));
|
||||
resultset_row_set(row, 2, (list_session->service && list_session->service->name
|
||||
? list_session->service->name : ""));
|
||||
resultset_row_set(row, 3, session_state(list_session->state));
|
||||
spinlock_release(&session_spin);
|
||||
return row;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ typedef struct servlistener
|
||||
struct servlistener *next; /**< Next service protocol */
|
||||
} SERV_LISTENER;
|
||||
|
||||
SERV_LISTENER *alloc_listener(char *protocol, char *address, unsigned short port, char *authenticator, SSL_LISTENER *ssl);
|
||||
SERV_LISTENER *listener_alloc(char *protocol, char *address, unsigned short port, char *authenticator, SSL_LISTENER *ssl);
|
||||
int listener_set_ssl_version(SSL_LISTENER *ssl_listener, char* version);
|
||||
void listener_set_certificates(SSL_LISTENER *ssl_listener, char* cert, char* key, char* ca_cert);
|
||||
int listener_init_SSL(SSL_LISTENER *ssl_listener);
|
||||
|
@ -129,8 +129,7 @@ typedef struct session
|
||||
session_state_t state; /*< Current descriptor state */
|
||||
size_t ses_id; /*< Unique session identifier */
|
||||
int enabled_log_priorities; /*< Bitfield of enabled syslog priorities */
|
||||
struct dcb *client; /*< The client connection */
|
||||
void *data; /*< The session data */
|
||||
struct dcb *client_dcb; /*< The client connection */
|
||||
void *router_session; /*< The router instance data */
|
||||
SESSION_STATS stats; /*< Session statistics */
|
||||
struct service *service; /*< The service this session is using */
|
||||
@ -153,7 +152,7 @@ extern bool check_timeouts;
|
||||
* hk_heartbeat.h */
|
||||
extern long next_timeout_check;
|
||||
|
||||
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client, type)
|
||||
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client_dcb, type)
|
||||
|
||||
/**
|
||||
* A convenience macro that can be used by the protocol modules to route
|
||||
|
@ -1429,15 +1429,15 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg)
|
||||
unsigned int errlen;
|
||||
|
||||
if (session == NULL || session->session == NULL ||
|
||||
session->session->data == NULL ||
|
||||
session->session->client == NULL)
|
||||
session->session->client_dcb == NULL ||
|
||||
session->session->client_dcb->data == NULL)
|
||||
{
|
||||
MXS_ERROR("Firewall filter session missing data.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dcb = session->session->client;
|
||||
mysql_session = (MYSQL_session*) session->session->data;
|
||||
dcb = session->session->client_dcb;
|
||||
mysql_session = (MYSQL_session*) dcb->data;
|
||||
errlen = msg != NULL ? strlen(msg) : 0;
|
||||
errmsg = (char*) malloc((512 + errlen) * sizeof(char));
|
||||
|
||||
@ -1955,7 +1955,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
|
||||
bool accept = my_instance->def_op;
|
||||
char *msg = NULL, *fullquery = NULL, *ipaddr;
|
||||
char uname_addr[128];
|
||||
DCB* dcb = my_session->session->client;
|
||||
DCB* dcb = my_session->session->client_dcb;
|
||||
USER* user = NULL;
|
||||
GWBUF* forward;
|
||||
ipaddr = strdup(dcb->remote);
|
||||
|
@ -992,7 +992,7 @@ newSession(FILTER *instance, SESSION *session)
|
||||
my_session->was_query = false;
|
||||
my_session->uid = NULL;
|
||||
my_session->session = session;
|
||||
sessauth = my_session->session->data;
|
||||
sessauth = my_session->session->client_dcb->data;
|
||||
if (sessauth->db && strnlen(sessauth->db, 128) > 0)
|
||||
{
|
||||
my_session->db = strdup(sessauth->db);
|
||||
|
@ -251,7 +251,7 @@ orphan_free(void* data)
|
||||
*/
|
||||
|
||||
if (ptr->session->state == SESSION_STATE_STOPPING &&
|
||||
ptr->session->refcount == 0 && ptr->session->client == NULL)
|
||||
ptr->session->refcount == 0 && ptr->session->client_dcb == NULL)
|
||||
{
|
||||
ptr->session->state = SESSION_STATE_TO_BE_FREED;
|
||||
}
|
||||
@ -485,7 +485,7 @@ newSession(FILTER *instance, SESSION *session)
|
||||
my_session->active = 1;
|
||||
my_session->residual = 0;
|
||||
my_session->tee_replybuf = NULL;
|
||||
my_session->client_dcb = session->client;
|
||||
my_session->client_dcb = session->client_dcb;
|
||||
my_session->instance = my_instance;
|
||||
my_session->client_multistatement = false;
|
||||
my_session->queue = NULL;
|
||||
@ -518,7 +518,7 @@ newSession(FILTER *instance, SESSION *session)
|
||||
FILTER_DEF* dummy;
|
||||
UPSTREAM* dummy_upstream;
|
||||
|
||||
if ((dcb = dcb_clone(session->client)) == NULL)
|
||||
if ((dcb = dcb_clone(session->client_dcb)) == NULL)
|
||||
{
|
||||
freeSession(instance, (void *) my_session);
|
||||
my_session = NULL;
|
||||
@ -578,7 +578,7 @@ newSession(FILTER *instance, SESSION *session)
|
||||
}
|
||||
|
||||
ses->tail = *dummy_upstream;
|
||||
MySQLProtocol* protocol = (MySQLProtocol*) session->client->protocol;
|
||||
MySQLProtocol* protocol = (MySQLProtocol*) session->client_dcb->protocol;
|
||||
my_session->use_ok = protocol->client_capabilities & (1 << 6);
|
||||
free(dummy_upstream);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ int dcbfun(struct dcb* dcb, GWBUF * buffer)
|
||||
int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){
|
||||
|
||||
|
||||
int i = 0,rval = 0;
|
||||
int i = 0,rval = 0;
|
||||
MYSQL_session* mysqlsess;
|
||||
DCB* dcb;
|
||||
char cwd[1024];
|
||||
@ -19,12 +19,12 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){
|
||||
if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){
|
||||
mxs_log_init(NULL,NULL,MXS_LOG_TARGET_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
if(!(instance.head = calloc(1,sizeof(FILTERCHAIN))))
|
||||
{
|
||||
printf("Error: Out of memory\n");
|
||||
MXS_ERROR("Out of memory\n");
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -41,26 +41,26 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){
|
||||
mysqlsess = calloc(1,sizeof(MYSQL_session));
|
||||
|
||||
sprintf(mysqlsess->user,"dummyuser");
|
||||
sprintf(mysqlsess->db,"dummydb");
|
||||
sprintf(mysqlsess->db,"dummydb");
|
||||
dcb->func.write = dcbfun;
|
||||
dcb->remote = strdup("0.0.0.0");
|
||||
dcb->user = strdup("user");
|
||||
instance.session->client = (void*)dcb;
|
||||
instance.session->data = (void*)mysqlsess;
|
||||
instance.session->client_dcb = (void*)dcb;
|
||||
instance.session->client_dcb->data = (void*)mysqlsess;
|
||||
|
||||
getcwd(cwd,sizeof(cwd));
|
||||
sprintf(tmp,"%s",cwd);
|
||||
|
||||
mxs_log_init(NULL, tmp, MXS_LOG_TARGET_DEFAULT);
|
||||
|
||||
|
||||
rval = process_opts(argc,argv);
|
||||
|
||||
|
||||
if(!(instance.thrpool = malloc(instance.thrcount * sizeof(pthread_t)))){
|
||||
printf("Error: Out of memory\n");
|
||||
MXS_ERROR("Out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Initialize worker threads*/
|
||||
pthread_mutex_lock(&instance.work_mtx);
|
||||
size_t thr_num = 1;
|
||||
@ -100,14 +100,14 @@ void free_buffers()
|
||||
if(instance.buffer){
|
||||
int i;
|
||||
for(i = 0;i<instance.buffer_count;i++){
|
||||
gwbuf_free(instance.buffer[i]);
|
||||
gwbuf_free(instance.buffer[i]);
|
||||
}
|
||||
free(instance.buffer);
|
||||
instance.buffer = NULL;
|
||||
instance.buffer_count = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(instance.infile >= 0){
|
||||
close(instance.infile);
|
||||
free(instance.infile_name);
|
||||
@ -167,7 +167,7 @@ FILTER_PARAMETER** read_params(int* paramc)
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(pc >= 64){
|
||||
do_read = 0;
|
||||
@ -183,7 +183,7 @@ FILTER_PARAMETER** read_params(int* paramc)
|
||||
}
|
||||
free(names[i]);
|
||||
free(values[i]);
|
||||
}
|
||||
}
|
||||
params[pc] = NULL;
|
||||
*paramc = pc;
|
||||
}
|
||||
@ -207,7 +207,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
|
||||
buffsz += strnlen(queue->hint->value,1024);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qstr = calloc(buffsz + 1,sizeof(char));
|
||||
|
||||
if(qstr){
|
||||
@ -235,7 +235,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
|
||||
case HINT_ROUTE_TO_ALL:
|
||||
sprintf(ptr,"|HINT_ROUTE_TO_ALL");
|
||||
break;
|
||||
|
||||
|
||||
case HINT_PARAMETER:
|
||||
sprintf(ptr,"|HINT_PARAMETER");
|
||||
break;
|
||||
@ -264,9 +264,9 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
|
||||
}
|
||||
|
||||
if(instance.verbose){
|
||||
printf("Query endpoint: %s\n", qstr);
|
||||
printf("Query endpoint: %s\n", qstr);
|
||||
}
|
||||
|
||||
|
||||
if(instance.outfile>=0){
|
||||
write(instance.outfile,qstr,strlen(qstr));
|
||||
write(instance.outfile,"\n",1);
|
||||
@ -279,7 +279,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
|
||||
|
||||
int clientReply(void* ins, void* session, GWBUF* queue)
|
||||
{
|
||||
|
||||
|
||||
if(instance.verbose){
|
||||
pthread_mutex_lock(&instance.work_mtx);
|
||||
unsigned char* ptr = (unsigned char*)queue->start;
|
||||
@ -291,13 +291,13 @@ int clientReply(void* ins, void* session, GWBUF* queue)
|
||||
printf("\n");
|
||||
pthread_mutex_unlock(&instance.work_mtx);
|
||||
}
|
||||
|
||||
|
||||
if(instance.outfile>=0){
|
||||
int qlen = queue->end - queue->start;
|
||||
write(instance.outfile,"Reply: ",strlen("Reply: "));
|
||||
write(instance.outfile,queue->start,qlen);
|
||||
write(instance.outfile,"\n",1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -313,7 +313,7 @@ int clientReply(void* ins, void* session, GWBUF* queue)
|
||||
int fdgets(int fd, char* buff, int size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
while(i < size - 1 && read(fd,&buff[i],1))
|
||||
{
|
||||
if(buff[i] == '\n' || buff[i] == '\0')
|
||||
@ -322,7 +322,7 @@ int fdgets(int fd, char* buff, int size)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
buff[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
@ -365,24 +365,24 @@ int load_query()
|
||||
rval = 1;
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
|
||||
query_list = tmpbuff;
|
||||
qbuff_sz *= 2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
query_list[qcount] = calloc((offset + 1),sizeof(char));
|
||||
strcpy(query_list[qcount],buffer);
|
||||
offset = 0;
|
||||
qcount++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**TODO check what messes up the first querystring*/
|
||||
GWBUF** tmpbff = malloc(sizeof(GWBUF*)*(qcount + 1));
|
||||
if(tmpbff){
|
||||
for(i = 0;i<qcount;i++){
|
||||
|
||||
|
||||
tmpbff[i] = gwbuf_alloc(strlen(query_list[i]) + 6);
|
||||
|
||||
if(tmpbff[i] == NULL)
|
||||
@ -413,7 +413,7 @@ int load_query()
|
||||
instance.buffer = tmpbff;
|
||||
}else{
|
||||
printf("Error: cannot allocate enough memory for buffers.\n");
|
||||
MXS_ERROR("cannot allocate enough memory for buffers.\n");
|
||||
MXS_ERROR("cannot allocate enough memory for buffers.\n");
|
||||
free_buffers();
|
||||
rval = 1;
|
||||
goto retblock;
|
||||
@ -423,7 +423,7 @@ int load_query()
|
||||
rval = 1;
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
|
||||
instance.buffer_count = qcount;
|
||||
|
||||
retblock:
|
||||
@ -478,7 +478,7 @@ int handler(void* user, const char* section, const char* name,
|
||||
|
||||
/**Section not found, creating a new one*/
|
||||
if(iter == NULL){
|
||||
|
||||
|
||||
CONFIG* nxt = malloc(sizeof(CONFIG));
|
||||
if(nxt && (nxt->item = malloc(sizeof(CONFIG_ITEM)))){
|
||||
nxt->section = strdup(section);
|
||||
@ -576,7 +576,7 @@ int load_config( char* fname)
|
||||
while(iter){
|
||||
item = iter->item;
|
||||
while(item){
|
||||
|
||||
|
||||
if(!strcmp("module",item->name)){
|
||||
|
||||
if(instance.mod_dir){
|
||||
@ -600,7 +600,7 @@ int load_config( char* fname)
|
||||
|
||||
}else{
|
||||
if(instance.verbose){
|
||||
printf("\t%s\n",iter->section);
|
||||
printf("\t%s\n",iter->section);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -620,7 +620,7 @@ int load_config( char* fname)
|
||||
item = instance.conf->item;
|
||||
}
|
||||
instance.conf = instance.conf->next;
|
||||
|
||||
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@ -629,7 +629,7 @@ int load_config( char* fname)
|
||||
instance.conf = instance.conf->next;
|
||||
item = iter->item;
|
||||
|
||||
while(item){
|
||||
while(item){
|
||||
free(item->name);
|
||||
free(item->value);
|
||||
free(item);
|
||||
@ -651,9 +651,9 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
int sess_err = 0;
|
||||
int x;
|
||||
if(cnf == NULL){
|
||||
|
||||
|
||||
fparams = read_params(¶mc);
|
||||
|
||||
|
||||
}else{
|
||||
|
||||
CONFIG* iter = cnf;
|
||||
@ -661,14 +661,14 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
while(iter){
|
||||
paramc = -1;
|
||||
item = iter->item;
|
||||
|
||||
|
||||
while(item){
|
||||
|
||||
/**Matching configuration found*/
|
||||
if(!strcmp(item->name,"module") && !strcmp(item->value,fc->name)){
|
||||
paramc = 0;
|
||||
item = iter->item;
|
||||
|
||||
|
||||
while(item){
|
||||
if(strcmp(item->name,"module") && strcmp(item->name,"type")){
|
||||
paramc++;
|
||||
@ -678,7 +678,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
item = iter->item;
|
||||
fparams = calloc((paramc + 1),sizeof(FILTER_PARAMETER*));
|
||||
if(fparams){
|
||||
|
||||
|
||||
int i = 0;
|
||||
while(item){
|
||||
if(strcmp(item->name,"module") != 0 &&
|
||||
@ -740,7 +740,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
MXS_WARNING("The filter %s does not support client replies.\n",fc->name);
|
||||
}
|
||||
|
||||
if(fc->next && fc->next->next){
|
||||
if(fc->next && fc->next->next){
|
||||
|
||||
fc->down[i]->routeQuery = (void*)fc->next->instance->routeQuery;
|
||||
fc->down[i]->session = fc->next->session[i];
|
||||
@ -775,7 +775,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(sess_err){
|
||||
for(i = 0;i<instance.session_count;i++){
|
||||
if(fc->filter && fc->session[i]){
|
||||
@ -788,9 +788,9 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
free(fc->name);
|
||||
free(fc);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
error:
|
||||
error:
|
||||
|
||||
|
||||
if(fparams){
|
||||
@ -809,9 +809,9 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
FILTERCHAIN* load_filter_module(char* str)
|
||||
{
|
||||
FILTERCHAIN* flt_ptr = NULL;
|
||||
if((flt_ptr = calloc(1,sizeof(FILTERCHAIN))) != NULL &&
|
||||
if((flt_ptr = calloc(1,sizeof(FILTERCHAIN))) != NULL &&
|
||||
(flt_ptr->session = calloc(instance.session_count,sizeof(SESSION*))) != NULL &&
|
||||
(flt_ptr->down = calloc(instance.session_count,sizeof(DOWNSTREAM*))) != NULL &&
|
||||
(flt_ptr->down = calloc(instance.session_count,sizeof(DOWNSTREAM*))) != NULL &&
|
||||
(flt_ptr->up = calloc(instance.session_count,sizeof(UPSTREAM*))) != NULL){
|
||||
flt_ptr->next = instance.head;
|
||||
}
|
||||
@ -839,7 +839,7 @@ void route_buffers()
|
||||
fin = instance.buffer_count*instance.session_count,
|
||||
step = (fin/50.f)/fin;
|
||||
FILTERCHAIN* fc = instance.head;
|
||||
|
||||
|
||||
while(fc->next->next){
|
||||
fc = fc->next;
|
||||
}
|
||||
@ -866,7 +866,7 @@ void route_buffers()
|
||||
while(instance.last_ind < instance.session_count){
|
||||
struct timespec ts1;
|
||||
ts1.tv_sec = 0;
|
||||
|
||||
|
||||
tprg = ((bprg + (float)instance.last_ind)/fin);
|
||||
if(!instance.verbose){
|
||||
if(tprg >= trig){
|
||||
@ -883,7 +883,7 @@ void route_buffers()
|
||||
instance.sess_ind = 0;
|
||||
instance.last_ind = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
if(!instance.verbose){
|
||||
@ -911,7 +911,7 @@ void work_buffer(void* thr_num)
|
||||
instance.buff_ind < instance.buffer_count)
|
||||
{
|
||||
struct timespec ts1;
|
||||
ts1.tv_sec = 0;
|
||||
ts1.tv_sec = 0;
|
||||
|
||||
if(instance.head->instance->routeQuery(instance.head->filter,
|
||||
|
||||
@ -954,7 +954,7 @@ GWBUF* gen_packet(PACKET pkt)
|
||||
if(psize > 0){
|
||||
buff = gwbuf_alloc(psize);
|
||||
ptr = (unsigned char*)buff->start;
|
||||
|
||||
|
||||
switch(pkt){
|
||||
case PACKET_OK:
|
||||
|
||||
@ -1007,8 +1007,8 @@ int process_opts(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( (rval = lseek(fd,0,SEEK_END)) < 0 ||
|
||||
|
||||
if( (rval = lseek(fd,0,SEEK_END)) < 0 ||
|
||||
lseek(fd,0,SEEK_SET) < 0){
|
||||
printf("Error: Cannot seek file.\n");
|
||||
close(fd);
|
||||
@ -1033,9 +1033,9 @@ int process_opts(int argc, char** argv)
|
||||
}
|
||||
tok = strtok_r(NULL,"=",&saveptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
free(buff);
|
||||
instance.verbose = 1;
|
||||
|
||||
@ -1114,7 +1114,7 @@ int process_opts(int argc, char** argv)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -549,3 +549,4 @@ static int combined_auth_check(
|
||||
auth_ret = check_db_name_after_auth(dcb, database, auth_ret);
|
||||
return auth_ret;
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb)
|
||||
|
||||
if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY)
|
||||
{
|
||||
auth_info = dcb->session->data;
|
||||
auth_info = dcb->session->client_dcb->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -549,8 +549,8 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
* still listening the socket for replies.
|
||||
*/
|
||||
if (dcb->session->state == SESSION_STATE_ROUTER_READY &&
|
||||
dcb->session->client != NULL &&
|
||||
dcb->session->client->state == DCB_STATE_POLLING &&
|
||||
dcb->session->client_dcb != NULL &&
|
||||
dcb->session->client_dcb->state == DCB_STATE_POLLING &&
|
||||
(session->router_session || router->getCapabilities() & RCAP_TYPE_NO_RSESSION))
|
||||
{
|
||||
client_protocol = SESSION_PROTOCOL(dcb->session,
|
||||
@ -571,7 +571,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
}
|
||||
goto return_rc;
|
||||
}
|
||||
else if (dcb->session->client->dcb_role == DCB_ROLE_INTERNAL)
|
||||
else if (dcb->session->client_dcb->dcb_role == DCB_ROLE_INTERNAL)
|
||||
{
|
||||
gwbuf_set_type(read_buffer, GWBUF_TYPE_MYSQL);
|
||||
router->clientReply(router_instance, session->router_session, read_buffer, dcb);
|
||||
@ -614,14 +614,14 @@ static int gw_write_backend_event(DCB *dcb)
|
||||
{
|
||||
data = (uint8_t *)GWBUF_DATA(dcb->writeq);
|
||||
|
||||
if (dcb->session->client == NULL)
|
||||
if (dcb->session->client_dcb == NULL)
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
else if (!(MYSQL_IS_COM_QUIT(data)))
|
||||
{
|
||||
/*< vraa : errorHandle */
|
||||
mysql_send_custom_error(dcb->session->client,
|
||||
mysql_send_custom_error(dcb->session->client_dcb,
|
||||
1,
|
||||
0,
|
||||
"Writing to backend failed due invalid Maxscale "
|
||||
@ -937,14 +937,14 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
}
|
||||
|
||||
/** Copy client flags to backend protocol */
|
||||
if (backend_dcb->session->client->protocol)
|
||||
if (backend_dcb->session->client_dcb->protocol)
|
||||
{
|
||||
/** Copy client flags to backend protocol */
|
||||
protocol->client_capabilities =
|
||||
((MySQLProtocol *)(backend_dcb->session->client->protocol))->client_capabilities;
|
||||
((MySQLProtocol *)(backend_dcb->session->client_dcb->protocol))->client_capabilities;
|
||||
/** Copy client charset to backend protocol */
|
||||
protocol->charset =
|
||||
((MySQLProtocol *)(backend_dcb->session->client->protocol))->charset;
|
||||
((MySQLProtocol *)(backend_dcb->session->client_dcb->protocol))->charset;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -971,7 +971,7 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
session->client_dcb->fd);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@ -984,7 +984,7 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
session->client_dcb->fd);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -996,7 +996,7 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
session->client_dcb->fd);
|
||||
break;
|
||||
} /*< switch */
|
||||
|
||||
@ -1148,7 +1148,7 @@ static int gw_backend_close(DCB *dcb)
|
||||
CHK_SESSION(session);
|
||||
/**
|
||||
* The lock is needed only to protect the read of session->state and
|
||||
* session->client values. Client's state may change by other thread
|
||||
* session->client_dcb values. Client's state may change by other thread
|
||||
* but client's close and adding client's DCB to zombies list is executed
|
||||
* only if client's DCB's state does _not_ change in parallel.
|
||||
*/
|
||||
@ -1158,16 +1158,16 @@ static int gw_backend_close(DCB *dcb)
|
||||
* Otherwise only this backend connection is closed.
|
||||
*/
|
||||
if (session->state == SESSION_STATE_STOPPING &&
|
||||
session->client != NULL)
|
||||
session->client_dcb != NULL)
|
||||
{
|
||||
if (session->client->state == DCB_STATE_POLLING)
|
||||
if (session->client_dcb->state == DCB_STATE_POLLING)
|
||||
{
|
||||
DCB *temp;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
/** Close client DCB */
|
||||
temp = session->client;
|
||||
session->client = NULL;
|
||||
temp = session->client_dcb;
|
||||
session->client_dcb = NULL;
|
||||
dcb_close(temp);
|
||||
}
|
||||
else
|
||||
@ -1243,7 +1243,7 @@ static int backend_write_delayqueue(DCB *dcb)
|
||||
MYSQL_session* mses;
|
||||
GWBUF* new_packet;
|
||||
|
||||
mses = (MYSQL_session *)dcb->session->client->data;
|
||||
mses = (MYSQL_session *)dcb->session->client_dcb->data;
|
||||
new_packet = gw_create_change_user_packet(mses,
|
||||
(MySQLProtocol *)dcb->protocol);
|
||||
/**
|
||||
@ -1327,9 +1327,9 @@ static int gw_change_user(DCB *backend,
|
||||
int rv = -1;
|
||||
int auth_ret = 1;
|
||||
|
||||
current_session = (MYSQL_session *)in_session->client->data;
|
||||
current_session = (MYSQL_session *)in_session->client_dcb->data;
|
||||
backend_protocol = backend->protocol;
|
||||
client_protocol = in_session->client->protocol;
|
||||
client_protocol = in_session->client_dcb->protocol;
|
||||
|
||||
/* now get the user, after 4 bytes header and 1 byte command */
|
||||
client_auth_packet += 5;
|
||||
@ -1386,7 +1386,7 @@ static int gw_change_user(DCB *backend,
|
||||
* decode the token and check the password.
|
||||
* Note: if auth_token_len == 0 && auth_token == NULL, user is without password
|
||||
*/
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client,
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client_dcb,
|
||||
auth_token,
|
||||
auth_token_len,
|
||||
client_protocol->scramble,
|
||||
@ -1396,11 +1396,11 @@ static int gw_change_user(DCB *backend,
|
||||
|
||||
if (auth_ret != 0)
|
||||
{
|
||||
if (!service_refresh_users(backend->session->client->service))
|
||||
if (!service_refresh_users(backend->session->client_dcb->service))
|
||||
{
|
||||
/* Try authentication again with new repository data */
|
||||
/* Note: if no auth client authentication will fail */
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client,
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client_dcb,
|
||||
auth_token, auth_token_len,
|
||||
client_protocol->scramble,
|
||||
sizeof(client_protocol->scramble),
|
||||
@ -1441,7 +1441,7 @@ static int gw_change_user(DCB *backend,
|
||||
* reply to the client.
|
||||
*/
|
||||
message = create_auth_fail_str(username,
|
||||
backend->session->client->remote,
|
||||
backend->session->client_dcb->remote,
|
||||
password_set,
|
||||
"",
|
||||
auth_ret);
|
||||
|
@ -542,14 +542,8 @@ int gw_read_client_event(DCB* dcb)
|
||||
protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
|
||||
mysql_client_auth_error_handling(dcb, auth_val);
|
||||
/**
|
||||
* Release MYSQL_session since it is not used anymore.
|
||||
* Close DCB and which will release MYSQL_session
|
||||
*/
|
||||
if (!DCB_IS_CLONE(dcb))
|
||||
{
|
||||
free(dcb->data);
|
||||
}
|
||||
dcb->data = NULL;
|
||||
|
||||
dcb_close(dcb);
|
||||
}
|
||||
/* One way or another, the buffer is now fully processed */
|
||||
|
@ -1282,7 +1282,7 @@ int gw_send_change_user_to_backend(char *dbname,
|
||||
int rc;
|
||||
MYSQL_session* mses;
|
||||
|
||||
mses = (MYSQL_session*)conn->owner_dcb->session->client->data;
|
||||
mses = (MYSQL_session*)conn->owner_dcb->session->client_dcb->data;
|
||||
buffer = gw_create_change_user_packet(mses, conn);
|
||||
rc = conn->owner_dcb->func.write(conn->owner_dcb, buffer);
|
||||
|
||||
|
@ -184,7 +184,7 @@ GetModuleObject()
|
||||
* The process of creating the instance causes the router to register
|
||||
* with the master server and begin replication of the binlogs from
|
||||
* the master server to MaxScale.
|
||||
*
|
||||
*
|
||||
* @param service The service this router is being create for
|
||||
* @param options An array of options for this query router
|
||||
*
|
||||
@ -456,7 +456,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
break;
|
||||
}
|
||||
inst->burst_size = size;
|
||||
|
||||
|
||||
}
|
||||
else if (strcmp(options[i], "heartbeat") == 0)
|
||||
{
|
||||
@ -614,7 +614,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
" Fix errors in it or configure with CHANGE MASTER TO ...",
|
||||
inst->service->name, inst->binlogdir);
|
||||
}
|
||||
|
||||
|
||||
/* Set service user or load db users */
|
||||
blr_set_service_mysql_user(inst->service);
|
||||
|
||||
@ -626,7 +626,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the binlog router
|
||||
* Initialise the binlog router
|
||||
*/
|
||||
if (inst->master_state == BLRM_UNCONNECTED) {
|
||||
|
||||
@ -754,7 +754,7 @@ ROUTER_SLAVE *slave;
|
||||
slave->uuid = NULL;
|
||||
slave->hostname = NULL;
|
||||
spinlock_init(&slave->catch_lock);
|
||||
slave->dcb = session->client;
|
||||
slave->dcb = session->client_dcb;
|
||||
slave->router = inst;
|
||||
#ifdef BLFILE_IN_SLAVE
|
||||
slave->file = NULL;
|
||||
@ -775,7 +775,7 @@ ROUTER_SLAVE *slave;
|
||||
spinlock_release(&inst->lock);
|
||||
|
||||
CHK_CLIENT_RSES(slave);
|
||||
|
||||
|
||||
return (void *)slave;
|
||||
}
|
||||
|
||||
@ -798,10 +798,10 @@ static void freeSession(
|
||||
ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)router_instance;
|
||||
ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_client_ses;
|
||||
int prev_val;
|
||||
|
||||
|
||||
prev_val = atomic_add(&router->stats.n_slaves, -1);
|
||||
ss_dassert(prev_val > 0);
|
||||
|
||||
|
||||
/*
|
||||
* Remove the slave session form the list of slaves that are using the
|
||||
* router currently.
|
||||
@ -811,11 +811,11 @@ int prev_val;
|
||||
router->slaves = slave->next;
|
||||
} else {
|
||||
ROUTER_SLAVE *ptr = router->slaves;
|
||||
|
||||
|
||||
while (ptr != NULL && ptr->next != slave) {
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
|
||||
if (ptr != NULL) {
|
||||
ptr->next = slave->next;
|
||||
}
|
||||
@ -846,7 +846,7 @@ int prev_val;
|
||||
* @param instance The router instance data
|
||||
* @param router_session The session being closed
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
closeSession(ROUTER *instance, void *router_session)
|
||||
{
|
||||
ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)instance;
|
||||
@ -927,12 +927,12 @@ ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_session;
|
||||
* @param queue The queue of data buffers to route
|
||||
* @return The number of bytes sent
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
routeQuery(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
{
|
||||
ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)instance;
|
||||
ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_session;
|
||||
|
||||
|
||||
return blr_slave_request(router, slave, queue);
|
||||
}
|
||||
|
||||
@ -1020,7 +1020,7 @@ struct tm tm;
|
||||
min15 /= 15.0;
|
||||
min10 /= 10.0;
|
||||
min5 /= 5.0;
|
||||
|
||||
|
||||
if (router_inst->master)
|
||||
dcb_printf(dcb, "\tMaster connection DCB: %p\n",
|
||||
router_inst->master);
|
||||
@ -1032,7 +1032,7 @@ struct tm tm;
|
||||
|
||||
localtime_r(&router_inst->stats.lastReply, &tm);
|
||||
asctime_r(&tm, buf);
|
||||
|
||||
|
||||
dcb_printf(dcb, "\tBinlog directory: %s\n",
|
||||
router_inst->binlogdir);
|
||||
dcb_printf(dcb, "\tHeartbeat period (seconds): %lu\n",
|
||||
@ -1046,7 +1046,7 @@ struct tm tm;
|
||||
dcb_printf(dcb, "\tCurrent binlog position: %lu\n",
|
||||
router_inst->current_pos);
|
||||
if (router_inst->trx_safe) {
|
||||
if (router_inst->pending_transaction) {
|
||||
if (router_inst->pending_transaction) {
|
||||
dcb_printf(dcb, "\tCurrent open transaction pos: %lu\n",
|
||||
router_inst->binlog_position);
|
||||
}
|
||||
@ -1273,7 +1273,7 @@ struct tm tm;
|
||||
}
|
||||
else if ((session->cstate & CS_UPTODATE) == 0)
|
||||
{
|
||||
dcb_printf(dcb, "\t\tSlave_mode: catchup. %s%s\n",
|
||||
dcb_printf(dcb, "\t\tSlave_mode: catchup. %s%s\n",
|
||||
((session->cstate & CS_EXPECTCB) == 0 ? "" :
|
||||
"Waiting for DCB queue to drain."),
|
||||
((session->cstate & CS_BUSY) == 0 ? "" :
|
||||
@ -1426,35 +1426,35 @@ unsigned long mysql_errno;
|
||||
}
|
||||
|
||||
/** to be inline'd */
|
||||
/**
|
||||
/**
|
||||
* @node Acquires lock to router client session if it is not closed.
|
||||
*
|
||||
* Parameters:
|
||||
* @param rses - in, use
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return true if router session was not closed. If return value is true
|
||||
* it means that router is locked, and must be unlocked later. False, if
|
||||
* router was closed before lock was acquired.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
static bool rses_begin_locked_router_action(ROUTER_SLAVE *rses)
|
||||
{
|
||||
bool succp = false;
|
||||
|
||||
|
||||
CHK_CLIENT_RSES(rses);
|
||||
|
||||
spinlock_acquire(&rses->rses_lock);
|
||||
succp = true;
|
||||
|
||||
|
||||
return succp;
|
||||
}
|
||||
|
||||
/** to be inline'd */
|
||||
/**
|
||||
/**
|
||||
* @node Releases router client session lock.
|
||||
*
|
||||
* Parameters:
|
||||
@ -1463,7 +1463,7 @@ static bool rses_begin_locked_router_action(ROUTER_SLAVE *rses)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
@ -1569,7 +1569,7 @@ GWBUF *ret;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 1;
|
||||
*ptr = 0; // OK
|
||||
*ptr = 0; // OK
|
||||
|
||||
return slave->dcb->func.write(slave->dcb, ret);
|
||||
}
|
||||
@ -1591,7 +1591,7 @@ GWBUF *ret;
|
||||
*
|
||||
*/
|
||||
int
|
||||
blr_send_custom_error(DCB *dcb, int packet_number, int affected_rows, char *msg, char *statemsg, unsigned int errcode)
|
||||
blr_send_custom_error(DCB *dcb, int packet_number, int affected_rows, char *msg, char *statemsg, unsigned int errcode)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
uint32_t mysql_payload_size = 0;
|
||||
@ -1604,8 +1604,8 @@ unsigned int mysql_errno = 0;
|
||||
const char *mysql_error_msg = NULL;
|
||||
const char *mysql_state = NULL;
|
||||
GWBUF *errbuf = NULL;
|
||||
|
||||
if (errcode == 0)
|
||||
|
||||
if (errcode == 0)
|
||||
mysql_errno = 1064;
|
||||
else
|
||||
mysql_errno = errcode;
|
||||
@ -1615,52 +1615,52 @@ GWBUF *errbuf = NULL;
|
||||
mysql_state = "42000";
|
||||
else
|
||||
mysql_state = statemsg;
|
||||
|
||||
|
||||
field_count = 0xff;
|
||||
gw_mysql_set_byte2(mysql_err, mysql_errno);
|
||||
mysql_statemsg[0]='#';
|
||||
memcpy(mysql_statemsg+1, mysql_state, 5);
|
||||
|
||||
|
||||
if (msg != NULL) {
|
||||
mysql_error_msg = msg;
|
||||
}
|
||||
|
||||
mysql_payload_size = sizeof(field_count) +
|
||||
sizeof(mysql_err) +
|
||||
sizeof(mysql_statemsg) +
|
||||
|
||||
mysql_payload_size = sizeof(field_count) +
|
||||
sizeof(mysql_err) +
|
||||
sizeof(mysql_statemsg) +
|
||||
strlen(mysql_error_msg);
|
||||
|
||||
|
||||
/** allocate memory for packet header + payload */
|
||||
errbuf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size);
|
||||
ss_dassert(errbuf != NULL);
|
||||
|
||||
|
||||
if (errbuf == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
outbuf = GWBUF_DATA(errbuf);
|
||||
|
||||
|
||||
/** write packet header and packet number */
|
||||
gw_mysql_set_byte3(mysql_packet_header, mysql_payload_size);
|
||||
mysql_packet_header[3] = packet_number;
|
||||
|
||||
|
||||
/** write header */
|
||||
memcpy(outbuf, mysql_packet_header, sizeof(mysql_packet_header));
|
||||
|
||||
|
||||
mysql_payload = outbuf + sizeof(mysql_packet_header);
|
||||
|
||||
|
||||
/** write field */
|
||||
memcpy(mysql_payload, &field_count, sizeof(field_count));
|
||||
mysql_payload = mysql_payload + sizeof(field_count);
|
||||
|
||||
|
||||
/** write errno */
|
||||
memcpy(mysql_payload, mysql_err, sizeof(mysql_err));
|
||||
mysql_payload = mysql_payload + sizeof(mysql_err);
|
||||
|
||||
|
||||
/** write sqlstate */
|
||||
memcpy(mysql_payload, mysql_statemsg, sizeof(mysql_statemsg));
|
||||
mysql_payload = mysql_payload + sizeof(mysql_statemsg);
|
||||
|
||||
|
||||
/** write error message */
|
||||
memcpy(mysql_payload, mysql_error_msg, strlen(mysql_error_msg));
|
||||
|
||||
|
@ -121,7 +121,7 @@ GetModuleObject()
|
||||
/**
|
||||
* Create an instance of the router for a particular service
|
||||
* within the gateway.
|
||||
*
|
||||
*
|
||||
* @param service The service this router is being create for
|
||||
* @param options Any array of options for the query router
|
||||
*
|
||||
@ -202,14 +202,14 @@ CLI_SESSION *client;
|
||||
session->state = SESSION_STATE_READY;
|
||||
client->mode = inst->mode;
|
||||
|
||||
dcb_printf(session->client, "Welcome the MariaDB Corporation MaxScale Debug Interface (%s).\n",
|
||||
dcb_printf(session->client_dcb, "Welcome the MariaDB Corporation MaxScale Debug Interface (%s).\n",
|
||||
version_str);
|
||||
if (client->mode == CLIM_DEVELOPER)
|
||||
{
|
||||
dcb_printf(session->client, "WARNING: This interface is meant for developer usage,\n");
|
||||
dcb_printf(session->client, "passing incorrect addresses to commands can endanger your MaxScale server.\n\n");
|
||||
dcb_printf(session->client_dcb, "WARNING: This interface is meant for developer usage,\n");
|
||||
dcb_printf(session->client_dcb, "passing incorrect addresses to commands can endanger your MaxScale server.\n\n");
|
||||
}
|
||||
dcb_printf(session->client, "Type help for a list of available commands.\n\n");
|
||||
dcb_printf(session->client_dcb, "Type help for a list of available commands.\n\n");
|
||||
|
||||
return (void *)client;
|
||||
}
|
||||
@ -221,7 +221,7 @@ CLI_SESSION *client;
|
||||
* @param instance The router instance data
|
||||
* @param router_session The session being closed
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
closeSession(ROUTER *instance, void *router_session)
|
||||
{
|
||||
CLI_INSTANCE *inst = (CLI_INSTANCE *)instance;
|
||||
@ -270,7 +270,7 @@ static void freeSession(
|
||||
* @param queue The queue of data buffers to route
|
||||
* @return The number of bytes sent
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
execute(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
{
|
||||
CLI_SESSION *session = (CLI_SESSION *)router_session;
|
||||
@ -285,9 +285,9 @@ CLI_SESSION *session = (CLI_SESSION *)router_session;
|
||||
if (strrchr(session->cmdbuf, '\n'))
|
||||
{
|
||||
if (execute_cmd(session))
|
||||
dcb_printf(session->session->client, "MaxScale> ");
|
||||
dcb_printf(session->session->client_dcb, "MaxScale> ");
|
||||
else
|
||||
dcb_close(session->session->client);
|
||||
dcb_close(session->session->client_dcb);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ convert_arg(int mode, char *arg, int arg_type)
|
||||
int
|
||||
execute_cmd(CLI_SESSION *cli)
|
||||
{
|
||||
DCB *dcb = cli->session->client;
|
||||
DCB *dcb = cli->session->client_dcb;
|
||||
int argc, i, j, found = 0;
|
||||
char *args[MAXARGS + 1];
|
||||
unsigned long arg1, arg2, arg3;
|
||||
|
@ -147,7 +147,7 @@ GetModuleObject()
|
||||
/**
|
||||
* Create an instance of the router for a particular service
|
||||
* within the gateway.
|
||||
*
|
||||
*
|
||||
* @param service The service this router is being create for
|
||||
* @param options Any array of options for the query router
|
||||
*
|
||||
@ -211,7 +211,7 @@ INFO_SESSION *client;
|
||||
return NULL;
|
||||
}
|
||||
client->session = session;
|
||||
client->dcb = session->client;
|
||||
client->dcb = session->client_dcb;
|
||||
client->queue = NULL;
|
||||
|
||||
spinlock_acquire(&inst->lock);
|
||||
@ -231,7 +231,7 @@ INFO_SESSION *client;
|
||||
* @param instance The router instance data
|
||||
* @param router_session The session being closed
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
closeSession(ROUTER *instance, void *router_session)
|
||||
{
|
||||
INFO_INSTANCE *inst = (INFO_INSTANCE *)instance;
|
||||
@ -309,19 +309,19 @@ static void handleError(
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
sesstate = session->state;
|
||||
client_dcb = session->client;
|
||||
|
||||
client_dcb = session->client_dcb;
|
||||
|
||||
if (sesstate == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
CHK_DCB(client_dcb);
|
||||
spinlock_release(&session->ses_lock);
|
||||
spinlock_release(&session->ses_lock);
|
||||
client_dcb->func.write(client_dcb, gwbuf_clone(errbuf));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
|
||||
/** false because connection is not available anymore */
|
||||
dcb_close(backend_dcb);
|
||||
*succp = false;
|
||||
@ -336,7 +336,7 @@ static void handleError(
|
||||
* @param queue The queue of data buffers to route
|
||||
* @return The number of bytes sent
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
execute(ROUTER *rinstance, void *router_session, GWBUF *queue)
|
||||
{
|
||||
INFO_INSTANCE *instance = (INFO_INSTANCE *)rinstance;
|
||||
@ -471,7 +471,7 @@ int len;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 0;
|
||||
*ptr++ = 1;
|
||||
*ptr = 0; // OK
|
||||
*ptr = 0; // OK
|
||||
|
||||
return session->dcb->func.write(session->dcb, ret);
|
||||
}
|
||||
@ -501,7 +501,7 @@ RESULT_ROW *row;
|
||||
|
||||
/**
|
||||
* The hardwired select @@vercom response
|
||||
*
|
||||
*
|
||||
* @param dcb The DCB of the client
|
||||
*/
|
||||
static void
|
||||
@ -549,7 +549,7 @@ static char buf[40];
|
||||
|
||||
/**
|
||||
* The hardwired select ... as starttime response
|
||||
*
|
||||
*
|
||||
* @param dcb The DCB of the client
|
||||
*/
|
||||
static void
|
||||
@ -705,7 +705,7 @@ static struct uri_table {
|
||||
* @param queue The queue of data buffers to route
|
||||
* @return The number of bytes sent
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
handle_url(INFO_INSTANCE *instance, INFO_SESSION *session, GWBUF *queue)
|
||||
{
|
||||
char *uri;
|
||||
|
@ -847,7 +847,7 @@ diagnostics(ROUTER *router, DCB *dcb)
|
||||
static void
|
||||
clientReply(ROUTER *instance, void *router_session, GWBUF *queue, DCB *backend_dcb)
|
||||
{
|
||||
ss_dassert(backend_dcb->session->client != NULL);
|
||||
ss_dassert(backend_dcb->session->client_dcb != NULL);
|
||||
SESSION_ROUTE_REPLY(backend_dcb->session, queue);
|
||||
}
|
||||
|
||||
@ -886,7 +886,7 @@ static void handleError(ROUTER *instance, void *router_session, GWBUF *errbuf,
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
sesstate = session->state;
|
||||
client_dcb = session->client;
|
||||
client_dcb = session->client_dcb;
|
||||
|
||||
if (sesstate == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -985,8 +985,8 @@ static void* newSession(ROUTER* router_inst, SESSION* session)
|
||||
int router_nservers = 0; /*< # of servers in total */
|
||||
int i;
|
||||
char db[MYSQL_DATABASE_MAXLEN+1];
|
||||
MySQLProtocol* protocol = session->client->protocol;
|
||||
MYSQL_session* data = session->data;
|
||||
MySQLProtocol* protocol = session->client_dcb->protocol;
|
||||
MYSQL_session* data = session->client_dcb->data;
|
||||
bool using_db = false;
|
||||
bool have_db = false;
|
||||
|
||||
@ -1027,12 +1027,12 @@ static void* newSession(ROUTER* router_inst, SESSION* session)
|
||||
#endif
|
||||
|
||||
client_rses->router = router;
|
||||
client_rses->rses_mysql_session = (MYSQL_session*)session->data;
|
||||
client_rses->rses_client_dcb = (DCB*)session->client;
|
||||
client_rses->rses_mysql_session = (MYSQL_session*)session->client_dcb->data;
|
||||
client_rses->rses_client_dcb = (DCB*)session->client_dcb;
|
||||
|
||||
spinlock_acquire(&router->lock);
|
||||
|
||||
shard_map_t *map = hashtable_fetch(router->shard_maps, session->client->user);
|
||||
shard_map_t *map = hashtable_fetch(router->shard_maps, session->client_dcb->user);
|
||||
enum shard_map_state state;
|
||||
|
||||
if (map)
|
||||
@ -2496,7 +2496,7 @@ static void clientReply(ROUTER* instance,
|
||||
}
|
||||
/** Holding lock ensures that router session remains open */
|
||||
ss_dassert(backend_dcb->session != NULL);
|
||||
client_dcb = backend_dcb->session->client;
|
||||
client_dcb = backend_dcb->session->client_dcb;
|
||||
|
||||
/** Unlock */
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
@ -3978,7 +3978,7 @@ static void handle_error_reply_client(SESSION* ses,
|
||||
|
||||
spinlock_acquire(&ses->ses_lock);
|
||||
sesstate = ses->state;
|
||||
client_dcb = ses->client;
|
||||
client_dcb = ses->client_dcb;
|
||||
spinlock_release(&ses->ses_lock);
|
||||
|
||||
/**
|
||||
@ -4069,7 +4069,7 @@ static bool handle_error_new_connection(ROUTER_INSTANCE* inst,
|
||||
if (BREF_IS_WAITING_RESULT(bref))
|
||||
{
|
||||
DCB* client_dcb;
|
||||
client_dcb = ses->client;
|
||||
client_dcb = ses->client_dcb;
|
||||
client_dcb->func.write(client_dcb, gwbuf_clone(errmsg));
|
||||
bref_clear_state(bref, BREF_WAITING_RESULT);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ MODULE_INFO info = {
|
||||
|
||||
|
||||
/**
|
||||
* @file shardrouter.c
|
||||
* @file shardrouter.c
|
||||
*
|
||||
* This is the sharding router that uses MaxScale's services to abstract
|
||||
* the actual implementation of the backend database. Queries are routed based on
|
||||
@ -364,13 +364,13 @@ parse_mapping_response(ROUTER_CLIENT_SES* rses, char* target, GWBUF* buf)
|
||||
*/
|
||||
bool subsvc_is_valid(SUBSERVICE* sub)
|
||||
{
|
||||
|
||||
if(sub->session == NULL ||
|
||||
|
||||
if(sub->session == NULL ||
|
||||
sub->service->router == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
spinlock_acquire(&sub->session->ses_lock);
|
||||
session_state_t ses_state = sub->session->state;
|
||||
spinlock_release(&sub->session->ses_lock);
|
||||
@ -420,7 +420,7 @@ gen_subsvc_dblist(ROUTER_INSTANCE* inst, ROUTER_CLIENT_SES* session)
|
||||
if(SUBSVC_IS_OK(session->subservice[i]))
|
||||
{
|
||||
clone = gwbuf_clone(buffer);
|
||||
|
||||
|
||||
rval |= !SESSION_ROUTE_QUERY(session->subservice[i]->session,clone);
|
||||
subsvc_set_state(session->subservice[i],SUBSVC_WAITING_RESULT|SUBSVC_QUERY_ACTIVE);
|
||||
}
|
||||
@ -485,7 +485,7 @@ get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF*
|
||||
MXS_INFO("shardrouter: SHOW TABLES with specific database '%s' on server '%s'", tok, tmp);
|
||||
}
|
||||
free(query);
|
||||
|
||||
|
||||
if(tmp == NULL)
|
||||
{
|
||||
rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db);
|
||||
@ -494,12 +494,12 @@ get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF*
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = tmp;
|
||||
rval = tmp;
|
||||
has_dbs = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(buffer->hint && buffer->hint->type == HINT_ROUTE_TO_NAMED_SERVER)
|
||||
{
|
||||
for(i = 0; i < client->n_subservice; i++)
|
||||
@ -512,14 +512,14 @@ get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF*
|
||||
{
|
||||
rval = srvrf->server->unique_name;
|
||||
MXS_INFO("shardrouter: Routing hint found (%s)",rval);
|
||||
|
||||
|
||||
}
|
||||
srvrf = srvrf->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(rval == NULL && !has_dbs && client->rses_mysql_session->db[0] != '\0')
|
||||
{
|
||||
/**
|
||||
@ -533,7 +533,7 @@ get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF*
|
||||
MXS_INFO("shardrouter: Using active database '%s'",client->rses_mysql_session->db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -730,7 +730,7 @@ filterReply(FILTER* instance, void *session, GWBUF *reply)
|
||||
|
||||
/**
|
||||
* This function reads the DCB's readqueue and sends it as a reply to the session
|
||||
* who owns the DCB.
|
||||
* who owns the DCB.
|
||||
* @param dcb The dummy DCB
|
||||
* @return 1 on success, 0 on failure
|
||||
*/
|
||||
@ -760,7 +760,7 @@ int fakeQuery(DCB* dcb)
|
||||
GWBUF* tmp = dcb->dcb_readqueue;
|
||||
void* rinst = dcb->session->service->router_instance;
|
||||
void *rses = dcb->session->router_session;
|
||||
|
||||
|
||||
dcb->dcb_readqueue = NULL;
|
||||
return dcb->session->service->router->routeQuery(rinst,rses,tmp);
|
||||
}
|
||||
@ -841,8 +841,8 @@ refreshInstance(
|
||||
}
|
||||
/*else if (paramtype == STRING_TYPE)
|
||||
{
|
||||
if (strncmp(param->name,
|
||||
"ignore_databases",
|
||||
if (strncmp(param->name,
|
||||
"ignore_databases",
|
||||
MAX_PARAM_LEN) == 0)
|
||||
{
|
||||
router->ignore_list = tokenize_string(param->qfd.valstr);
|
||||
@ -862,7 +862,7 @@ refreshInstance(
|
||||
/**
|
||||
* Create an instance of shardrouter statement router within the MaxScale.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param service The service this router is being create for
|
||||
* @param options The options for this query router
|
||||
*
|
||||
@ -964,7 +964,7 @@ createInstance(SERVICE *service, char **options)
|
||||
router->bitvalue = 0;
|
||||
|
||||
/**
|
||||
* Read config version number from service to inform what configuration
|
||||
* Read config version number from service to inform what configuration
|
||||
* is used if any.
|
||||
*/
|
||||
router->shardrouter_version = service->svc_config_version;
|
||||
@ -1018,8 +1018,8 @@ newSession(
|
||||
#endif
|
||||
|
||||
client_rses->router = router;
|
||||
client_rses->rses_mysql_session = (MYSQL_session*) session->data;
|
||||
client_rses->rses_client_dcb = (DCB*) session->client;
|
||||
client_rses->rses_mysql_session = (MYSQL_session*) session->client_dcb->data;
|
||||
client_rses->rses_client_dcb = (DCB*) session->client_dcb;
|
||||
client_rses->rses_autocommit_enabled = true;
|
||||
client_rses->rses_transaction_active = false;
|
||||
client_rses->session = session;
|
||||
@ -1027,12 +1027,12 @@ newSession(
|
||||
client_rses->replydcb->func.read = fakeReply;
|
||||
client_rses->replydcb->state = DCB_STATE_POLLING;
|
||||
client_rses->replydcb->session = session;
|
||||
|
||||
|
||||
client_rses->routedcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
||||
client_rses->routedcb->func.read = fakeQuery;
|
||||
client_rses->routedcb->state = DCB_STATE_POLLING;
|
||||
client_rses->routedcb->session = session;
|
||||
|
||||
|
||||
spinlock_init(&client_rses->rses_lock);
|
||||
|
||||
client_rses->subservice = calloc(router->n_services, sizeof(SUBSERVICE*));
|
||||
@ -1051,10 +1051,10 @@ newSession(
|
||||
{
|
||||
goto errorblock;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: add NULL value checks */
|
||||
client_rses->subservice[i] = subsvc;
|
||||
|
||||
|
||||
subsvc->scur = calloc(1,sizeof(sescmd_cursor_t));
|
||||
if(subsvc->scur == NULL)
|
||||
{
|
||||
@ -1066,15 +1066,15 @@ newSession(
|
||||
subsvc->scur->scmd_cur_ptr_property = client_rses->rses_properties;
|
||||
subsvc->service = router->services[i];
|
||||
subsvc->dcb = dcb_clone(client_rses->rses_client_dcb);
|
||||
|
||||
|
||||
if(subsvc->dcb == NULL){
|
||||
subsvc_set_state(subsvc,SUBSVC_FAILED);
|
||||
MXS_ERROR("Failed to clone client DCB in shardrouter.");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
subsvc->session = session_alloc(subsvc->service,subsvc->dcb);
|
||||
|
||||
|
||||
if(subsvc->session == NULL){
|
||||
dcb_close(subsvc->dcb);
|
||||
subsvc->dcb = NULL;
|
||||
@ -1082,9 +1082,9 @@ newSession(
|
||||
MXS_ERROR("Failed to create subsession for service %s in shardrouter.",subsvc->service->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
dummy_filterdef = filter_alloc("tee_dummy","tee_dummy");
|
||||
|
||||
|
||||
if(dummy_filterdef == NULL)
|
||||
{
|
||||
subsvc_set_state(subsvc,SUBSVC_FAILED);
|
||||
@ -1092,21 +1092,21 @@ newSession(
|
||||
continue;
|
||||
}
|
||||
dummy_filterdef->obj = &dummyObject;
|
||||
dummy_filterdef->filter = (FILTER*)client_rses;
|
||||
dummy_filterdef->filter = (FILTER*)client_rses;
|
||||
dummy_upstream = filterUpstream(dummy_filterdef,subsvc->session,&subsvc->session->tail);
|
||||
|
||||
|
||||
if(dummy_upstream == NULL)
|
||||
{
|
||||
subsvc_set_state(subsvc,SUBSVC_FAILED);
|
||||
MXS_ERROR("Failed to set filterUpstream in shardrouter.");
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
subsvc->session->tail = *dummy_upstream;
|
||||
|
||||
|
||||
|
||||
|
||||
subsvc_set_state(subsvc,SUBSVC_OK);
|
||||
|
||||
|
||||
free(dummy_upstream);
|
||||
}
|
||||
|
||||
@ -1171,9 +1171,9 @@ closeSession(
|
||||
int i;
|
||||
MXS_DEBUG("%lu [RWSplit:closeSession]", pthread_self());
|
||||
|
||||
/**
|
||||
/**
|
||||
* router session can be NULL if newSession failed and it is discarding
|
||||
* its connections and DCB's.
|
||||
* its connections and DCB's.
|
||||
*/
|
||||
if(router_session == NULL)
|
||||
{
|
||||
@ -1191,17 +1191,17 @@ closeSession(
|
||||
ROUTER_OBJECT* rtr;
|
||||
ROUTER* rinst;
|
||||
void *rses;
|
||||
SESSION *ses;
|
||||
|
||||
SESSION *one_session;
|
||||
|
||||
for(i = 0;i<router_cli_ses->n_subservice;i++)
|
||||
{
|
||||
rtr = router_cli_ses->subservice[i]->service->router;
|
||||
rinst = router_cli_ses->subservice[i]->service->router_instance;
|
||||
ses = router_cli_ses->subservice[i]->session;
|
||||
if(ses != NULL)
|
||||
one_session = router_cli_ses->subservice[i]->session;
|
||||
if(one_session != NULL)
|
||||
{
|
||||
rses = ses->router_session;
|
||||
ses->state = SESSION_STATE_STOPPING;
|
||||
rses = one_session->router_session;
|
||||
one_session->state = SESSION_STATE_STOPPING;
|
||||
rtr->closeSession(rinst,rses);
|
||||
}
|
||||
router_cli_ses->subservice[i]->state = SUBSVC_CLOSED;
|
||||
@ -1210,7 +1210,7 @@ closeSession(
|
||||
router_cli_ses->routedcb->session = NULL;
|
||||
dcb_close(router_cli_ses->replydcb);
|
||||
dcb_close(router_cli_ses->routedcb);
|
||||
|
||||
|
||||
/** Unlock */
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
}
|
||||
@ -1226,10 +1226,10 @@ freeSession(
|
||||
|
||||
router_cli_ses = (ROUTER_CLIENT_SES *) router_client_session;
|
||||
|
||||
|
||||
/**
|
||||
* For each property type, walk through the list, finalize properties
|
||||
* and free the allocated memory.
|
||||
|
||||
/**
|
||||
* For each property type, walk through the list, finalize properties
|
||||
* and free the allocated memory.
|
||||
*/
|
||||
for(i = RSES_PROP_TYPE_FIRST; i < RSES_PROP_TYPE_COUNT; i++)
|
||||
{
|
||||
@ -1243,10 +1243,10 @@ freeSession(
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 0;i<router_cli_ses->n_subservice;i++)
|
||||
{
|
||||
|
||||
|
||||
/* TODO: free router client session */
|
||||
free(router_cli_ses->subservice[i]);
|
||||
}
|
||||
@ -1258,7 +1258,7 @@ freeSession(
|
||||
* all the memory and other resources associated
|
||||
* to the client session.
|
||||
*/
|
||||
hashtable_free(router_cli_ses->dbhash);
|
||||
hashtable_free(router_cli_ses->dbhash);
|
||||
free(router_cli_ses);
|
||||
return;
|
||||
}
|
||||
@ -1266,12 +1266,12 @@ freeSession(
|
||||
/**
|
||||
* Examine the query type, transaction state and routing hints. Find out the
|
||||
* target for query routing.
|
||||
*
|
||||
* @param qtype Type of query
|
||||
*
|
||||
* @param qtype Type of query
|
||||
* @param trx_active Is transcation active or not
|
||||
* @param hint Pointer to list of hints attached to the query buffer
|
||||
*
|
||||
* @return bitfield including the routing target, or the target server name
|
||||
*
|
||||
* @return bitfield including the routing target, or the target server name
|
||||
* if the query would otherwise be routed to slave.
|
||||
*/
|
||||
static route_target_t
|
||||
@ -1556,14 +1556,14 @@ routeQuery(ROUTER* instance,
|
||||
}
|
||||
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
|
||||
|
||||
packet = GWBUF_DATA(querybuf);
|
||||
packet_type = packet[4];
|
||||
|
||||
if(rses_is_closed)
|
||||
{
|
||||
/**
|
||||
* MYSQL_COM_QUIT may have sent by client and as a part of backend
|
||||
/**
|
||||
* MYSQL_COM_QUIT may have sent by client and as a part of backend
|
||||
* closing procedure.
|
||||
*/
|
||||
if(packet_type != MYSQL_COM_QUIT)
|
||||
@ -1631,7 +1631,7 @@ routeQuery(ROUTER* instance,
|
||||
default:
|
||||
break;
|
||||
} /**< switch by packet type */
|
||||
|
||||
|
||||
if(packet_type == MYSQL_COM_INIT_DB)
|
||||
{
|
||||
if(!(change_successful = change_current_db(router_cli_ses->current_db,
|
||||
@ -1647,15 +1647,15 @@ routeQuery(ROUTER* instance,
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether the query should be routed to single server or to
|
||||
* Find out whether the query should be routed to single server or to
|
||||
* all of them.
|
||||
*/
|
||||
if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_DATABASES))
|
||||
{
|
||||
/**
|
||||
* Generate custom response that contains all the databases
|
||||
* Generate custom response that contains all the databases
|
||||
*/
|
||||
|
||||
|
||||
GWBUF* dbres = gen_show_dbs_response(inst,router_cli_ses);
|
||||
poll_add_epollin_event_to_dcb(router_cli_ses->replydcb,dbres);
|
||||
ret = 1;
|
||||
@ -1670,7 +1670,7 @@ routeQuery(ROUTER* instance,
|
||||
{
|
||||
tname = hashtable_fetch(router_cli_ses->dbhash, router_cli_ses->rses_mysql_session->db);
|
||||
route_target = TARGET_NAMED_SERVER;
|
||||
|
||||
|
||||
}
|
||||
else if(route_target != TARGET_ALL &&
|
||||
(tname = get_shard_target_name(inst, router_cli_ses, querybuf, qtype)) != NULL)
|
||||
@ -1697,7 +1697,7 @@ routeQuery(ROUTER* instance,
|
||||
* No current database and no databases in query or
|
||||
* the database is ignored, route to first available backend.
|
||||
*/
|
||||
|
||||
|
||||
route_target = TARGET_ANY;
|
||||
|
||||
}
|
||||
@ -1706,7 +1706,7 @@ routeQuery(ROUTER* instance,
|
||||
if(!change_successful)
|
||||
{
|
||||
/**
|
||||
* Bad shard status. The changing of the database
|
||||
* Bad shard status. The changing of the database
|
||||
* was not successful and the error message was already sent.
|
||||
*/
|
||||
|
||||
@ -1777,12 +1777,12 @@ routeQuery(ROUTER* instance,
|
||||
if(TARGET_IS_NAMED_SERVER(route_target))
|
||||
{
|
||||
/**
|
||||
* Search backend server by name or replication lag.
|
||||
* Search backend server by name or replication lag.
|
||||
* If it fails, then try to find valid slave or master.
|
||||
*/
|
||||
|
||||
succp = get_shard_subsvc(&target_subsvc,router_cli_ses,tname);
|
||||
|
||||
|
||||
if(!succp)
|
||||
{
|
||||
MXS_INFO("Was supposed to route to named server "
|
||||
@ -1796,12 +1796,12 @@ routeQuery(ROUTER* instance,
|
||||
{
|
||||
sescmd_cursor_t* scur;
|
||||
scur = target_subsvc->scur;
|
||||
/**
|
||||
* Store current stmt if execution of previous session command
|
||||
/**
|
||||
* Store current stmt if execution of previous session command
|
||||
* haven't completed yet. Note that according to MySQL protocol
|
||||
* there can only be one such non-sescmd stmt at the time.
|
||||
*/
|
||||
if(scur && sescmd_cursor_is_active(scur))
|
||||
if(scur && sescmd_cursor_is_active(scur))
|
||||
{
|
||||
target_subsvc->pending_cmd = gwbuf_clone(querybuf);
|
||||
rses_end_locked_router_action(router_cli_ses);
|
||||
@ -1811,16 +1811,16 @@ routeQuery(ROUTER* instance,
|
||||
|
||||
if(SESSION_ROUTE_QUERY(target_subsvc->session,querybuf) == 1)
|
||||
{
|
||||
|
||||
|
||||
|
||||
atomic_add(&inst->stats.n_queries, 1);
|
||||
/**
|
||||
* Add one query response waiter to backend reference
|
||||
*/
|
||||
subsvc_set_state(target_subsvc,SUBSVC_QUERY_ACTIVE|SUBSVC_WAITING_RESULT);
|
||||
|
||||
|
||||
atomic_add(&target_subsvc->n_res_waiting, 1);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1839,18 +1839,18 @@ retblock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @node Acquires lock to router client session if it is not closed.
|
||||
*
|
||||
* Parameters:
|
||||
* @param rses - in, use
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return true if router session was not closed. If return value is true
|
||||
* it means that router is locked, and must be unlocked later. False, if
|
||||
* router was closed before lock was acquired.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
@ -1881,7 +1881,7 @@ return_succp:
|
||||
|
||||
/** to be inline'd */
|
||||
|
||||
/**
|
||||
/**
|
||||
* @node Releases router client session lock.
|
||||
*
|
||||
* Parameters:
|
||||
@ -1890,7 +1890,7 @@ return_succp:
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*
|
||||
*
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
@ -1955,7 +1955,7 @@ diagnostic(ROUTER *instance, DCB *dcb)
|
||||
"Operations\n");
|
||||
dcb_printf(dcb,
|
||||
"\t\t Global Router\n");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1967,7 +1967,7 @@ diagnostic(ROUTER *instance, DCB *dcb)
|
||||
* The routine will reply to client for session change with master server data
|
||||
*
|
||||
* @param instance The router instance
|
||||
* @param router_session The router session
|
||||
* @param router_session The router session
|
||||
* @param backend_dcb The backend DCB
|
||||
* @param queue The GWBUF with reply data
|
||||
*/
|
||||
@ -1978,12 +1978,12 @@ clientReply(
|
||||
GWBUF* writebuf,
|
||||
DCB* backend_dcb)
|
||||
{
|
||||
|
||||
|
||||
SESSION_ROUTE_REPLY(backend_dcb->session, writebuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Create a generic router session property strcture.
|
||||
*/
|
||||
static rses_property_t*
|
||||
@ -2044,7 +2044,7 @@ rses_property_done(
|
||||
* Add property to the router_client_ses structure's rses_properties
|
||||
* array. The slot is determined by the type of property.
|
||||
* In each slot there is a list of properties of similar type.
|
||||
*
|
||||
*
|
||||
* Router client session must be locked.
|
||||
*/
|
||||
static void
|
||||
@ -2075,7 +2075,7 @@ rses_property_add(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Router session must be locked.
|
||||
* Return session command pointer if succeed, NULL if failed.
|
||||
*/
|
||||
@ -2139,14 +2139,14 @@ mysql_sescmd_done(
|
||||
* command are handled here.
|
||||
* Read session commands from property list. If command is already replied,
|
||||
* discard packet. Else send reply to client. In both cases move cursor forward
|
||||
* until all session command replies are handled.
|
||||
*
|
||||
* until all session command replies are handled.
|
||||
*
|
||||
* Cases that are expected to happen and which are handled:
|
||||
* s = response not yet replied to client, S = already replied response,
|
||||
* q = query
|
||||
* 1. q+ for example : select * from mysql.user
|
||||
* 2. s+ for example : set autocommit=1
|
||||
* 3. S+
|
||||
* 3. S+
|
||||
* 4. sq+
|
||||
* 5. Sq+
|
||||
* 6. Ss+
|
||||
@ -2168,9 +2168,9 @@ sescmd_cursor_process_replies(
|
||||
|
||||
CHK_GWBUF(replybuf);
|
||||
|
||||
/**
|
||||
* Walk through packets in the message and the list of session
|
||||
* commands.
|
||||
/**
|
||||
* Walk through packets in the message and the list of session
|
||||
* commands.
|
||||
*/
|
||||
while(scmd != NULL && replybuf != NULL)
|
||||
{
|
||||
@ -2191,7 +2191,7 @@ sescmd_cursor_process_replies(
|
||||
replybuf = gwbuf_consume(replybuf, buflen);
|
||||
}
|
||||
/** Set response status received */
|
||||
|
||||
|
||||
subsvc_clear_state(subsvc, SUBSVC_WAITING_RESULT);
|
||||
}
|
||||
/** Response is in the buffer and it will be sent to client. */
|
||||
@ -2219,7 +2219,7 @@ sescmd_cursor_process_replies(
|
||||
|
||||
/**
|
||||
* Get the address of current session command.
|
||||
*
|
||||
*
|
||||
* Router session must be locked */
|
||||
static mysql_sescmd_t*
|
||||
sescmd_cursor_get_command(
|
||||
@ -2261,9 +2261,9 @@ sescmd_cursor_set_active(
|
||||
sescmd_cursor->scmd_cur_active = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone session command's command buffer.
|
||||
* Router session must be locked
|
||||
/**
|
||||
* Clone session command's command buffer.
|
||||
* Router session must be locked
|
||||
*/
|
||||
static GWBUF*
|
||||
sescmd_cursor_clone_querybuf(
|
||||
@ -2339,12 +2339,12 @@ execute_sescmd_history(
|
||||
|
||||
/**
|
||||
* If session command cursor is passive, sends the command to backend for
|
||||
* execution.
|
||||
*
|
||||
* execution.
|
||||
*
|
||||
* Returns true if command was sent or added successfully to the queue.
|
||||
* Returns false if command sending failed or if there are no pending session
|
||||
* commands.
|
||||
*
|
||||
*
|
||||
* Router session must be locked.
|
||||
*/
|
||||
static bool
|
||||
@ -2353,21 +2353,21 @@ execute_sescmd_in_backend(SUBSERVICE* subsvc)
|
||||
bool succp;
|
||||
int rc = 0;
|
||||
sescmd_cursor_t* scur;
|
||||
|
||||
|
||||
|
||||
if(SUBSVC_IS_CLOSED(subsvc) || !SUBSVC_IS_OK(subsvc))
|
||||
{
|
||||
succp = false;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
|
||||
if(!subsvc_is_valid(subsvc))
|
||||
{
|
||||
succp = false;
|
||||
goto return_succp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Get cursor pointer and copy of command buffer to cursor.
|
||||
*/
|
||||
scur = subsvc->scur;
|
||||
@ -2397,8 +2397,8 @@ execute_sescmd_in_backend(SUBSERVICE* subsvc)
|
||||
|
||||
case MYSQL_COM_QUERY:
|
||||
default:
|
||||
/**
|
||||
* Mark session command buffer, it triggers writing
|
||||
/**
|
||||
* Mark session command buffer, it triggers writing
|
||||
* MySQL command to protocol
|
||||
*/
|
||||
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
|
||||
@ -2422,8 +2422,8 @@ return_succp:
|
||||
* Moves cursor to next property and copied address of its sescmd to cursor.
|
||||
* Current propery must be non-null.
|
||||
* If current property is the last on the list, *scur->scmd_ptr_property == NULL
|
||||
*
|
||||
* Router session must be locked
|
||||
*
|
||||
* Router session must be locked
|
||||
*/
|
||||
static bool
|
||||
sescmd_cursor_next(
|
||||
@ -2509,11 +2509,11 @@ getCapabilities()
|
||||
/**
|
||||
* Execute in backends used by current router session.
|
||||
* Save session variable commands to router session property
|
||||
* struct. Thus, they can be replayed in backends which are
|
||||
* struct. Thus, they can be replayed in backends which are
|
||||
* started and joined later.
|
||||
*
|
||||
*
|
||||
* Suppress redundant OK packets sent by backends.
|
||||
*
|
||||
*
|
||||
* The first OK packet is replied to the client.
|
||||
* Return true if succeed, false is returned if router session was closed or
|
||||
* if execute_sescmd_in_backend failed.
|
||||
@ -2535,7 +2535,7 @@ route_session_write(
|
||||
|
||||
/**
|
||||
* These are one-way messages and server doesn't respond to them.
|
||||
* Therefore reply processing is unnecessary and session
|
||||
* Therefore reply processing is unnecessary and session
|
||||
* command property is not needed. It is just routed to all available
|
||||
* backends.
|
||||
*/
|
||||
@ -2592,8 +2592,8 @@ route_session_write(
|
||||
succp = false;
|
||||
goto return_succp;
|
||||
}
|
||||
/**
|
||||
* Additional reference is created to querybuf to
|
||||
/**
|
||||
* Additional reference is created to querybuf to
|
||||
* prevent it from being released before properties
|
||||
* are cleaned up as a part of router sessionclean-up.
|
||||
*/
|
||||
@ -2606,7 +2606,7 @@ route_session_write(
|
||||
for(i = 0; i < router_cli_ses->n_subservice; i++)
|
||||
{
|
||||
subsvc = router_cli_ses->subservice[i];
|
||||
|
||||
|
||||
if(!SUBSVC_IS_CLOSED(subsvc))
|
||||
{
|
||||
sescmd_cursor_t* scur;
|
||||
@ -2619,18 +2619,18 @@ route_session_write(
|
||||
i+1 >= router_cli_ses->n_subservice ? "<" : "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
scur = subsvc->scur;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Add one waiter to backend reference.
|
||||
*/
|
||||
subsvc_set_state(subsvc,SUBSVC_WAITING_RESULT);
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Start execution if cursor is not already executing.
|
||||
* Otherwise, cursor will execute pending commands
|
||||
* when it completes with previous commands.
|
||||
@ -2668,7 +2668,7 @@ return_succp:
|
||||
|
||||
/**
|
||||
* Error Handler routine to resolve _backend_ failures. If it succeeds then there
|
||||
* are enough operative backends available and connected. Otherwise it fails,
|
||||
* are enough operative backends available and connected. Otherwise it fails,
|
||||
* and session is terminated.
|
||||
*
|
||||
* @param instance The router instance
|
||||
@ -2677,7 +2677,7 @@ return_succp:
|
||||
* @param backend_dcb The backend DCB
|
||||
* @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT
|
||||
* @param succp Result of action: true if router can continue
|
||||
*
|
||||
*
|
||||
* Even if succp == true connecting to new slave may have failed. succp is to
|
||||
* tell whether router has enough master/slave connections to continue work.
|
||||
*/
|
||||
@ -2694,11 +2694,11 @@ handleError(
|
||||
ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *) router_session;
|
||||
|
||||
CHK_DCB(backend_dcb);
|
||||
|
||||
|
||||
/** Don't handle same error twice on same DCB */
|
||||
if(backend_dcb->dcb_errhandle_called)
|
||||
{
|
||||
/** we optimistically assume that previous call succeed */
|
||||
/** we optimistically assume that previous call succeed */
|
||||
*succp = true;
|
||||
return;
|
||||
}
|
||||
@ -2763,13 +2763,13 @@ static SUBSERVICE* get_subsvc_from_ses(ROUTER_CLIENT_SES* rses, SESSION* ses)
|
||||
return rses->subservice[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls hang-up function for DCB if it is not both running and in
|
||||
* Calls hang-up function for DCB if it is not both running and in
|
||||
* master/slave/joined/ndb role. Called by DCB's callback routine.
|
||||
*
|
||||
* TODO: See if there's a way to inject this into the subservices
|
||||
|
@ -139,7 +139,7 @@ GetModuleObject()
|
||||
/**
|
||||
* Create an instance of the router for a particular service
|
||||
* within the gateway.
|
||||
*
|
||||
*
|
||||
* @param service The service this router is being create for
|
||||
* @param options The options for this query router
|
||||
*
|
||||
@ -183,7 +183,7 @@ WEB_SESSION *wsession;
|
||||
* @param instance The router instance data
|
||||
* @param session The session being closed
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
closeSession(ROUTER *instance, void *session)
|
||||
{
|
||||
free(session);
|
||||
@ -196,7 +196,7 @@ static void freeSession(
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
routeQuery(ROUTER *instance, void *session, GWBUF *queue)
|
||||
{
|
||||
WEB_SESSION *wsession = (WEB_SESSION *)session;
|
||||
@ -367,7 +367,7 @@ send_static_html(DCB *dcb, char *html)
|
||||
static void
|
||||
send_index(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, index_page);
|
||||
@ -382,7 +382,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
send_css(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, css);
|
||||
@ -397,7 +397,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
send_title(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, title_page);
|
||||
@ -412,7 +412,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
send_frame1(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, frame1_page);
|
||||
@ -427,7 +427,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
send_menu(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, menu_page);
|
||||
@ -442,7 +442,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
send_blank(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
send_static_html(dcb, blank_page);
|
||||
@ -465,7 +465,7 @@ service_row(SERVICE *service, DCB *dcb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the services page. This produces a table by means of the
|
||||
* Send the services page. This produces a table by means of the
|
||||
* serviceIterate call.
|
||||
*
|
||||
* @param session The router session
|
||||
@ -473,7 +473,7 @@ service_row(SERVICE *service, DCB *dcb)
|
||||
static void
|
||||
send_services(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
dcb_printf(dcb, "<HTML><HEAD>");
|
||||
@ -497,8 +497,8 @@ static void
|
||||
session_row(SESSION *session, DCB *dcb)
|
||||
{
|
||||
dcb_printf(dcb, "<TR><TD>%-16p</TD><TD>%s</TD><TD>%s</TD><TD>%s</TD></TR>\n",
|
||||
session, ((session->client && session->client->remote)
|
||||
? session->client->remote : ""),
|
||||
session, ((session->client_dcb && session->client_dcb->remote)
|
||||
? session->client_dcb->remote : ""),
|
||||
(session->service && session->service->name
|
||||
? session->service->name : ""),
|
||||
session_state(session->state));
|
||||
@ -514,7 +514,7 @@ session_row(SESSION *session, DCB *dcb)
|
||||
static void
|
||||
send_sessions(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
dcb_printf(dcb, "<HTML><HEAD>");
|
||||
@ -550,7 +550,7 @@ server_row(SERVER *server, DCB *dcb)
|
||||
static void
|
||||
send_servers(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
dcb_printf(dcb, "<HTML><HEAD>");
|
||||
@ -586,7 +586,7 @@ monitor_row(MONITOR *monitor, DCB *dcb)
|
||||
static void
|
||||
send_monitors(WEB_SESSION *session)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
send_html_header(dcb);
|
||||
dcb_printf(dcb, "<HTML><HEAD>");
|
||||
@ -608,7 +608,7 @@ DCB *dcb = session->session->client;
|
||||
static void
|
||||
respond_error(WEB_SESSION *session, int err, char *msg)
|
||||
{
|
||||
DCB *dcb = session->session->client;
|
||||
DCB *dcb = session->session->client_dcb;
|
||||
|
||||
dcb_printf(dcb, "HTTP/1.1 %d %s\n", err, msg);
|
||||
dcb_printf(dcb, "Content-Type: text/html\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user