diff --git a/server/core/buffer.c b/server/core/buffer.c index 993f1d2af..d3278a505 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -317,12 +317,23 @@ gwbuf_trim(GWBUF *buf, unsigned int n_bytes) return buf; } +/** + * Set given type to all buffers on the list. + * * + * @param buf The shared buffer + * @param type Type to be added + */ void gwbuf_set_type( GWBUF* buf, gwbuf_type_t type) { - CHK_GWBUF(buf); - buf->gwbuf_type |= type; + /** Set type consistenly to all buffers on the list */ + while (buf != NULL) + { + CHK_GWBUF(buf); + buf->gwbuf_type |= type; + buf=buf->next; + } } diff --git a/server/include/router.h b/server/include/router.h index 8f0851091..6c29fe1bf 100644 --- a/server/include/router.h +++ b/server/include/router.h @@ -97,10 +97,13 @@ typedef struct router_object { */ #define ROUTER_VERSION { 1, 0, 0 } +/** + * Router capability type. Indicates what kind of input router accepts. + */ typedef enum router_capability_t { - RCAP_TYPE_UNDEFINED = 0, - RCAP_TYPE_STMT_INPUT = (1 << 0), - RCAP_TYPE_PACKET_INPUT = (1 << 1) + RCAP_TYPE_UNDEFINED = 0x00, + RCAP_TYPE_STMT_INPUT = 0x01, /*< statement per buffer */ + RCAP_TYPE_PACKET_INPUT = 0x02 /*< data as it was read from DCB */ } router_capability_t; diff --git a/server/modules/include/mysql_client_server_protocol.h b/server/modules/include/mysql_client_server_protocol.h index ed820fded..f7d6030c1 100644 --- a/server/modules/include/mysql_client_server_protocol.h +++ b/server/modules/include/mysql_client_server_protocol.h @@ -253,27 +253,30 @@ typedef struct server_command_st { struct server_command_st* scom_next; } server_command_t; -/* - * MySQL Protocol specific state data +/** + * MySQL Protocol specific state data. + * + * Protocol carries information from client side to backend side, such as + * MySQL session command information and history of earlier session commands. */ typedef struct { #if defined(SS_DEBUG) skygw_chk_t protocol_chk_top; #endif - int fd; /*< The socket descriptor */ - struct dcb *owner_dcb; /*< The DCB of the socket + int fd; /*< The socket descriptor */ + struct dcb *owner_dcb; /*< The DCB of the socket * we are running on */ SPINLOCK protocol_lock; - server_command_t protocol_command; /*< list of active commands */ - server_command_t* protocol_cmd_history; /*< command history list */ - mysql_auth_state_t protocol_auth_state; /*< Authentication status */ - uint8_t scramble[MYSQL_SCRAMBLE_LEN]; /*< server scramble, + server_command_t protocol_command; /*< session command list */ + server_command_t* protocol_cmd_history; /*< session command history */ + mysql_auth_state_t protocol_auth_state; /*< Authentication status */ + uint8_t scramble[MYSQL_SCRAMBLE_LEN]; /*< server scramble, * created or received */ - uint32_t server_capabilities; /*< server capabilities, + uint32_t server_capabilities; /*< server capabilities, * created or received */ - uint32_t client_capabilities; /*< client capabilities, + uint32_t client_capabilities; /*< client capabilities, * created or received */ - unsigned long tid; /*< MySQL Thread ID, in + unsigned long tid; /*< MySQL Thread ID, in * handshake */ #if defined(SS_DEBUG) skygw_chk_t protocol_chk_tail; diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index bcddc18ef..b277bb505 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -167,7 +167,7 @@ static int gw_read_backend_event(DCB *dcb) { backend_protocol = (MySQLProtocol *) dcb->protocol; CHK_PROTOCOL(backend_protocol); -#if 1 + LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [gw_read_backend_event] Read dcb %p fd %d protocol " @@ -177,7 +177,6 @@ static int gw_read_backend_event(DCB *dcb) { dcb->fd, backend_protocol->protocol_auth_state, STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)))); -#endif /* backend is connected: @@ -420,13 +419,13 @@ static int gw_read_backend_event(DCB *dcb) { /* reading MySQL command output from backend and writing to the client */ { - GWBUF *read_buffer = NULL; - ROUTER_OBJECT *router = NULL; - ROUTER *router_instance = NULL; - void *rsession = NULL; - SESSION *session = dcb->session; - int nbytes_read = 0; - + GWBUF *read_buffer = NULL; + ROUTER_OBJECT *router = NULL; + ROUTER *router_instance = NULL; + void *rsession = NULL; + SESSION *session = dcb->session; + int nbytes_read = 0; + CHK_SESSION(session); router = session->service->router; router_instance = session->service->router_instance; @@ -1226,7 +1225,7 @@ static GWBUF* process_response_data ( /** Get command which was stored in gw_MySQLWrite_backend */ p = DCB_PROTOCOL(dcb, MySQLProtocol); - CHK_PROTOCOL(p); + CHK_PROTOCOL(p); /** All buffers processed here are sescmd responses */ gwbuf_set_type(readbuf, GWBUF_TYPE_SESCMD_RESPONSE); diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index a26cbb057..5d577eebd 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -666,10 +666,11 @@ int gw_read_client_event( case MYSQL_IDLE: { uint8_t cap = 0; - uint8_t *ptr_buff = NULL; - int mysql_command = -1; + uint8_t* payload = NULL; bool stmt_input; /*< router input type */ + ss_dassert(nbytes_read >= 5); + session = dcb->session; ss_dassert( session!= NULL); @@ -685,13 +686,7 @@ int gw_read_client_event( /* Now, we are assuming in the first buffer there is * the information form mysql command */ - ptr_buff = GWBUF_DATA(read_buffer); - - /* get mysql commang at fifth byte */ - if (ptr_buff) { - ss_dassert(nbytes_read >= 5); - mysql_command = ptr_buff[4]; - } + payload = GWBUF_DATA(read_buffer); /** * Without rsession there is no access to backend. * COM_QUIT : close client dcb @@ -700,7 +695,7 @@ int gw_read_client_event( if(rsession == NULL) { /** COM_QUIT */ - if (mysql_command == '\x01') + if (MYSQL_IS_COM_QUIT(payload)) { LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, @@ -767,7 +762,7 @@ int gw_read_client_event( } /** Route COM_QUIT to backend */ - if (mysql_command == '\x01') + if (MYSQL_IS_COM_QUIT(payload)) { /** * Sends COM_QUIT packets since buffer is already @@ -1394,11 +1389,25 @@ static int route_by_statement(SESSION *session, GWBUF *readbuf) { int rc = -1; GWBUF* packetbuf; +#if defined(SS_DEBUG) + gwbuf_type_t prevtype; + GWBUF* tmpbuf; + tmpbuf = readbuf; + while (tmpbuf != NULL) + { + ss_dassert(GWBUF_IS_TYPE_MYSQL(tmpbuf)); + tmpbuf=tmpbuf->next; + } +#endif do { + ss_dassert(GWBUF_IS_TYPE_MYSQL(readbuf)); + packetbuf = gw_MySQL_get_next_packet(&readbuf); + ss_dassert(GWBUF_IS_TYPE_MYSQL(packetbuf)); + if (packetbuf != NULL) { CHK_GWBUF(packetbuf); diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index d983503e6..c39fef739 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -738,9 +738,9 @@ static void* newSession( client_rses->rses_master_ref = master_ref; /* assert with master_host */ ss_dassert(master_ref && (master_ref->bref_backend->backend_server && SERVER_MASTER)); + client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT; client_rses->rses_backend_ref = backend_ref; client_rses->rses_nbackends = router_nservers; /*< # of backend servers */ - client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT; router->stats.n_sessions += 1; /** @@ -1052,6 +1052,9 @@ static int routeQuery( { rses_is_closed = true; } + + ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf)); + packet = GWBUF_DATA(querybuf); packet_type = packet[4]; @@ -1564,10 +1567,6 @@ static void clientReply ( */ writebuf = sescmd_cursor_process_replies(writebuf, bref); } - else - { - ss_dassert(false); - } /** * If response will be sent to client, decrease waiter count. * This applies to session commands only. Counter decrement @@ -1818,11 +1817,11 @@ static bool select_connect_backend_servers( { LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, - "%lu [select_connect_backend_servers] Didn't find master ", - "for session %p rses %p.", + "%lu [select_connect_backend_servers] Session %p doesn't " + "currently have a master chosen. Proceeding to master " + "selection.", pthread_self(), - session, - backend_ref))); + session))); master_found = false; master_connected = false; @@ -2004,7 +2003,8 @@ static bool select_connect_backend_servers( } } /* take the master_host for master */ - else if (master_host && (b->backend_server == master_host->backend_server)) + else if (master_host && + (b->backend_server == master_host->backend_server)) { *p_master_ref = &backend_ref[i]; @@ -3618,16 +3618,15 @@ static bool prep_stmt_drop( * and the SERVER_MASTER bitval * Servers are checked even if they are in 'maintenance' * - * @param servers The list of servers - * @param The number of servers - * @return The Master found + * @param servers The list of servers + * @param router_nservers The number of servers + * @return The Master found * */ static BACKEND *get_root_master(backend_ref_t *servers, int router_nservers) { int i = 0; BACKEND * master_host = NULL; - /* (1) find root server(s) with lowest replication depth level */ for (i = 0; i< router_nservers; i++) { BACKEND* b = NULL; b = servers[i].bref_backend;