From 1baf693b02b2c8377a7e150cc1d7fc7894336b75 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Sun, 23 Aug 2015 16:39:08 +0100 Subject: [PATCH 001/179] First changes for lazy session creation. --- server/core/poll.c | 21 ++++----------------- server/core/service.c | 43 +++++++++++++------------------------------ 2 files changed, 17 insertions(+), 47 deletions(-) diff --git a/server/core/poll.c b/server/core/poll.c index 5e913f5f9..d369ff365 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -299,23 +299,6 @@ poll_add_dcb(DCB *dcb) STRDCBSTATE(dcb->state)))); raise(SIGABRT); } - /* - * This test could be wrong. On the face of it, we don't want to add a - * DCB to the poll list if it is not linked to a session because the code - * that handles events will expect to find a session. Test added by - * Martin as an experiment on 23 August 2015 - */ - if (false && NULL == dcb->session) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [%s] Error : Attempt to add dcb %p " - "to poll list but it is not linked to a session, crashing.", - __func__, - pthread_self(), - dcb))); - raise(SIGABRT); - } if (DCB_STATE_POLLING == dcb->state || DCB_STATE_LISTENING == dcb->state) { @@ -925,6 +908,10 @@ unsigned long qtime; { if (dcb->state == DCB_STATE_LISTENING) { + if (NULL == dcb->session) + { + dcb->session = session_alloc(dcb->service, dcb); + } LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [poll_waitevents] " diff --git a/server/core/service.c b/server/core/service.c index 224a602b3..12971f016 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -363,38 +363,21 @@ GWPROTOCOL *funcs; if (port->listener->func.listen(port->listener, config_bind)) { - port->listener->session = session_alloc(service, port->listener); - - if (port->listener->session != NULL) - { - port->listener->session->state = SESSION_STATE_LISTENER; - listeners += 1; - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create session to service %s.", - service->name))); - - users_free(service->users); - dcb_close(port->listener); - port->listener = NULL; - goto retblock; - } - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, + listeners += 1; + /* If lazy session creation fails, how does listeners get decremented? */ + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, "Error : Unable to start to listen port %d for %s %s.", port->port, - port->protocol, - service->name))); - users_free(service->users); - dcb_close(port->listener); - port->listener = NULL; - } + port->protocol, + service->name))); + users_free(service->users); + dcb_close(port->listener); + port->listener = NULL; + } retblock: return listeners; From 5e2e2585ad44a3b2c1e14d47217b10ff288f10ea Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Sun, 23 Aug 2015 16:43:07 +0100 Subject: [PATCH 002/179] Fix mistakes. --- server/core/poll.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/core/poll.c b/server/core/poll.c index d369ff365..4e34f3657 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -910,7 +911,11 @@ unsigned long qtime; { if (NULL == dcb->session) { - dcb->session = session_alloc(dcb->service, dcb); + dcb->session = (SESSION *)session_alloc(dcb->service, dcb); + if (dcb->session) + { + dcb->session->state = SESSION_STATE_LISTENER; + } } LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, From 37ac15879150631efd09e6264b69320dc048e76c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 24 Aug 2015 12:12:43 +0100 Subject: [PATCH 003/179] Changes to try to eliminate setting dcb->session to NULL with risk of crashing system. --- server/core/poll.c | 9 - server/core/service.c | 44 ++- server/core/session.c | 308 ++++++++---------- server/modules/protocol/httpd.c | 6 +- server/modules/protocol/maxscaled.c | 2 +- server/modules/protocol/telnetd.c | 5 + .../routing/readwritesplit/readwritesplit.c | 2 +- 7 files changed, 182 insertions(+), 194 deletions(-) diff --git a/server/core/poll.c b/server/core/poll.c index 4e34f3657..98f9e83fb 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -909,14 +908,6 @@ unsigned long qtime; { if (dcb->state == DCB_STATE_LISTENING) { - if (NULL == dcb->session) - { - dcb->session = (SESSION *)session_alloc(dcb->service, dcb); - if (dcb->session) - { - dcb->session->state = SESSION_STATE_LISTENER; - } - } LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [poll_waitevents] " diff --git a/server/core/service.c b/server/core/service.c index 12971f016..804c821c8 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -354,7 +354,6 @@ GWPROTOCOL *funcs; goto retblock; } memcpy(&(port->listener->func), funcs, sizeof(GWPROTOCOL)); - port->listener->session = NULL; if (port->address) sprintf(config_bind, "%s:%d", port->address, port->port); @@ -363,21 +362,38 @@ GWPROTOCOL *funcs; if (port->listener->func.listen(port->listener, config_bind)) { - listeners += 1; - /* If lazy session creation fails, how does listeners get decremented? */ - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, + port->listener->session = session_alloc(service, port->listener); + + if (port->listener->session != NULL) + { + port->listener->session->state = SESSION_STATE_LISTENER; + listeners += 1; + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Failed to create session to service %s.", + service->name))); + + users_free(service->users); + dcb_close(port->listener); + port->listener = NULL; + goto retblock; + } + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, "Error : Unable to start to listen port %d for %s %s.", port->port, - port->protocol, - service->name))); - users_free(service->users); - dcb_close(port->listener); - port->listener = NULL; - } + port->protocol, + service->name))); + users_free(service->users); + dcb_close(port->listener); + port->listener = NULL; + } retblock: return listeners; diff --git a/server/core/session.c b/server/core/session.c index 06737b2fb..9c0710d9a 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -58,6 +58,7 @@ static SESSION *allSessions = NULL; static int session_setup_filters(SESSION *session); +static void session_simple_free(SESSION *session, DCB *dcb); /** * Allocate a new session for a new client of the specified service. @@ -76,8 +77,7 @@ session_alloc(SERVICE *service, DCB *client_dcb) SESSION *session; session = (SESSION *)calloc(1, sizeof(SESSION)); - ss_info_dassert(session != NULL, - "Allocating memory for session failed."); + ss_info_dassert(session != NULL, "Allocating memory for session failed."); if (session == NULL) { @@ -87,43 +87,29 @@ session_alloc(SERVICE *service, DCB *client_dcb) "session object due error %d, %s.", errno, strerror(errno)))); - if (client_dcb->data && !DCB_IS_CLONE(client_dcb)) - { - void *clientdata = client_dcb->data; - client_dcb->data = NULL; - free(clientdata); - } - goto return_session; + session_simple_free(session, client_dcb); + return NULL; } #if defined(SS_DEBUG) session->ses_chk_top = CHK_NUM_SESSION; session->ses_chk_tail = CHK_NUM_SESSION; #endif - if (DCB_IS_CLONE(client_dcb)) - { - session->ses_is_child = true; - } + session->ses_is_child = (bool) DCB_IS_CLONE(client_dcb); spinlock_init(&session->ses_lock); - /*< - * Prevent backend threads from accessing before session is completely - * initialized. - */ - spinlock_acquire(&session->ses_lock); session->service = service; - session->client = client_dcb; - session->n_filters = 0; - memset(&session->stats, 0, sizeof(SESSION_STATS)); - session->stats.connect = time(0); - session->state = SESSION_STATE_ALLOC; + session->client = client_dcb; + session->n_filters = 0; + memset(&session->stats, 0, sizeof(SESSION_STATS)); + session->stats.connect = time(0); + session->state = SESSION_STATE_ALLOC; /*< - * Associate the session to the client DCB and set the reference count on - * the session to indicate that there is a single reference to the + * Associate the session to the client DCB and set the reference count on + * the session to indicate that there is a single reference to the * session. There is no need to protect this or use atomic add as the * session has not been made available to the other threads at this * point. */ session->data = client_dcb->data; - client_dcb->session = session; session->refcount = 1; /*< * This indicates that session is ready to be shared with backend @@ -131,139 +117,99 @@ session_alloc(SERVICE *service, DCB *client_dcb) */ session->state = SESSION_STATE_READY; - /*< Release session lock */ - spinlock_release(&session->ses_lock); - - /* - * Only create a router session if we are not the listening - * DCB or an internal DCB. Creating a router session may create a connection to a - * backend server, depending upon the router module implementation - * and should be avoided for the listener session - * - * Router session creation may create other DCBs that link to the - * session, therefore it is important that the session lock is + /* + * Only create a router session if we are not the listening + * DCB or an internal DCB. Creating a router session may create a connection to a + * backend server, depending upon the router module implementation + * and should be avoided for the listener session + * + * Router session creation may create other DCBs that link to the + * session, therefore it is important that the session lock is * relinquished before the router call. - */ - if (client_dcb->state != DCB_STATE_LISTENING && + */ + if (client_dcb->state != DCB_STATE_LISTENING && client_dcb->dcb_role != DCB_ROLE_INTERNAL) - { - session->router_session = - service->router->newSession(service->router_instance, session); + { + session->router_session = service->router->newSession(service->router_instance, session); if (session->router_session == NULL) - { - /** - * Inform other threads that session is closing. - */ - session->state = SESSION_STATE_STOPPING; - /*< - * Decrease refcount, set dcb's session pointer NULL - * and set session pointer to NULL. - */ - session->client = NULL; - session_free(session); - client_dcb->session = NULL; - session = NULL; + { + session_simple_free(session, client_dcb); + LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "Error : Failed to create %s session.", + "%lu [%s] Error : Failed to create %s session because router" + "could not establish a new router session, see earlier error.", + pthread_self(), + __func__, service->name))); - goto return_session; + return NULL; } - /* - * Pending filter chain being setup set the head of the chain to - * be the router. As filters are inserted the current head will - * be pushed to the filter and the head updated. - * - * NB This dictates that filters are created starting at the end - * of the chain nearest the router working back to the client - * protocol end of the chain. - */ - session->head.instance = service->router_instance; - session->head.session = session->router_session; + /* + * Pending filter chain being setup set the head of the chain to + * be the router. As filters are inserted the current head will + * be pushed to the filter and the head updated. + * + * NB This dictates that filters are created starting at the end + * of the chain nearest the router working back to the client + * protocol end of the chain. + */ + session->head.instance = service->router_instance; + session->head.session = session->router_session; - session->head.routeQuery = (void *)(service->router->routeQuery); + session->head.routeQuery = (void *)(service->router->routeQuery); - session->tail.instance = session; - session->tail.session = session; - session->tail.clientReply = session_reply; + session->tail.instance = session; + session->tail.session = session; + session->tail.clientReply = session_reply; - if (service->n_filters > 0) - { - if (!session_setup_filters(session)) - { - /** - * Inform other threads that session is closing. - */ - session->state = SESSION_STATE_STOPPING; - /*< - * Decrease refcount, set dcb's session pointer NULL - * and set session pointer to NULL. - */ - session->client = NULL; - session_free(session); - client_dcb->session = NULL; - session = NULL; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Setting up filters failed. " - "Terminating session %s.", - service->name))); - goto return_session; - } - } - } - - spinlock_acquire(&session->ses_lock); - - if (session->state != SESSION_STATE_READY) + if (service->n_filters > 0) { - spinlock_release(&session->ses_lock); - session->client = NULL; - session_free(session); - client_dcb->session = NULL; - session = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create %s session.", - service->name))); - spinlock_release(&session_spin); + if (!session_setup_filters(session)) + { + session_simple_free(session, client_dcb); + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "Error : Setting up filters failed. " + "Terminating session %s.", + service->name))); + return NULL; + } } - else - { - session->state = SESSION_STATE_ROUTER_READY; - spinlock_release(&session->ses_lock); - spinlock_acquire(&session_spin); - /** Assign a session id and increase */ - session->ses_id = ++session_id; - session->next = allSessions; - allSessions = session; - spinlock_release(&session_spin); + } + + session->state = SESSION_STATE_ROUTER_READY; + spinlock_acquire(&session_spin); + /** Assign a session id and increase, insert session into list */ + session->ses_id = ++session_id; + session->next = allSessions; + allSessions = session; + spinlock_release(&session_spin); - if (session->client->user == NULL) - { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started session [%lu] for %s service ", - session->ses_id, - service->name))); - } - else - { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started %s client session [%lu] for '%s' from %s", - service->name, - session->ses_id, - session->client->user, - session->client->remote))); - } - atomic_add(&service->stats.n_sessions, 1); - atomic_add(&service->stats.n_current, 1); - CHK_SESSION(session); - } -return_session: - return session; + if (session->client->user == NULL) + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started session [%lu] for %s service ", + session->ses_id, + service->name))); + } + else + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started %s client session [%lu] for '%s' from %s", + service->name, + session->ses_id, + session->client->user, + session->client->remote))); + } + atomic_add(&service->stats.n_sessions, 1); + atomic_add(&service->stats.n_current, 1); + CHK_SESSION(session); + + client_dcb->session = session; + return session; } /** @@ -360,30 +306,57 @@ int session_unlink_dcb( return nlink; } +/** + * Deallocate the specified session, minimal actions during session_alloc + * + * @param session The session to deallocate + */ +static void +session_simple_free(SESSION *session, DCB *dcb) +{ + /* Does this possibly need a lock? */ + if (dcb->data && !DCB_IS_CLONE(dcb)) + { + void * clientdata = dcb->data; + dcb->data = NULL; + free(clientdata); + } + if (session) + { + if (session && session->router_session) + { + session->service->router->freeSession( + session->service->router_instance, + session->router_session); + } + session->state = SESSION_STATE_STOPPING; + } + + free(session); +} + + /** * Deallocate the specified session * * @param session The session to deallocate */ -bool session_free( - SESSION *session) +bool +session_free(SESSION *session) { - bool succp = false; - SESSION *ptr; - int nlink; - int i; - CHK_SESSION(session); - /*< + + /* * Remove one reference. If there are no references left, * free session. */ - nlink = session_unlink_dcb(session, NULL); - - if (nlink != 0) { - ss_dassert(nlink > 0); - goto return_succp; + if (atomic_add(&session->refcount, -1) - 1) + { + /* Must be one or more references left */ + ss_dassert(nlink > 0); + return false; } + session->state = SESSION_STATE_TO_BE_FREED; /* First of all remove from the linked list */ spinlock_acquire(&session_spin); @@ -393,13 +366,16 @@ bool session_free( } else { - ptr = allSessions; - while (ptr && ptr->next != session) + SESSION *chksession; + chksession = allSessions; + while (chksession && chksession->next != session) { - ptr = ptr->next; + chksession = chksession->next; } - if (ptr) - ptr->next = session->next; + if (chksession) + { + chksession->next = session->next; + } } spinlock_release(&session_spin); atomic_add(&session->service->stats.n_current, -1); @@ -416,6 +392,7 @@ bool session_free( } if (session->n_filters) { + int i; for (i = 0; i < session->n_filters; i++) { if (session->filters[i].filter) @@ -453,10 +430,7 @@ bool session_free( } free(session); } - succp = true; - -return_succp : - return succp; + return true; } /** diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index fa7418157..e3c955bdc 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -351,7 +351,8 @@ int n_connect = 0; memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL)); /* we don't need the session */ - client->session = NULL; + /* But not clear that we have one! */ + /* client->session = NULL; */ /* create the session data for HTTPD */ client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session)); @@ -360,9 +361,10 @@ int n_connect = 0; client->session = session_alloc(dcb->session->service, client); - if (poll_add_dcb(client) == -1) + if (NULL == client->session || poll_add_dcb(client) == -1) { close(so); + dcb_close(client); return n_connect; } n_connect++; diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index 6b1b5e570..d57304390 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -291,7 +291,7 @@ int n_connect = 0; client_dcb->session = session_alloc(dcb->session->service, client_dcb); - if (poll_add_dcb(client_dcb)) + if (NULL == client_dcb->session || poll_add_dcb(client_dcb)) { dcb_close(dcb); return n_connect; diff --git a/server/modules/protocol/telnetd.c b/server/modules/protocol/telnetd.c index 8274c91cf..d184d3093 100644 --- a/server/modules/protocol/telnetd.c +++ b/server/modules/protocol/telnetd.c @@ -311,6 +311,11 @@ int n_connect = 0; memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL)); client_dcb->session = session_alloc(dcb->session->service, client_dcb); + if (NULL == client_dcb->session) + { + dcb_close(client_dcb); + return n_connect; + } telnetd_pr = (TELNETD *)malloc(sizeof(TELNETD)); client_dcb->protocol = (void *)telnetd_pr; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 06932e206..417abdfe7 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1684,7 +1684,7 @@ static skygw_query_type_t is_read_tmp_table( { skygw_log_write(LE,"[%s] Error: Master server reference is NULL.", __FUNCTION__); - return; + return type; } rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; From 65c42e2d80f7c228e1a5c556ac500054e8832341 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 24 Aug 2015 16:19:25 +0100 Subject: [PATCH 004/179] Move removal of closing DCB from poll list to the kill zombies processing, rather than immediately on close; modify persistent connections to obtain candidates for the pool from the kill zombies processing to be sure that they really are finished all previous processing. --- server/core/dcb.c | 79 ++++++++++++++++++++++--------------------- server/core/session.c | 1 - server/include/dcb.h | 1 + 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 14fbdd3ff..37879ed4c 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -536,6 +536,33 @@ dcb_process_victim_queue(DCB *listofdcb) while (dcb != NULL) { DCB *nextdcb = NULL; + /*< + * Stop dcb's listening and modify state accordingly. + */ + if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING) + { + if (dcb->state == DCB_STATE_LISTENING) + { + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "%lu [%s] Error : Removing DCB %p but was in state %s " + "which is not expected for a call to dcb_close, although it" + "should be processed correctly. ", + pthread_self(), + __func__, + dcb, + STRDCBSTATE(dcb->state)))); + } + if ((dcb->state == DCB_STATE_POLLING && !dcb_maybe_add_persistent(dcb)) + || (dcb->state == DCB_STATE_LISTENING)) + { + dcb_close_finish(dcb); + } + } + + /* If DCB was put into persistent queue, will no longer be flagged zombie */ + if (!dcb->dcb_is_zombie) continue; + if (dcb->fd > 0) { /*< @@ -1794,11 +1821,6 @@ dcb_close(DCB *dcb) dcb, dcb ? STRDCBSTATE(dcb->state) : "Invalid DCB"))); - if (DCB_STATE_ZOMBIE == dcb->state) - { - return; - } - if (DCB_STATE_UNDEFINED == dcb->state || DCB_STATE_DISCONNECTED == dcb->state) { @@ -1822,43 +1844,21 @@ dcb_close(DCB *dcb) return; } - /*< - * Stop dcb's listening and modify state accordingly. - */ - if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING) - { - if (dcb->state == DCB_STATE_LISTENING) - { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%lu [dcb_close] Error : Removing DCB %p but was in state %s " - "which is not expected for a call to dcb_close, although it" - "should be processed correctly. ", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); - } - if ((dcb->state == DCB_STATE_POLLING && !dcb_maybe_add_persistent(dcb)) - || (dcb->state == DCB_STATE_LISTENING)) - { - dcb_close_finish(dcb); - } - } - spinlock_acquire(&zombiespin); - if (dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ALLOC) + if (dcb->dcb_is_zombie) { - /*< - * Add closing dcb to the top of the list. - */ - dcb->memdata.next = zombies; - zombies = dcb; - /*< - * Set state which indicates that it has been added to zombies - * list. - */ - dcb->state = DCB_STATE_ZOMBIE; + return; } + /*< + * Add closing dcb to the top of the list. + */ + dcb->dcb_is_zombie = true; + dcb->memdata.next = zombies; + zombies = dcb; + /*< + * Set state which indicates that it has been added to zombies + * list. + */ spinlock_release(&zombiespin); } @@ -1889,6 +1889,7 @@ dcb_maybe_add_persistent(DCB *dcb) pthread_self(), user))); dcb->user = strdup(user); + dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); session_unlink_dcb(dcb->session, dcb); spinlock_acquire(&dcb->server->persistlock); diff --git a/server/core/session.c b/server/core/session.c index 9c0710d9a..31bbbd637 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -353,7 +353,6 @@ session_free(SESSION *session) if (atomic_add(&session->refcount, -1) - 1) { /* Must be one or more references left */ - ss_dassert(nlink > 0); return false; } session->state = SESSION_STATE_TO_BE_FREED; diff --git a/server/include/dcb.h b/server/include/dcb.h index 7339286a1..feb0a3387 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -227,6 +227,7 @@ typedef struct dcb_callback { typedef struct dcb { skygw_chk_t dcb_chk_top; bool dcb_errhandle_called; /*< this can be called only once */ + bool dcb_is_zombie; /**< Whether the DCB is in the zombie list */ dcb_role_t dcb_role; SPINLOCK dcb_initlock; DCBEVENTQ evq; /**< The event queue for this DCB */ From ae669c6f888ba0aec07e4cb12a260bbf72c14020 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 24 Aug 2015 16:29:41 +0100 Subject: [PATCH 005/179] Fix mistake --- server/core/dcb.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 37879ed4c..5ded385c9 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1845,20 +1845,15 @@ dcb_close(DCB *dcb) } spinlock_acquire(&zombiespin); - if (dcb->dcb_is_zombie) + if (!dcb->dcb_is_zombie) { - return; + /*< + * Add closing dcb to the top of the list, setting zombie marker + */ + dcb->dcb_is_zombie = true; + dcb->memdata.next = zombies; + zombies = dcb; } - /*< - * Add closing dcb to the top of the list. - */ - dcb->dcb_is_zombie = true; - dcb->memdata.next = zombies; - zombies = dcb; - /*< - * Set state which indicates that it has been added to zombies - * list. - */ spinlock_release(&zombiespin); } From 12922225b85baca8b0a1f744894bbb1e56e674d3 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:11:44 +0100 Subject: [PATCH 006/179] Remove redundant DCB state DCB_STATE_FREED, remove obsolete assertion from poll.c, tidy up. --- server/core/dcb.c | 32 ++++++++++++++------------------ server/core/poll.c | 1 - server/include/dcb.h | 1 - utils/skygw_debug.h | 5 ++--- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 5ded385c9..1f6eea6a8 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -409,7 +409,6 @@ dcb_process_zombies(int threadid) DCB *zombiedcb, *previousdcb; DCB *listofdcb = NULL; DCB *dcb = NULL; -bool succp = false; /** * Perform a dirty read to see if there is anything in the queue. @@ -470,15 +469,14 @@ bool succp = false; LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, - "%lu [dcb_process_zombies] Remove dcb " + "%lu [%s] Remove dcb " "%p fd %d in state %s from the " "list of zombies.", pthread_self(), + __func__, zombiedcb, zombiedcb->fd, STRDCBSTATE(zombiedcb->state)))); - ss_info_dassert(zombiedcb->state == DCB_STATE_ZOMBIE, - "dcb not in DCB_STATE_ZOMBIE state."); /*< * Move zombie dcb to linked list of victim dcbs. * The variable dcb is used to hold the last DCB @@ -553,15 +551,16 @@ dcb_process_victim_queue(DCB *listofdcb) dcb, STRDCBSTATE(dcb->state)))); } - if ((dcb->state == DCB_STATE_POLLING && !dcb_maybe_add_persistent(dcb)) - || (dcb->state == DCB_STATE_LISTENING)) - { - dcb_close_finish(dcb); + else { + /* Must be DCB_STATE_POLLING */ + if (dcb_maybe_add_persistent(dcb)) + { + /* Have taken DCB into persistent pool, no further killing */ + continue; + } } + dcb_close_finish(dcb); } - - /* If DCB was put into persistent queue, will no longer be flagged zombie */ - if (!dcb->dcb_is_zombie) continue; if (dcb->fd > 0) { @@ -603,10 +602,10 @@ dcb_process_victim_queue(DCB *listofdcb) &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->state = DCB_STATE_DISCONNECTED; - nextdcb = dcb->memdata.next; - dcb_final_free(dcb); - dcb = nextdcb; + dcb->state = DCB_STATE_DISCONNECTED; + nextdcb = dcb->memdata.next; + dcb_final_free(dcb); + dcb = nextdcb; } /** Reset threads session data */ LOGIF(LT, tls_log_info.li_sesid = 0); @@ -732,7 +731,6 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol) session->client, session->client->fd))); } - ss_dassert(dcb->fd == DCBFD_CLOSED); /*< must be uninitialized at this point */ /** * Successfully connected to backend. Assign file descriptor to dcb */ @@ -2281,8 +2279,6 @@ gw_dcb_state2string (int state) return "DCB for listening socket"; case DCB_STATE_DISCONNECTED: return "DCB socket closed"; - case DCB_STATE_FREED: - return "DCB memory could be freed"; case DCB_STATE_ZOMBIE: return "DCB Zombie"; case DCB_STATE_UNDEFINED: diff --git a/server/core/poll.c b/server/core/poll.c index 98f9e83fb..da996f3b6 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -866,7 +866,6 @@ unsigned long qtime; ss_debug(spinlock_acquire(&dcb->dcb_initlock);) ss_dassert(dcb->state != DCB_STATE_ALLOC); ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); - ss_dassert(dcb->state != DCB_STATE_FREED); ss_debug(spinlock_release(&dcb->dcb_initlock);) LOGIF(LD, (skygw_log_write( diff --git a/server/include/dcb.h b/server/include/dcb.h index feb0a3387..c9312a128 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -179,7 +179,6 @@ typedef enum { DCB_STATE_DISCONNECTED, /*< The socket is now closed */ DCB_STATE_NOPOLLING, /*< Removed from poll mask */ DCB_STATE_ZOMBIE, /*< DCB is no longer active, waiting to free it */ - DCB_STATE_FREED /*< Memory freed */ } dcb_state_t; typedef enum { diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index f9b586a0c..1aaa3f2ae 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -206,9 +206,8 @@ typedef enum skygw_chk_t { ((s) == DCB_STATE_LISTENING ? "DCB_STATE_LISTENING" : \ ((s) == DCB_STATE_DISCONNECTED ? "DCB_STATE_DISCONNECTED" : \ ((s) == DCB_STATE_NOPOLLING ? "DCB_STATE_NOPOLLING" : \ - ((s) == DCB_STATE_FREED ? "DCB_STATE_FREED" : \ - ((s) == DCB_STATE_ZOMBIE ? "DCB_STATE_ZOMBIE" : \ - ((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN")))))))) + ((s) == DCB_STATE_ZOMBIE ? "DCB_STATE_ZOMBIE" : \ + ((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN")))))))) #define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \ ((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \ From f18f233de25f6af2453d381899a092694c712e8d Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:23:24 +0100 Subject: [PATCH 007/179] Try to resolve unexpected compiler errors --- server/core/dcb.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 1f6eea6a8..e38f2e93b 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -462,12 +462,18 @@ DCB *dcb = NULL; * queue or NULL if the DCB is at the head of the * queue. Remove zombiedcb from the zombies list. */ - if (previousdcb == NULL) + if (NULL == previousdcb) + { zombies = zombiedcb->memdata.next; - else + } + else + { previousdcb->memdata.next = zombiedcb->memdata.next; + } - LOGIF(LD, (skygw_log_write_flush( + if (LOG_IS_ENABLED(LD)) + { + (skygw_log_write_flush( LOGFILE_DEBUG, "%lu [%s] Remove dcb " "%p fd %d in state %s from the " @@ -476,7 +482,8 @@ DCB *dcb = NULL; __func__, zombiedcb, zombiedcb->fd, - STRDCBSTATE(zombiedcb->state)))); + STRDCBSTATE(zombiedcb->state))); + } /*< * Move zombie dcb to linked list of victim dcbs. * The variable dcb is used to hold the last DCB From d27ffcf06a32b6f172290dfb6ddcbd754dffe176 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:31:54 +0100 Subject: [PATCH 008/179] Fix mistake in debug STRDCBSTATE() --- server/core/dcb.c | 6 ++---- utils/skygw_debug.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index e38f2e93b..0051de676 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -471,9 +471,7 @@ DCB *dcb = NULL; previousdcb->memdata.next = zombiedcb->memdata.next; } - if (LOG_IS_ENABLED(LD)) - { - (skygw_log_write_flush( + LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, "%lu [%s] Remove dcb " "%p fd %d in state %s from the " @@ -482,7 +480,7 @@ DCB *dcb = NULL; __func__, zombiedcb, zombiedcb->fd, - STRDCBSTATE(zombiedcb->state))); + STRDCBSTATE(zombiedcb->state)))); } /*< * Move zombie dcb to linked list of victim dcbs. diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index 1aaa3f2ae..ff5d5c9c0 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -207,7 +207,7 @@ typedef enum skygw_chk_t { ((s) == DCB_STATE_DISCONNECTED ? "DCB_STATE_DISCONNECTED" : \ ((s) == DCB_STATE_NOPOLLING ? "DCB_STATE_NOPOLLING" : \ ((s) == DCB_STATE_ZOMBIE ? "DCB_STATE_ZOMBIE" : \ - ((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN")))))))) + ((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN"))))))) #define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \ ((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \ From 980b56e7fa967c20c55826fe7ad16f06a362b6b2 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:33:40 +0100 Subject: [PATCH 009/179] Fix stupid extra } --- server/core/dcb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 0051de676..8ca414ccc 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -481,7 +481,6 @@ DCB *dcb = NULL; zombiedcb, zombiedcb->fd, STRDCBSTATE(zombiedcb->state)))); - } /*< * Move zombie dcb to linked list of victim dcbs. * The variable dcb is used to hold the last DCB From 3dd20cb9ecf7747fc39b12d790b148ac6471f6a2 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:53:01 +0100 Subject: [PATCH 010/179] Acquire user for DCB from DCB session sooner, needed for persistent connection handling. --- server/core/dcb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 8ca414ccc..89d3e524b 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1849,6 +1849,9 @@ dcb_close(DCB *dcb) spinlock_acquire(&zombiespin); if (!dcb->dcb_is_zombie) { + char *user; + user = session_getUser(dcb->session); + dcb->user = strdup(user); /*< * Add closing dcb to the top of the list, setting zombie marker */ @@ -1869,11 +1872,9 @@ dcb_close(DCB *dcb) static bool dcb_maybe_add_persistent(DCB *dcb) { - char *user; int poolcount = -1; - user = session_getUser(dcb->session); - if (user - && strlen(user) + if (dcb->user + && strlen(dcb->user) && dcb->server && dcb->server->persistpoolmax && !dcb->dcb_errhandle_called From ea09918312d5c4431dee3c0dc1f701f4ae99ee72 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 09:54:56 +0100 Subject: [PATCH 011/179] Fix mistakes. --- server/core/dcb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 89d3e524b..76fffc5db 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1885,8 +1885,7 @@ dcb_maybe_add_persistent(DCB *dcb) LOGFILE_DEBUG, "%lu [dcb_maybe_add_persistent] Adding DCB to persistent pool, user %s.\n", pthread_self(), - user))); - dcb->user = strdup(user); + dcb->user))); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); session_unlink_dcb(dcb->session, dcb); @@ -1906,7 +1905,7 @@ dcb_maybe_add_persistent(DCB *dcb) "max for pool %d, error handle called %s, hung flag %s, pool count %d.\n", pthread_self(), dcb, - user ? user : "", + dcb->user ? dcb->user : "", (dcb->server && dcb->server->persistpoolmax) ? dcb->server->persistpoolmax : 0, dcb->dcb_errhandle_called ? "true" : "false", (dcb->flags & DCBF_HUNG) ? "true" : "false", From 8425deab18cc64950b4b17dab89e5cacbc1984a0 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 11:46:25 +0100 Subject: [PATCH 012/179] Fixed bugs by moving setting of thread bit mask from polling to DCB closing, fixed other mistakes. --- server/core/dcb.c | 8 ++++++-- server/core/poll.c | 4 ---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 76fffc5db..61b945114 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -560,6 +560,7 @@ dcb_process_victim_queue(DCB *listofdcb) if (dcb_maybe_add_persistent(dcb)) { /* Have taken DCB into persistent pool, no further killing */ + dcb = dcb->memdata.next; continue; } } @@ -1858,6 +1859,10 @@ dcb_close(DCB *dcb) dcb->dcb_is_zombie = true; dcb->memdata.next = zombies; zombies = dcb; + /*< Set bit for each maxscale thread. This should be done before + * the state is changed, so as to protect the DCB from premature + * destruction. */ + bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); } spinlock_release(&zombiespin); } @@ -1873,7 +1878,7 @@ static bool dcb_maybe_add_persistent(DCB *dcb) { int poolcount = -1; - if (dcb->user + if (dcb->user != NULL && strlen(dcb->user) && dcb->server && dcb->server->persistpoolmax @@ -1888,7 +1893,6 @@ dcb_maybe_add_persistent(DCB *dcb) dcb->user))); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); - session_unlink_dcb(dcb->session, dcb); spinlock_acquire(&dcb->server->persistlock); dcb->nextpersistent = dcb->server->persistent; dcb->server->persistent = dcb; diff --git a/server/core/poll.c b/server/core/poll.c index da996f3b6..eecd457f4 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -368,10 +368,6 @@ poll_remove_dcb(DCB *dcb) dcb, STRDCBSTATE(dcb->state)))); } - /*< Set bit for each maxscale thread. This should be done before - * the state is changed, so as to protect the DCB from premature - * destruction. */ - bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); /*< * Set state to NOPOLLING and remove dcb from poll set. */ From e7c74c39cfaa16e96eca2cabc8092d4c592e0cdf Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 12:19:02 +0100 Subject: [PATCH 013/179] Fix bug in persistent connections; add code to check for DCB session pointer in poll loop before invoking processing. --- server/core/dcb.c | 2 +- server/core/poll.c | 55 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 61b945114..7ae8622fe 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1852,7 +1852,7 @@ dcb_close(DCB *dcb) { char *user; user = session_getUser(dcb->session); - dcb->user = strdup(user); + if (NULL != user) dcb->user = strdup(user); /*< * Add closing dcb to the top of the list, setting zombie marker */ diff --git a/server/core/poll.c b/server/core/poll.c index eecd457f4..182a1385f 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -96,7 +96,7 @@ static simple_mutex_t epoll_wait_mutex; /*< serializes calls to epoll_wait */ static int n_waiting = 0; /*< No. of threads in epoll_wait */ static int process_pollq(int thread_id); static void poll_add_event_to_dcb(DCB* dcb, GWBUF* buf, __uint32_t ev); - +static bool poll_dcb_session_check(DCB *dcb); DCB *eventq = NULL; SPINLOCK pollqlock = SPINLOCK_INIT; @@ -885,7 +885,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.write_ready(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.write_ready(dcb); + } } else { LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, @@ -915,7 +918,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.accept(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.accept(dcb); + } } else { @@ -932,7 +938,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.read(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.read(dcb); + } } } if (ev & EPOLLERR) @@ -967,7 +976,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.error(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.error(dcb); + } } if (ev & EPOLLHUP) @@ -996,7 +1008,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.hangup(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.hangup(dcb); + } } else spinlock_release(&dcb->dcb_initlock); @@ -1029,7 +1044,10 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - dcb->func.hangup(dcb); + if (poll_dcb_session_check(dcb)) + { + dcb->func.hangup(dcb); + } } else spinlock_release(&dcb->dcb_initlock); @@ -1098,6 +1116,29 @@ unsigned long qtime; } /** + * + * Check that the DCB has a session link before processing. + * If not, log an error. Processing will be bypassed + * + * @param dcb The DCB to check + * @return bool Does the DCB have a non-null session link + */ +static bool +poll_dcb_session_check(DCB *dcb) +{ + if (dcb->session) + { + return true; + } + else + { + LOGIF; + return false; + } +} + +/** + * * Shutdown the polling loop */ void From 72b301785bcb223faa72e43b949a27547ef5e8cc Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 25 Aug 2015 12:25:36 +0100 Subject: [PATCH 014/179] Complete implementation of error logging when no session pointer in DCB. --- server/core/poll.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/core/poll.c b/server/core/poll.c index 182a1385f..5a9c72829 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -1132,7 +1132,13 @@ poll_dcb_session_check(DCB *dcb) } else { - LOGIF; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "%lu [%s] The dcb %p that was about to be processed does not " + "have a non-null session pointer " + pthread_self(), + __func__, + dcb))); return false; } } From 1f6b544f339469006a72f9ff457b8c2a57ccf394 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 15:43:21 +0100 Subject: [PATCH 015/179] Tidy dcb_free (prefer use of dcb_close) and remove from test code; add good random number generator. --- server/core/dcb.c | 14 +++----------- server/core/secrets.c | 6 ++---- server/core/test/testdcb.c | 6 +++--- server/core/test/testpoll.c | 2 +- server/core/test/testsession.c | 2 +- server/core/utils.c | 4 ++-- utils/skygw_utils.cc | 3 ++- 7 files changed, 14 insertions(+), 23 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 7ae8622fe..448c9a091 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -230,23 +230,15 @@ DCB *newdcb; /** - * Free a DCB that has not been associated with a descriptor. + * Provided only for consistency, simply calls dcb_close to guarantee + * safe disposal of a DCB * * @param dcb The DCB to free */ void dcb_free(DCB *dcb) { - if (dcb->fd != DCBFD_CLOSED) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Attempt to free a DCB via dcb_free " - "that has been associated with a descriptor."))); - } - raise(SIGABRT); - /* Another statement to avoid a compiler warning */ - dcb_final_free(dcb); + dcb_close(dcb); } /* diff --git a/server/core/secrets.c b/server/core/secrets.c index d26833e5c..b614a5555 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -23,6 +23,7 @@ #include #include #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -36,15 +37,13 @@ extern __thread log_info_t tls_log_info; static unsigned char secrets_randomchar() { - return (char)((rand() % ('~' - ' ')) + ' '); + return (char)((random_jkiss() % ('~' - ' ')) + ' '); } static int secrets_random_str(unsigned char *output, int len) { int i; - srand((unsigned long )time(0L) ^ (unsigned long )output); - for ( i = 0; i < len; ++i ) { output[i] = secrets_randomchar(); @@ -273,7 +272,6 @@ if(strlen(path) > PATH_MAX) } close(randfd); - srand(randval); secrets_random_str(key.enckey, MAXSCALE_KEYLEN); secrets_random_str(key.initvector, MAXSCALE_IV_LEN); diff --git a/server/core/test/testdcb.c b/server/core/test/testdcb.c index 13462fc87..1eb8a1a88 100644 --- a/server/core/test/testdcb.c +++ b/server/core/test/testdcb.c @@ -59,9 +59,9 @@ int buflen; printAllDCBs(); ss_info_dassert(true, "Something is true"); ss_dfprintf(stderr, "\t..done\n"); - dcb_free(dcb); - ss_dfprintf(stderr, "Freed original dcb"); - ss_info_dassert(!dcb_isvalid(dcb), "Freed DCB must not be valid"); + dcb_close(dcb); + ss_dfprintf(stderr, "Closed original dcb"); + ss_info_dassert(!dcb_isvalid(dcb), "Closed DCB must not be valid"); ss_dfprintf(stderr, "\t..done\nMake clone DCB a zombie"); clone->state = DCB_STATE_NOPOLLING; dcb_close(clone); diff --git a/server/core/test/testpoll.c b/server/core/test/testpoll.c index 7b9175b2c..a4e6e71db 100644 --- a/server/core/test/testpoll.c +++ b/server/core/test/testpoll.c @@ -85,7 +85,7 @@ int result; sleep(10); poll_shutdown(); ss_dfprintf(stderr, "\t..done\nTidy up."); - dcb_free(dcb); + dcb_close(dcb); ss_dfprintf(stderr, "\t..done\n"); return 0; diff --git a/server/core/test/testsession.c b/server/core/test/testsession.c index 4d8d4cc04..d471fdad4 100644 --- a/server/core/test/testsession.c +++ b/server/core/test/testsession.c @@ -59,7 +59,7 @@ int result; sleep(10); poll_shutdown(); ss_dfprintf(stderr, "\t..done\nTidy up."); - dcb_free(dcb); + dcb_close(dcb); ss_dfprintf(stderr, "\t..done\n"); return 0; diff --git a/server/core/utils.c b/server/core/utils.c index a26c2b4e5..45b47e632 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -43,6 +43,7 @@ #include #include #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; @@ -100,7 +101,7 @@ char *gw_strend(register const char *s) { * generate a random char *****************************************/ static char gw_randomchar() { - return (char)((rand() % 78) + 30); + return (char)((random_jkiss() % 78) + 30); } /***************************************** @@ -110,7 +111,6 @@ static char gw_randomchar() { int gw_generate_random_str(char *output, int len) { int i; - srand(time(0L)); for ( i = 0; i < len; ++i ) { output[i] = gw_randomchar(); diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index 26a8e8b88..7ca3baec3 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -30,6 +30,7 @@ #include #include "skygw_utils.h" #include +#include #if defined(MLIST) @@ -1265,7 +1266,7 @@ void acquire_lock( misscount += 1; if (misscount > 10) { - ts1.tv_nsec = (rand()%misscount)*1000000; + ts1.tv_nsec = (random_jkiss()%misscount)*1000000; nanosleep(&ts1, NULL); } } From 162db1352389dcc1c8d4154ddc65cbe76ff87a1c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 15:43:43 +0100 Subject: [PATCH 016/179] Add actual random number generation code. --- server/core/random.c | 97 +++++++++++++++++++++++++++++++++++++++++ server/include/random.h | 22 ++++++++++ 2 files changed, 119 insertions(+) create mode 100644 server/core/random.c create mode 100644 server/include/random.h diff --git a/server/core/random.c b/server/core/random.c new file mode 100644 index 000000000..bba20ade5 --- /dev/null +++ b/server/core/random.c @@ -0,0 +1,97 @@ +/* + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright MariaDB Corporation Ab 2013-2014 + */ + +/** + * @file random.c - Random number generator for the MariaDB Corporation MaxScale + * + * @verbatim + * Revision History + * + * Date Who Description + * 26/08/15 Martin Brampton Initial implementation + * + * @endverbatim + */ + +#include +#include +#include +#include +#include + +/* Public domain code for JKISS RNG - Comments added */ +static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217; /* Seed variables */ +static bool init = false; + +/*** + * + * Return a random number + * + * @return uint Random number + * + */ +unsigned int +random_jkiss(void) +{ + unsigned long long t; + if (!init) random_init_jkiss(); + x = 314527869 * x + 1234567; + y ^= y << 5; y ^= y >> 7; y ^= y << 22; + t = 4294584393ULL * z + c; c = t >> 32; z = t; + return x + y + z; +} + +/* Own code adapted from http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf */ + +/*** + * + * Obtain a seed random number from /dev/urandom if available. + * Otherwise use constant values + * + * @return uint Random number + * + */ +static unsigned int +random_devrand() +{ + int fn; + unsigned int r; + fn = open("/dev/urandom", O_RDONLY); + if (fn == -1) return 0; + if (read(fn, &r, 4) != 4) return 0; + close(fn); + return r; +} + +/*** + * + * Initialise the generator using /dev/urandom if available, and warm up + * with 1000 iterations + * + */ +static void +random_init_jkiss() +{ + int newrand, i; + if ((newrand = random_devrand()) != 0) x = newrand; + if ((newrand = random_devrand()) != 0) y = newrand; + if ((newrand = random_devrand()) != 0) z = newrand; + if ((newrand = random_devrand()) != 0) + c = newrand % 698769068 + 1; /* Should be less than 698769069 */ + for (i = 0; i < 1000; i++) random_jkiss(); +} \ No newline at end of file diff --git a/server/include/random.h b/server/include/random.h new file mode 100644 index 000000000..b302594d2 --- /dev/null +++ b/server/include/random.h @@ -0,0 +1,22 @@ +/* + * File: random.h + * Author: mbrampton + * + * Created on 26 August 2015, 15:34 + */ + +#ifndef RANDOM_H +#define RANDOM_H + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int random_jkiss(void); + +#ifdef __cplusplus +} +#endif + +#endif /* RANDOM_H */ + From 820bb4ea0037482c3d9da7f92d88346551b9c759 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 16:18:08 +0100 Subject: [PATCH 017/179] Avoid name clash - change random to random_jkiss --- server/core/CMakeLists.txt | 6 +++--- server/core/{random.c => random_jkiss.c} | 4 ++-- server/core/secrets.c | 2 +- server/core/utils.c | 2 +- server/include/{random.h => random_jkiss.h} | 2 +- utils/skygw_utils.cc | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename server/core/{random.c => random_jkiss.c} (95%) rename server/include/{random.h => random_jkiss.h} (90%) diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index a2e9208e8..43318d018 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,5 +1,5 @@ if(BUILD_TESTS OR BUILD_TOOLS) - add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c) + add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c random_jkiss.c) if(WITH_JEMALLOC) target_link_libraries(fullcore ${JEMALLOC_LIBRARIES}) elseif(WITH_TCMALLOC) @@ -11,8 +11,8 @@ endif() add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c gw_utils.c utils.c dcb.c load_utils.c session.c service.c server.c poll.c config.c users.c hashtable.c dbusers.c thread.c gwbitmask.c - monitor.c adminusers.c secrets.c filter.c modutil.c hint.c - housekeeper.c memlog.c resultset.c gwdirs.c externcmd.c) + monitor.c adminusers.c secrets.c filter.c modutil.c hint.c + housekeeper.c memlog.c resultset.c gwdirs.c externcmd.c random_jkiss.c) if(WITH_JEMALLOC) target_link_libraries(maxscale ${JEMALLOC_LIBRARIES}) diff --git a/server/core/random.c b/server/core/random_jkiss.c similarity index 95% rename from server/core/random.c rename to server/core/random_jkiss.c index bba20ade5..37e008612 100644 --- a/server/core/random.c +++ b/server/core/random_jkiss.c @@ -17,7 +17,7 @@ */ /** - * @file random.c - Random number generator for the MariaDB Corporation MaxScale + * @file random_jkiss.c - Random number generator for the MariaDB Corporation MaxScale * * @verbatim * Revision History @@ -32,7 +32,7 @@ #include #include #include -#include +#include /* Public domain code for JKISS RNG - Comments added */ static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217; /* Seed variables */ diff --git a/server/core/secrets.c b/server/core/secrets.c index b614a5555..7fbd0d096 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; diff --git a/server/core/utils.c b/server/core/utils.c index 45b47e632..df16180c2 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; diff --git a/server/include/random.h b/server/include/random_jkiss.h similarity index 90% rename from server/include/random.h rename to server/include/random_jkiss.h index b302594d2..ee321afed 100644 --- a/server/include/random.h +++ b/server/include/random_jkiss.h @@ -1,5 +1,5 @@ /* - * File: random.h + * File: random_jkiss.h * Author: mbrampton * * Created on 26 August 2015, 15:34 diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index 7ca3baec3..46976e254 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -30,7 +30,7 @@ #include #include "skygw_utils.h" #include -#include +#include #if defined(MLIST) From 4ec5e3b69dad11be732f56a326a500aa4acbfe1c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 16:18:37 +0100 Subject: [PATCH 018/179] Change header random.h to random_jkiss.h --- server/include/random_jkiss.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/include/random_jkiss.h b/server/include/random_jkiss.h index ee321afed..661294437 100644 --- a/server/include/random_jkiss.h +++ b/server/include/random_jkiss.h @@ -5,8 +5,8 @@ * Created on 26 August 2015, 15:34 */ -#ifndef RANDOM_H -#define RANDOM_H +#ifndef RANDOM_JKISS_H +#define RANDOM_JKISS_H #ifdef __cplusplus extern "C" { From b66bcbd36c6da6126b6e237120c14ac97296db8c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 16:30:08 +0100 Subject: [PATCH 019/179] Correct small mistake --- server/include/random_jkiss.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/include/random_jkiss.h b/server/include/random_jkiss.h index 661294437..21d638c82 100644 --- a/server/include/random_jkiss.h +++ b/server/include/random_jkiss.h @@ -12,7 +12,7 @@ extern "C" { #endif -unsigned int random_jkiss(void); +extern unsigned int random_jkiss(void); #ifdef __cplusplus } From 70d82fd45ee0a01d5788192eb052dcaba8e6457e Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 26 Aug 2015 18:33:46 +0300 Subject: [PATCH 020/179] Fixed compilation problems. --- server/core/CMakeLists.txt | 4 ++-- server/core/poll.c | 2 +- server/core/random_jkiss.c | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 43318d018..2dabf4d33 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -23,11 +23,11 @@ endif() target_link_libraries(maxscale ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++) install(TARGETS maxscale DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c) +add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c random_jkiss.c) target_link_libraries(maxkeys log_manager utils pthread crypt crypto) install(TARGETS maxkeys DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c) +add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c random_jkiss.c) target_link_libraries(maxpasswd log_manager utils pthread crypt crypto) install(TARGETS maxpasswd DESTINATION ${MAXSCALE_BINDIR}) diff --git a/server/core/poll.c b/server/core/poll.c index 5a9c72829..e0bcb0d0c 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -1135,7 +1135,7 @@ poll_dcb_session_check(DCB *dcb) LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "%lu [%s] The dcb %p that was about to be processed does not " - "have a non-null session pointer " + "have a non-null session pointer ", pthread_self(), __func__, dcb))); diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index 37e008612..a4443890b 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -38,6 +38,8 @@ static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217; /* Seed variables */ static bool init = false; +static void random_init_jkiss(); + /*** * * Return a random number @@ -94,4 +96,4 @@ random_init_jkiss() if ((newrand = random_devrand()) != 0) c = newrand % 698769068 + 1; /* Should be less than 698769069 */ for (i = 0; i < 1000; i++) random_jkiss(); -} \ No newline at end of file +} From 57b82dcedb16b05703a588db7259b406f30abd55 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 16:36:08 +0100 Subject: [PATCH 021/179] Correct initialisation logic. --- server/core/random_jkiss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index a4443890b..350154dd7 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -51,7 +51,11 @@ unsigned int random_jkiss(void) { unsigned long long t; - if (!init) random_init_jkiss(); + if (!init) + { + random_init_jkiss(); + init = true; + } x = 314527869 * x + 1234567; y ^= y << 5; y ^= y >> 7; y ^= y << 22; t = 4294584393ULL * z + c; c = t >> 32; z = t; From c01aa6952e9459cf9a362f256394e87f2f9d8f8a Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 26 Aug 2015 17:16:10 +0100 Subject: [PATCH 022/179] Fix initialisation problem; put all statements on separate lines. --- server/core/random_jkiss.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index 350154dd7..bfafd8054 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -32,6 +32,7 @@ #include #include #include +#include #include /* Public domain code for JKISS RNG - Comments added */ @@ -53,12 +54,16 @@ random_jkiss(void) unsigned long long t; if (!init) { - random_init_jkiss(); init = true; + random_init_jkiss(); } x = 314527869 * x + 1234567; - y ^= y << 5; y ^= y >> 7; y ^= y << 22; - t = 4294584393ULL * z + c; c = t >> 32; z = t; + y ^= y << 5; + y ^= y >> 7; + y ^= y << 22; + t = 4294584393ULL * z + c; + c = t >> 32; + z = t; return x + y + z; } @@ -99,5 +104,5 @@ random_init_jkiss() if ((newrand = random_devrand()) != 0) z = newrand; if ((newrand = random_devrand()) != 0) c = newrand % 698769068 + 1; /* Should be less than 698769069 */ - for (i = 0; i < 1000; i++) random_jkiss(); + for (i = 0; i < 100; i++) random_jkiss(); } From 0d62f5281284d49185e730ed57d64a8e5083902c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 09:12:41 +0100 Subject: [PATCH 023/179] Ensure thread safe through use of spinlock; add further comments. --- server/core/random_jkiss.c | 48 +++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index bfafd8054..feb0aa19a 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -18,6 +18,9 @@ /** * @file random_jkiss.c - Random number generator for the MariaDB Corporation MaxScale + * + * See http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf for discussion of random + * number generators (RNGs). * * @verbatim * Revision History @@ -35,15 +38,22 @@ #include #include -/* Public domain code for JKISS RNG - Comments added */ +/* Public domain code for JKISS RNG - Comment header added */ + +/* If possible, the seed variables will be set from /dev/urandom but + * should that fail, these arbitrary numbers will be used as a last resort. + */ static unsigned int x = 123456789,y = 987654321,z = 43219876,c = 6543217; /* Seed variables */ static bool init = false; -static void random_init_jkiss(); +static SPINLOCK random_jkiss_spinlock = SPINLOCK_INIT; + +static unsigned int random_jkiss_devrand(void); +static void random_init_jkiss(void); /*** * - * Return a random number + * Return a pseudo-random number that satisfies major tests for random sequences * * @return uint Random number * @@ -52,9 +62,13 @@ unsigned int random_jkiss(void) { unsigned long long t; + unsigned int result; + spinlock_acquire(&random_jkiss_spinlock); if (!init) { + /* Must set init first because initialisation calls this function */ init = true; + spinlock_release(&random_jkiss_spinlock); random_init_jkiss(); } x = 314527869 * x + 1234567; @@ -64,7 +78,9 @@ random_jkiss(void) t = 4294584393ULL * z + c; c = t >> 32; z = t; - return x + y + z; + result = x + y + z; + spinlock_release(&random_jkiss_spinlock); + return result; } /* Own code adapted from http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf */ @@ -72,19 +88,21 @@ random_jkiss(void) /*** * * Obtain a seed random number from /dev/urandom if available. - * Otherwise use constant values * * @return uint Random number * */ static unsigned int -random_devrand() +random_jkiss_devrand(void) { int fn; unsigned int r; - fn = open("/dev/urandom", O_RDONLY); - if (fn == -1) return 0; - if (read(fn, &r, 4) != 4) return 0; + if ((fn = open("/dev/urandom", O_RDONLY)) == -1) return 0; + if (read(fn, &r, 4) != 4) + { + close(fn); + return 0; + } close(fn); return r; } @@ -96,13 +114,15 @@ random_devrand() * */ static void -random_init_jkiss() +random_init_jkiss(void) { int newrand, i; - if ((newrand = random_devrand()) != 0) x = newrand; - if ((newrand = random_devrand()) != 0) y = newrand; - if ((newrand = random_devrand()) != 0) z = newrand; - if ((newrand = random_devrand()) != 0) + if ((newrand = random_jkiss_devrand()) != 0) x = newrand; + if ((newrand = random_jkiss_devrand()) != 0) y = newrand; + if ((newrand = random_jkiss_devrand()) != 0) z = newrand; + if ((newrand = random_jkiss_devrand()) != 0) c = newrand % 698769068 + 1; /* Should be less than 698769069 */ + + /* "Warm up" our random number generator */ for (i = 0; i < 100; i++) random_jkiss(); } From 9c5f6224818a99f0fb93ea87494ff25e0058f6f9 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 15:30:06 +0100 Subject: [PATCH 024/179] Additional spinlock in random_jkiss. Initial attempt at implementing dummy sessions to provide total consistency - used in mysql_client in relation to authentication - a single static dummy session is used and linked from the client dcb when authentication is not yet complete. --- server/core/dcb.c | 5 ++- server/core/random_jkiss.c | 2 + server/core/session.c | 53 +++++++++++++++++++++++++ server/include/session.h | 4 +- server/modules/protocol/mysql_backend.c | 2 +- server/modules/protocol/mysql_client.c | 5 ++- utils/skygw_debug.h | 9 +++-- 7 files changed, 71 insertions(+), 9 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 448c9a091..013029de6 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -346,7 +346,10 @@ dcb_final_free(DCB *dcb) local_session->client = NULL; spinlock_release(&local_session->ses_lock); } - session_free(local_session); + if (SESSION_STATE_DUMMY != local_session->state) + { + session_free(local_session); + } } } diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index feb0aa19a..f60b4beee 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -117,11 +117,13 @@ static void random_init_jkiss(void) { int newrand, i; + spinlock_acquire(&random_jkiss_spinlock); if ((newrand = random_jkiss_devrand()) != 0) x = newrand; if ((newrand = random_jkiss_devrand()) != 0) y = newrand; if ((newrand = random_jkiss_devrand()) != 0) z = newrand; if ((newrand = random_jkiss_devrand()) != 0) c = newrand % 698769068 + 1; /* Should be less than 698769069 */ + spinlock_release(&random_jkiss_spinlock); /* "Warm up" our random number generator */ for (i = 0; i < 100; i++) random_jkiss(); diff --git a/server/core/session.c b/server/core/session.c index 31bbbd637..b50d5e0c8 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -56,6 +56,7 @@ static size_t session_id; static SPINLOCK session_spin = SPINLOCK_INIT; static SESSION *allSessions = NULL; +static struct session session_dummy_struct; static int session_setup_filters(SESSION *session); static void session_simple_free(SESSION *session, DCB *dcb); @@ -212,6 +213,48 @@ session_alloc(SERVICE *service, DCB *client_dcb) return session; } +/** + * Allocate a dummy session so that DCBs can always have sessions. + * + * Only one dummy session exists, it is statically declared + * + * @param client_dcb The client side DCB + * @return The dummy created session + */ +SESSION * +session_alloc_dummy(DCB *client_dcb) +{ + SESSION *session; + + session = &session_dummy_struct; +#if defined(SS_DEBUG) + session->ses_chk_top = CHK_NUM_SESSION; + session->ses_chk_tail = CHK_NUM_SESSION; +#endif + session->ses_is_child = false; + spinlock_init(&session->ses_lock); + session->service = NULL; + session->client = NULL; + session->n_filters = 0; + memset(&session->stats, 0, sizeof(SESSION_STATS)); + session->stats.connect = 0; + session->state = SESSION_STATE_DUMMY; + /*< + * Associate the session to the client DCB and set the reference count on + * the session to indicate that there is a single reference to the + * session. There is no need to protect this or use atomic add as the + * session has not been made available to the other threads at this + * point. + */ + session->data = NULL; + session->refcount = 1; + session->ses_id = 0; + session->next = NULL; + + client_dcb->session = session; + return session; +} + /** * Enable specified logging for the current session and increase logger * counter. @@ -323,6 +366,10 @@ session_simple_free(SESSION *session, DCB *dcb) } if (session) { + if (SESSION_STATE_DUMMY == session->state) + { + return; + } if (session && session->router_session) { session->service->router->freeSession( @@ -344,6 +391,10 @@ session_simple_free(SESSION *session, DCB *dcb) bool session_free(SESSION *session) { + if (session && SESSION_STATE_DUMMY == session->state) + { + return true; + } CHK_SESSION(session); /* @@ -711,6 +762,8 @@ session_state(int state) { case SESSION_STATE_ALLOC: return "Session Allocated"; + case SESSION_STATE_DUMMY: + return "Dummy Session"; case SESSION_STATE_READY: return "Session Ready"; case SESSION_STATE_ROUTER_READY: diff --git a/server/include/session.h b/server/include/session.h index 7a9381507..e916c902e 100644 --- a/server/include/session.h +++ b/server/include/session.h @@ -64,7 +64,8 @@ typedef enum { SESSION_STATE_LISTENER, /*< for listener session */ SESSION_STATE_LISTENER_STOPPED, /*< for listener session */ SESSION_STATE_TO_BE_FREED, /*< ready to be freed as soon as there are no references */ - SESSION_STATE_FREE /*< for all sessions */ + SESSION_STATE_FREE, /*< for all sessions */ + SESSION_STATE_DUMMY /*< dummy session for consistency */ } session_state_t; /** @@ -162,6 +163,7 @@ typedef struct session { SESSION *get_all_sessions(); SESSION *session_alloc(struct service *, struct dcb *); +SESSION *session_alloc_dummy(struct dcb *); bool session_free(SESSION *); int session_isvalid(SESSION *); int session_reply(void *inst, void *session, GWBUF *data); diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index de178fe60..6a024c348 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -140,7 +140,7 @@ static MYSQL_session* gw_get_shared_session_auth_info( spinlock_acquire(&dcb->session->ses_lock); - if (dcb->session->state != SESSION_STATE_ALLOC) { + if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY) { auth_info = dcb->session->data; } else { LOGIF(LE, (skygw_log_write_flush( diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 70ddcac84..33515c89b 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -912,7 +912,7 @@ int gw_read_client_event( if (session != NULL) { CHK_SESSION(session); - ss_dassert(session->state != SESSION_STATE_ALLOC); + ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY); protocol->protocol_auth_state = MYSQL_IDLE; /** @@ -1012,7 +1012,7 @@ int gw_read_client_event( if (session != NULL) { CHK_SESSION(session); - ss_dassert(session->state != SESSION_STATE_ALLOC); + ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY); protocol->protocol_auth_state = MYSQL_IDLE; /** @@ -1643,6 +1643,7 @@ int gw_MySQLAccept(DCB *listener) } client_dcb->service = listener->session->service; + client_dcb->session = session_alloc_dummy(client_dcb); client_dcb->fd = c_sock; // get client address diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index ff5d5c9c0..8f164b828 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -210,10 +210,11 @@ typedef enum skygw_chk_t { ((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN"))))))) #define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \ - ((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \ - ((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \ - ((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \ - (s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY":\ + ((s) == SESSION_STATE_DUMMY ? "SESSION_STATE_DUMMY" : \ + ((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \ + ((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \ + ((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \ + (s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY":\ "SESSION_STATE_UNKNOWN")))) #define STRPROTOCOLSTATE(s) ((s) == MYSQL_ALLOC ? "MYSQL_ALLOC" : \ From 753746f5c50e8c206df14dbdc1cdc320e4ba417a Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 16:12:36 +0100 Subject: [PATCH 025/179] Fix mistakes --- server/core/CMakeLists.txt | 4 ++-- server/core/random_jkiss.c | 2 ++ utils/skygw_debug.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 2dabf4d33..5ad84ce59 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -23,11 +23,11 @@ endif() target_link_libraries(maxscale ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ${CURL_LIBRARIES} log_manager utils ssl aio pthread crypt dl crypto inih z rt m stdc++) install(TARGETS maxscale DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c random_jkiss.c) +add_executable(maxkeys maxkeys.c secrets.c utils.c gwdirs.c spinlock.c random_jkiss.c) target_link_libraries(maxkeys log_manager utils pthread crypt crypto) install(TARGETS maxkeys DESTINATION ${MAXSCALE_BINDIR}) -add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c random_jkiss.c) +add_executable(maxpasswd maxpasswd.c secrets.c utils.c gwdirs.c spinlock.c random_jkiss.c) target_link_libraries(maxpasswd log_manager utils pthread crypt crypto) install(TARGETS maxpasswd DESTINATION ${MAXSCALE_BINDIR}) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index f60b4beee..6eea33739 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* Public domain code for JKISS RNG - Comment header added */ @@ -63,6 +64,7 @@ random_jkiss(void) { unsigned long long t; unsigned int result; + spinlock_acquire(&random_jkiss_spinlock); if (!init) { diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index 8f164b828..c5c1c0ce9 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -215,7 +215,7 @@ typedef enum skygw_chk_t { ((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \ ((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \ (s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY":\ - "SESSION_STATE_UNKNOWN")))) + "SESSION_STATE_UNKNOWN"))))) #define STRPROTOCOLSTATE(s) ((s) == MYSQL_ALLOC ? "MYSQL_ALLOC" : \ ((s) == MYSQL_PENDING_CONNECT ? "MYSQL_PENDING_CONNECT" : \ From 068ec77d053d16aab8715237f6ca78e229e74711 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 16:44:40 +0100 Subject: [PATCH 026/179] Fix bugs. --- server/modules/protocol/mysql_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 33515c89b..a90feab39 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -750,7 +750,7 @@ int gw_read_client_event( session = dcb->session; - if (protocol->protocol_auth_state == MYSQL_IDLE && session != NULL) + if (protocol->protocol_auth_state == MYSQL_IDLE && session != NULL && SESSION_STATE_DUMMY != session->state) { CHK_SESSION(session); router = session->service->router; @@ -1096,7 +1096,7 @@ int gw_read_client_event( session_state_t ses_state; session = dcb->session; - ss_dassert(session!= NULL); + ss_dassert(session!= NULL && SESSION_STATE_DUMMY != session->state); if (session != NULL) { @@ -1803,7 +1803,7 @@ gw_client_close(DCB *dcb) * session may be NULL if session_alloc failed. * In that case, router session wasn't created. */ - if (session != NULL) + if (session != NULL && SESSION_STATE_DUMMY != session->state) { CHK_SESSION(session); spinlock_acquire(&session->ses_lock); From 53383189003c4270a69c00573e2684a71023dd52 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 17:25:41 +0100 Subject: [PATCH 027/179] Improve error message when DCB has no session pointer in poll loop. --- server/core/poll.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/server/core/poll.c b/server/core/poll.c index e0bcb0d0c..15e31d313 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -96,7 +96,7 @@ static simple_mutex_t epoll_wait_mutex; /*< serializes calls to epoll_wait */ static int n_waiting = 0; /*< No. of threads in epoll_wait */ static int process_pollq(int thread_id); static void poll_add_event_to_dcb(DCB* dcb, GWBUF* buf, __uint32_t ev); -static bool poll_dcb_session_check(DCB *dcb); +static bool poll_dcb_session_check(DCB *dcb, const char *); DCB *eventq = NULL; SPINLOCK pollqlock = SPINLOCK_INIT; @@ -885,7 +885,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "write_ready")) { dcb->func.write_ready(dcb); } @@ -918,7 +918,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "accept")) { dcb->func.accept(dcb); } @@ -938,7 +938,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "read")) { dcb->func.read(dcb); } @@ -976,7 +976,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "error")) { dcb->func.error(dcb); } @@ -1008,7 +1008,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "hangup EPOLLHUP")) { dcb->func.hangup(dcb); } @@ -1044,7 +1044,7 @@ unsigned long qtime; dcb, &tls_log_info.li_sesid, &tls_log_info.li_enabled_logs))); - if (poll_dcb_session_check(dcb)) + if (poll_dcb_session_check(dcb, "hangup EPOLLRDHUP")) { dcb->func.hangup(dcb); } @@ -1120,11 +1120,12 @@ unsigned long qtime; * Check that the DCB has a session link before processing. * If not, log an error. Processing will be bypassed * - * @param dcb The DCB to check - * @return bool Does the DCB have a non-null session link + * @param dcb The DCB to check + * @param function The name of the function about to be called + * @return bool Does the DCB have a non-null session link */ static bool -poll_dcb_session_check(DCB *dcb) +poll_dcb_session_check(DCB *dcb, const char *function) { if (dcb->session) { @@ -1134,11 +1135,12 @@ poll_dcb_session_check(DCB *dcb) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "%lu [%s] The dcb %p that was about to be processed does not " + "%lu [%s] The dcb %p that was about to be processed by %s does not " "have a non-null session pointer ", pthread_self(), __func__, - dcb))); + dcb, + function))); return false; } } From d29c5909a63f736455acd43530abf6615820f17b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 28 Aug 2015 19:49:03 +0300 Subject: [PATCH 028/179] Properly close the branch session of the tee filter. --- server/modules/filter/tee.c | 61 +++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 1557166f9..996f247db 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -212,6 +212,7 @@ int route_single_query(TEE_INSTANCE* my_instance, GWBUF* buffer, GWBUF* clone); int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer); +void create_orphan(SESSION* ses); static void orphan_free(void* data) @@ -557,6 +558,7 @@ char *remote, *userName; if ((ses = session_alloc(my_instance->service, dcb)) == NULL) { + filter_free(dummy); dcb_close(dcb); freeSession(instance, (void *)my_session); my_session = NULL; @@ -572,39 +574,27 @@ char *remote, *userName; dummy->obj = GetModuleObject(); dummy->filter = NULL; - + my_session->branch_session = ses; + my_session->branch_dcb = dcb; + my_session->dummy_filterdef = dummy; - if((dummy_upstream = filterUpstream( + if(true || (dummy_upstream = filterUpstream( dummy, my_session, &ses->tail)) == NULL) { - spinlock_acquire(&ses->ses_lock); - ses->state = SESSION_STATE_STOPPING; - spinlock_release(&ses->ses_lock); - - ses->service->router->closeSession( - ses->service->router_instance, - ses->router_session); - - ses->client = NULL; - dcb->session = NULL; - session_free(ses); + filter_free(dummy); + closeSession(instance,(void*)my_session); dcb_close(dcb); - freeSession(instance, (void *) my_session); - my_session = NULL; + free(my_session); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : tee: Allocating memory for" "dummy upstream failed." " Terminating session."))); - goto retblock; + return NULL; } ses->tail = *dummy_upstream; - my_session->branch_session = ses; - my_session->branch_dcb = dcb; - my_session->dummy_filterdef = dummy; - MySQLProtocol* protocol = (MySQLProtocol*)session->client->protocol; my_session->use_ok = protocol->client_capabilities & (1 << 6); free(dummy_upstream); @@ -712,19 +702,7 @@ skygw_log_write(LOGFILE_TRACE,"Tee free: %d", atomic_add(&debug_seq,1)); } else if(state == SESSION_STATE_STOPPING) { - orphan_session_t* orphan; - if((orphan = malloc(sizeof(orphan_session_t))) == NULL) - { - skygw_log_write(LOGFILE_ERROR,"Error : Failed to " - "allocate memory for orphan session struct, " - "child session might leak memory."); - }else{ - orphan->session = ses; - spinlock_acquire(&orphanLock); - orphan->next = allOrphans; - allOrphans = orphan; - spinlock_release(&orphanLock); - } + create_orphan(ses); } } if (my_session->dummy_filterdef) @@ -1400,4 +1378,21 @@ int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer) my_session->command = command; return 1; +} + +void create_orphan(SESSION* ses) +{ + orphan_session_t* orphan; + if((orphan = malloc(sizeof(orphan_session_t))) == NULL) + { + skygw_log_write(LOGFILE_ERROR,"Error : Failed to " + "allocate memory for orphan session struct, " + "child session might leak memory."); + }else{ + orphan->session = ses; + spinlock_acquire(&orphanLock); + orphan->next = allOrphans; + allOrphans = orphan; + spinlock_release(&orphanLock); + } } \ No newline at end of file From f1c3b65b1539fdff6f7a4c019652be05ba45a344 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 28 Aug 2015 19:52:02 +0300 Subject: [PATCH 029/179] Fixed mistake. --- server/modules/filter/tee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 996f247db..6486a9a19 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -578,7 +578,7 @@ char *remote, *userName; my_session->branch_dcb = dcb; my_session->dummy_filterdef = dummy; - if(true || (dummy_upstream = filterUpstream( + if((dummy_upstream = filterUpstream( dummy, my_session, &ses->tail)) == NULL) { filter_free(dummy); From a711b25fec07074e31962fe25b2cded635a8ccfc Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 28 Aug 2015 18:20:18 +0100 Subject: [PATCH 030/179] Improve user name setting in DCB for persistent connections and to fix bug; change name of session_alloc_dummy to session_set_dummy to be more informative. --- server/core/dcb.c | 11 ++++++----- server/core/session.c | 2 +- server/include/session.h | 2 +- server/modules/protocol/mysql_client.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 013029de6..ab1e3638e 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1845,9 +1845,6 @@ dcb_close(DCB *dcb) spinlock_acquire(&zombiespin); if (!dcb->dcb_is_zombie) { - char *user; - user = session_getUser(dcb->session); - if (NULL != user) dcb->user = strdup(user); /*< * Add closing dcb to the top of the list, setting zombie marker */ @@ -1873,8 +1870,10 @@ static bool dcb_maybe_add_persistent(DCB *dcb) { int poolcount = -1; - if (dcb->user != NULL - && strlen(dcb->user) + char *user; + user = session_getUser(dcb->session); + if (user != NULL + && strlen(user) && dcb->server && dcb->server->persistpoolmax && !dcb->dcb_errhandle_called @@ -1888,6 +1887,8 @@ dcb_maybe_add_persistent(DCB *dcb) dcb->user))); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); + if (dcb->user) free(dcb->user); + dcb->user = strdup(user); spinlock_acquire(&dcb->server->persistlock); dcb->nextpersistent = dcb->server->persistent; dcb->server->persistent = dcb; diff --git a/server/core/session.c b/server/core/session.c index b50d5e0c8..1411d34bd 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -222,7 +222,7 @@ session_alloc(SERVICE *service, DCB *client_dcb) * @return The dummy created session */ SESSION * -session_alloc_dummy(DCB *client_dcb) +session_set_dummy(DCB *client_dcb) { SESSION *session; diff --git a/server/include/session.h b/server/include/session.h index e916c902e..edb4af1d4 100644 --- a/server/include/session.h +++ b/server/include/session.h @@ -163,7 +163,7 @@ typedef struct session { SESSION *get_all_sessions(); SESSION *session_alloc(struct service *, struct dcb *); -SESSION *session_alloc_dummy(struct dcb *); +SESSION *session_set_dummy(struct dcb *); bool session_free(SESSION *); int session_isvalid(SESSION *); int session_reply(void *inst, void *session, GWBUF *data); diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index a90feab39..077ec6918 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1643,7 +1643,7 @@ int gw_MySQLAccept(DCB *listener) } client_dcb->service = listener->session->service; - client_dcb->session = session_alloc_dummy(client_dcb); + client_dcb->session = session_set_dummy(client_dcb); client_dcb->fd = c_sock; // get client address From d74990833bb67ff3ed9193f7ad4d18fd202d4e52 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 1 Sep 2015 09:59:34 +0100 Subject: [PATCH 031/179] Move capture of user name for persistent connections; expand error message in mysql client to give more information. --- server/core/dcb.c | 18 ++++++++++++------ server/modules/protocol/mysql_client.c | 6 ++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index ab1e3638e..7112ef7a3 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1845,6 +1845,16 @@ dcb_close(DCB *dcb) spinlock_acquire(&zombiespin); if (!dcb->dcb_is_zombie) { + if (dcb->server && DCB_STATE_POLLING == dcb->state) + { + /* May be a candidate for persistence, so save user name */ + char *user; + user = session_getUser(dcb->session); + if (user && strlen(user) && !dcb->user) + { + dcb->user = strdup(user); + } + } /*< * Add closing dcb to the top of the list, setting zombie marker */ @@ -1870,10 +1880,8 @@ static bool dcb_maybe_add_persistent(DCB *dcb) { int poolcount = -1; - char *user; - user = session_getUser(dcb->session); - if (user != NULL - && strlen(user) + if (dcb->user != NULL + && strlen(dcb->user) && dcb->server && dcb->server->persistpoolmax && !dcb->dcb_errhandle_called @@ -1887,8 +1895,6 @@ dcb_maybe_add_persistent(DCB *dcb) dcb->user))); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); - if (dcb->user) free(dcb->user); - dcb->user = strdup(user); spinlock_acquire(&dcb->server->persistlock); dcb->nextpersistent = dcb->server->persistent; dcb->server->persistent = dcb; diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 077ec6918..ac5381df3 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1859,8 +1859,10 @@ gw_client_hangup_event(DCB *dcb) } #if defined(SS_DEBUG) LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Client hangup error handling."))); + LOGFILE_ERROR, + "Client hangup error handling, session state %s, dcb state %s.", + session_state(session->state), + STRDCBSTATE(dcb->state)))); #endif dcb_close(dcb); From d3cdaa43467ae37d55618a45dd4ce1b8c03a8c2e Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 4 Sep 2015 18:09:43 +0100 Subject: [PATCH 032/179] No need to process zombie victims if queue is empty. --- server/core/dcb.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 7112ef7a3..63a345284 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -510,7 +510,10 @@ DCB *dcb = NULL; } spinlock_release(&zombiespin); - dcb_process_victim_queue(listofdcb); + if (listofdcb) + { + dcb_process_victim_queue(listofdcb); + } return zombies; } @@ -527,12 +530,11 @@ DCB *dcb = NULL; static inline void dcb_process_victim_queue(DCB *listofdcb) { - DCB *dcb; + DCB *dcb = listofdcb; - dcb = listofdcb; while (dcb != NULL) { - DCB *nextdcb = NULL; + DCB *nextdcb; /*< * Stop dcb's listening and modify state accordingly. */ @@ -1813,12 +1815,6 @@ dcb_close(DCB *dcb) { CHK_DCB(dcb); - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [dcb_close] DCB %p in state %s", - pthread_self(), - dcb, - dcb ? STRDCBSTATE(dcb->state) : "Invalid DCB"))); - if (DCB_STATE_UNDEFINED == dcb->state || DCB_STATE_DISCONNECTED == dcb->state) { From 42c9532a5642134ad10cdbaf36edafe741ffe638 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Sat, 5 Sep 2015 00:32:29 +0100 Subject: [PATCH 033/179] Simplify logic and reverse list to kill, so as to cancel out the reversal in the original zombie list. Probably not significant, but might be helpful. --- server/core/dcb.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 63a345284..7cc647a81 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -401,9 +401,9 @@ dcb_final_free(DCB *dcb) DCB * dcb_process_zombies(int threadid) { -DCB *zombiedcb, *previousdcb; +DCB *zombiedcb; +DCB *previousdcb = NULL, *nextdcb; DCB *listofdcb = NULL; -DCB *dcb = NULL; /** * Perform a dirty read to see if there is anything in the queue. @@ -413,7 +413,9 @@ DCB *dcb = NULL; * dcb_final_free. */ if (!zombies) + { return NULL; + } /* * Process the zombie queue and create a list of DCB's that can be @@ -426,11 +428,10 @@ DCB *dcb = NULL; */ spinlock_acquire(&zombiespin); zombiedcb = zombies; - previousdcb = NULL; while (zombiedcb) { CHK_DCB(zombiedcb); - + nextdcb = zombiedcb->memdata.next; /* * Skip processing of DCB's that are * in the event queue waiting to be processed. @@ -438,7 +439,6 @@ DCB *dcb = NULL; if (zombiedcb->evq.next || zombiedcb->evq.prev) { previousdcb = zombiedcb; - zombiedcb = zombiedcb->memdata.next; } else { @@ -484,29 +484,17 @@ DCB *dcb = NULL; * (listofdcb) is not NULL, then it follows that * dcb will also not be null. */ - if (listofdcb == NULL) - { - listofdcb = zombiedcb; - } - else - { - dcb->memdata.next = zombiedcb; - } - /* Set dcb for next iteration of loop */ - dcb = zombiedcb; - zombiedcb = zombiedcb->memdata.next; - /* After we've moved zombiedcb forward, set - link to null as dcb is last of the new list */ - dcb->memdata.next = NULL; + zombiedcb->memdata.next = listofdcb; + listofdcb = zombiedcb; } else { - /* Since we didn't remove this dcb from the zombies - list, we need to advance the previous pointer */ + /* Since we didn't remove this dcb from the zombies + list, we need to advance the previous pointer */ previousdcb = zombiedcb; - zombiedcb = zombiedcb->memdata.next; } } + zombiedcb = nextdcb; } spinlock_release(&zombiespin); From 4a1ad3df6930733435817d642ee5708293d24a18 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Sat, 5 Sep 2015 08:53:19 +0100 Subject: [PATCH 034/179] Attempt solution to crash caused by leaving link to backend DCB in router session. --- server/modules/protocol/mysql_backend.c | 1 - server/modules/routing/readconnroute.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 6a024c348..b737d0f58 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -1145,7 +1145,6 @@ gw_backend_hangup(DCB *dcb) spinlock_release(&session->ses_lock); } ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); retblock: return 1; diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index ccb071e1a..a8dfb1f72 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -855,6 +856,7 @@ static void handleError( DCB *client_dcb; SESSION *session = backend_dcb->session; session_state_t sesstate; + ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session; /** Reset error handle flag from a given DCB */ if (action == ERRACT_RESET) @@ -888,6 +890,14 @@ static void handleError( { spinlock_release(&session->ses_lock); } + + if (backend_dcb != router_cli_ses->backend_dcb) + { + /* Linkages have gone badly wrong - this may not be best solution */ + raise(SIGABRT); + } + router_cli_ses->backend_dcb = NULL; + dcb_close(backend_dcb); /** false because connection is not available anymore */ *succp = false; From 986c918d52cdeba5b92685371482705b3708a982 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 9 Sep 2015 08:31:59 +0100 Subject: [PATCH 035/179] Remove ERRACT_RESET action from router error handler; remove sole call from mysql_client. Correct comments on parameters for router error handlers. --- server/include/router.h | 3 +-- server/modules/protocol/mysql_client.c | 2 +- server/modules/routing/binlog/blr.c | 10 ++-------- server/modules/routing/maxinfo/maxinfo.c | 10 ++-------- server/modules/routing/readconnroute.c | 10 ++-------- server/modules/routing/readwritesplit/readwritesplit.c | 5 ++--- server/modules/routing/schemarouter/schemarouter.c | 9 +++------ server/modules/routing/schemarouter/shardrouter.c | 8 +++----- 8 files changed, 16 insertions(+), 41 deletions(-) diff --git a/server/include/router.h b/server/include/router.h index 3815253bf..4faa2ca81 100644 --- a/server/include/router.h +++ b/server/include/router.h @@ -45,8 +45,7 @@ typedef void *ROUTER; typedef enum error_action { ERRACT_NEW_CONNECTION = 0x001, - ERRACT_REPLY_CLIENT = 0x002, - ERRACT_RESET = 0x004 + ERRACT_REPLY_CLIENT = 0x002 } error_action_t; /** diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index ac5381df3..6d0561abd 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1130,7 +1130,7 @@ int gw_read_client_event( else { /** Reset error handler when routing of the new query begins */ - router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL); + dcb->dcb_errhandle_called = false; if (stmt_input) { diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 630665628..4d3e356f5 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -1072,8 +1072,8 @@ int len; * @param router_session The router session * @param message The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION - * @param succp Result of action + * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT + * @param succp Result of action: true iff router can continue * */ static void @@ -1084,12 +1084,6 @@ int error; socklen_t len; char msg[85], *errmsg; - if (action == ERRACT_RESET) - { - backend_dcb->dcb_errhandle_called = false; - return; - } - /** Don't handle same error twice on same DCB */ if (backend_dcb->dcb_errhandle_called) { diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 386a4c850..8ac6ce8cc 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -291,7 +291,8 @@ static void freeSession( * @param router_session The router session * @param message The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION + * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT + * @param succp Result of action: true iff router can continue * */ static void handleError( @@ -307,13 +308,6 @@ static void handleError( SESSION *session = backend_dcb->session; session_state_t sesstate; - /** Reset error handle flag from a given DCB */ - if (action == ERRACT_RESET) - { - backend_dcb->dcb_errhandle_called = false; - return; - } - /** Don't handle same error twice on same DCB */ if (backend_dcb->dcb_errhandle_called) { diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index a8dfb1f72..3be509444 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -841,7 +841,8 @@ clientReply( * @param router_session The router session * @param message The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION + * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT + * @param succp Result of action: true if router can continue * */ static void handleError( @@ -858,13 +859,6 @@ static void handleError( session_state_t sesstate; ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session; - /** Reset error handle flag from a given DCB */ - if (action == ERRACT_RESET) - { - backend_dcb->dcb_errhandle_called = false; - return; - } - /** Don't handle same error twice on same DCB */ if (backend_dcb->dcb_errhandle_called) { diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 417abdfe7..7f014bf55 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4805,9 +4805,8 @@ static void rwsplit_process_router_options( * @param router_session The router session * @param errmsgbuf The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION - * @param succp Result of action. True if there is at least master - * and enough slaves to continue session. Otherwise false. + * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT + * @param succp Result of action: true iff 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. diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index d0c6ad59c..a058db7e7 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -4096,8 +4096,8 @@ return_succp: * @param router_session The router session * @param errmsgbuf The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION - * @param succp Result of action. + * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT + * @param succp Result of action: true iff 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. @@ -4115,10 +4115,7 @@ static void handleError ( ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; CHK_DCB(backend_dcb); - if(succp == NULL || action == ERRACT_RESET) - { - return; - } + /** Don't handle same error twice on same DCB */ if (backend_dcb->dcb_errhandle_called) { diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 1122b0b5c..ab4a6a0e0 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -2791,8 +2791,8 @@ return_succp: * @param router_session The router session * @param errmsgbuf The error message to reply * @param backend_dcb The backend DCB - * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION - * @param succp Result of action. + * @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. @@ -2809,10 +2809,8 @@ handleError( SESSION* session; ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *) router_session; - if(action == ERRACT_RESET) - return; - CHK_DCB(backend_dcb); + /** Don't handle same error twice on same DCB */ if(backend_dcb->dcb_errhandle_called) { From 2e50dfd4840755381d283448959362361a9e7589 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 9 Sep 2015 08:37:40 +0100 Subject: [PATCH 036/179] Readjust indentation in handleError function of read connection router. --- server/modules/routing/readconnroute.c | 70 +++++++++++++------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 3be509444..b94d164e3 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -846,44 +846,44 @@ clientReply( * */ static void handleError( - ROUTER *instance, - void *router_session, - GWBUF *errbuf, - DCB *backend_dcb, - error_action_t action, - bool *succp) + ROUTER *instance, + void *router_session, + GWBUF *errbuf, + DCB *backend_dcb, + error_action_t action, + bool *succp) { - DCB *client_dcb; - SESSION *session = backend_dcb->session; - session_state_t sesstate; + DCB *client_dcb; + SESSION *session = backend_dcb->session; + session_state_t sesstate; ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session; - /** Don't handle same error twice on same DCB */ - if (backend_dcb->dcb_errhandle_called) - { - /** we optimistically assume that previous call succeed */ - *succp = true; - return; - } - else - { - backend_dcb->dcb_errhandle_called = true; - } - spinlock_acquire(&session->ses_lock); - sesstate = session->state; - client_dcb = session->client; + /** Don't handle same error twice on same DCB */ + if (backend_dcb->dcb_errhandle_called) + { + /** we optimistically assume that previous call succeed */ + *succp = true; + return; + } + else + { + backend_dcb->dcb_errhandle_called = true; + } + spinlock_acquire(&session->ses_lock); + sesstate = session->state; + client_dcb = session->client; - if (sesstate == SESSION_STATE_ROUTER_READY) - { - CHK_DCB(client_dcb); - spinlock_release(&session->ses_lock); - client_dcb->func.write(client_dcb, gwbuf_clone(errbuf)); - } - else - { - spinlock_release(&session->ses_lock); - } + if (sesstate == SESSION_STATE_ROUTER_READY) + { + CHK_DCB(client_dcb); + spinlock_release(&session->ses_lock); + client_dcb->func.write(client_dcb, gwbuf_clone(errbuf)); + } + else + { + spinlock_release(&session->ses_lock); + } if (backend_dcb != router_cli_ses->backend_dcb) { @@ -893,8 +893,8 @@ static void handleError( router_cli_ses->backend_dcb = NULL; dcb_close(backend_dcb); - /** false because connection is not available anymore */ - *succp = false; + /** false because connection is not available anymore */ + *succp = false; } /** to be inline'd */ From f6916a23bd2a847fca6d4536d7b489ce7fd3a266 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 9 Sep 2015 09:33:00 +0100 Subject: [PATCH 037/179] Move responsibility for closing DCB on error to router error handling. Check that routers remove or disable links to closed DCB. --- server/core/dcb.c | 1 + server/core/poll.c | 3 +- server/modules/protocol/mysql_backend.c | 8 --- server/modules/protocol/mysql_client.c | 4 +- server/modules/routing/binlog/blr.c | 3 +- server/modules/routing/maxinfo/maxinfo.c | 2 + server/modules/routing/readconnroute.c | 3 +- .../routing/readwritesplit/readwritesplit.c | 28 +++++---- .../routing/schemarouter/schemarouter.c | 60 +++++++++--------- .../routing/schemarouter/shardrouter.c | 62 ++++++++++--------- 10 files changed, 89 insertions(+), 85 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 7cc647a81..1c3e08338 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -55,6 +55,7 @@ * fixes for various error situations, * remove dcb_set_state etc, simplifications. * 10/07/2015 Martin Brampton Simplify, merge dcb_read and dcb_read_n + * 04/09/2015 Martin Brampton Changes to ensure DCB always has session pointer * * @endverbatim */ diff --git a/server/core/poll.c b/server/core/poll.c index 15e31d313..f3ee8528b 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -74,8 +74,7 @@ int max_poll_sleep; * thread utilisation and fairer scheduling of the event * processing. * 07/07/15 Martin Brampton Simplified add and remove DCB, improve error handling. - * 23/08/15 Martin Brampton Provisionally added test so only DCB with a - * session link can be added to the poll list + * 23/08/15 Martin Brampton Added test so only DCB with a session link can be added to the poll list * * @endverbatim */ diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index b737d0f58..a75330f16 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -415,7 +415,6 @@ static int gw_read_backend_event(DCB *dcb) { session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); rc = 1; goto return_rc; } @@ -488,8 +487,6 @@ static int gw_read_backend_event(DCB *dcb) { session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); } - ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); rc = 0; goto return_rc; } @@ -912,8 +909,6 @@ static int gw_error_backend_event(DCB *dcb) session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); } - ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); retblock: return 1; @@ -1144,7 +1139,6 @@ gw_backend_hangup(DCB *dcb) session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); } - ss_dassert(dcb->dcb_errhandle_called); retblock: return 1; @@ -1324,8 +1318,6 @@ static int backend_write_delayqueue(DCB *dcb) spinlock_acquire(&session->ses_lock); session->state = SESSION_STATE_STOPPING; spinlock_release(&session->ses_lock); - ss_dassert(dcb->dcb_errhandle_called); - dcb_close(dcb); } } } diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 6d0561abd..845e6eb63 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -39,6 +39,8 @@ * 10/11/2014 Massimiliano Pinto Added: client charset added to protocol struct * 29/05/2015 Markus Makela Added SSL support * 11/06/2015 Martin Brampton COM_QUIT suppressed for persistent connections + * 04/09/2015 Martin Brampton Introduce DUMMY session to fulfill guarantee DCB always has session + * 09/09/2015 Martin Brampton Modify error handler calls */ #include #include @@ -813,7 +815,6 @@ int gw_read_client_event( LOGFILE_ERROR, "Error : Routing the query failed. " "Session will be closed."))); - dcb_close(dcb); } rc = 1; goto return_rc; @@ -1192,7 +1193,6 @@ int gw_read_client_event( "Error : Routing the query failed. " "Session will be closed."))); - dcb_close(dcb); } } } diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 4d3e356f5..bbc947e48 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -37,7 +37,7 @@ * 18/02/2015 Massimiliano Pinto Addition of dcb_close in closeSession * 07/05/2015 Massimiliano Pinto Addition of MariaDB 10 compatibility support * 12/06/2015 Massimiliano Pinto Addition of MariaDB 10 events in diagnostics() - + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ @@ -1114,6 +1114,7 @@ char msg[85], *errmsg; if (errmsg) free(errmsg); *succp = true; + dcb_close(backend_dcb); LOGIF(LM, (skygw_log_write_flush( LOGFILE_MESSAGE, "%s: Master %s disconnected after %ld seconds. " diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 8ac6ce8cc..43a43e746 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -26,6 +26,7 @@ * Date Who Description * 16/02/15 Mark Riddoch Initial implementation * 27/02/15 Massimiliano Pinto Added maxinfo_add_mysql_user + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ @@ -335,6 +336,7 @@ static void handleError( } /** false because connection is not available anymore */ + dcb_close(backend_dcb); *succp = false; } diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index b94d164e3..3db858932 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -67,7 +67,8 @@ * 06/03/2014 Massimiliano Pinto Server connection counter is now updated in closeSession * 24/06/2014 Massimiliano Pinto New rules for selecting the Master server * 27/06/2014 Mark Riddoch Addition of server weighting - * 11/06/2015 Martin Brampton Remove decrement n_current (moved to dcb.c) + * 11/06/2015 Martin Brampton Remove decrement n_current (moved to dcb.c) + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 7f014bf55..cfecd53dd 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -67,6 +67,8 @@ extern __thread log_info_t tls_log_info; * 18/07/2013 Massimiliano Pinto routeQuery now handles COM_QUIT * as QUERY_TYPE_SESSION_WRITE * 17/07/2014 Massimiliano Pinto Server connection counter is updated in closeSession + * + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ @@ -4825,17 +4827,14 @@ static void handleError ( CHK_DCB(backend_dcb); - /** Reset error handle flag from a given DCB */ - if (action == ERRACT_RESET) - { - backend_dcb->dcb_errhandle_called = false; - return; - } - /** 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 */ + /* + * The return of true is potentially misleading, but appears to + * be safe with the code as it stands on 9 Sept 2015 - MNB + */ *succp = true; return; } @@ -4848,12 +4847,13 @@ static void handleError ( if (session == NULL || rses == NULL) { *succp = false; - return; } - CHK_SESSION(session); - CHK_CLIENT_RSES(rses); + else + { + CHK_SESSION(session); + CHK_CLIENT_RSES(rses); - switch (action) { + switch (action) { case ERRACT_NEW_CONNECTION: { SERVER* srv; @@ -4861,7 +4861,7 @@ static void handleError ( if (!rses_begin_locked_router_action(rses)) { *succp = false; - return; + break; } srv = rses->rses_master_ref->bref_backend->backend_server; /** @@ -4914,7 +4914,9 @@ static void handleError ( default: *succp = false; break; + } } + dcb_close(backend_dcb); } diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index a058db7e7..67875056a 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -58,6 +58,7 @@ extern __thread log_info_t tls_log_info; * * Date Who Description * 01/12/2014 Vilho Raatikka/Markus Mäkelä Initial implementation + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ @@ -4103,37 +4104,38 @@ return_succp: * tell whether router has enough master/slave connections to continue work. */ static void handleError ( - ROUTER* instance, - void* router_session, - GWBUF* errmsgbuf, - DCB* backend_dcb, - error_action_t action, - bool* succp) + ROUTER* instance, + void* router_session, + GWBUF* errmsgbuf, + DCB* backend_dcb, + error_action_t action, + bool* succp) { - SESSION* session; - ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance; - ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; + SESSION* session; + ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance; + ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; - CHK_DCB(backend_dcb); + 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 */ - *succp = true; - return; - } - else - { - backend_dcb->dcb_errhandle_called = true; - } - session = backend_dcb->session; + /** Don't handle same error twice on same DCB */ + if (backend_dcb->dcb_errhandle_called) + { + /** we optimistically assume that previous call succeed */ + *succp = true; + return; + } + else + { + backend_dcb->dcb_errhandle_called = true; + } + session = backend_dcb->session; - if (session == NULL || rses == NULL) - { - *succp = false; - return; - } + if (session == NULL || rses == NULL) + { + *succp = false; + } + else + { CHK_SESSION(session); CHK_CLIENT_RSES(rses); @@ -4143,7 +4145,7 @@ static void handleError ( if (!rses_begin_locked_router_action(rses)) { *succp = false; - return; + break; } /** * This is called in hope of getting replacement for @@ -4171,6 +4173,8 @@ static void handleError ( *succp = false; break; } + } + dcb_close(backend_dcb); } diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index ab4a6a0e0..e01d37eae 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -63,6 +63,7 @@ extern __thread log_info_t tls_log_info; * * Date Who Description * 20/01/2015 Markus Mäkelä/Vilho Raatikka Initial implementation + * 09/09/2015 Martin Brampton Modify error handler * * @endverbatim */ @@ -2826,38 +2827,39 @@ handleError( if(session == NULL || rses == NULL) { - if(succp) - *succp = false; - return; - } - CHK_SESSION(session); - CHK_CLIENT_RSES(rses); - - switch(action) - { - case ERRACT_NEW_CONNECTION: - { - if(!rses_begin_locked_router_action(rses)) - { - *succp = false; - return; - } - - rses_end_locked_router_action(rses); - break; - } - - case ERRACT_REPLY_CLIENT: - { - - *succp = false; /*< no new backend servers were made available */ - break; - } - - default: *succp = false; - break; } + else + { + CHK_SESSION(session); + CHK_CLIENT_RSES(rses); + + switch(action) + { + case ERRACT_NEW_CONNECTION: + { + if(!rses_begin_locked_router_action(rses)) + { + *succp = false; + break; + } + + rses_end_locked_router_action(rses); + break; + } + + case ERRACT_REPLY_CLIENT: + { + *succp = false; /*< no new backend servers were made available */ + break; + } + + default: + *succp = false; + break; + } + } + dcb_close(backend_dcb); } From 296e306daa2b0fe8ee8b8c7b883c22e611594c64 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 9 Sep 2015 16:58:03 +0100 Subject: [PATCH 038/179] Set session pointer to client dcb to null when dcb is closed. --- server/modules/protocol/mysql_backend.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index a75330f16..4d36351e1 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -1190,10 +1190,13 @@ gw_backend_close(DCB *dcb) { if (session->client->state == DCB_STATE_POLLING) { + DCB *temp; spinlock_release(&session->ses_lock); /** Close client DCB */ - dcb_close(session->client); + temp = session->client; + session->client = NULL; + dcb_close(temp); } else { From c1194a5ee8871346fac5f64c010066596d034403 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 10 Sep 2015 18:04:55 +0300 Subject: [PATCH 039/179] Fixed test build failures. --- log_manager/test/CMakeLists.txt | 6 +++--- query_classifier/test/CMakeLists.txt | 2 +- query_classifier/test/canonical_tests/CMakeLists.txt | 2 +- server/core/CMakeLists.txt | 2 +- server/core/test/CMakeLists.txt | 10 +++++----- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/log_manager/test/CMakeLists.txt b/log_manager/test/CMakeLists.txt index bbcfd5791..6018e746d 100644 --- a/log_manager/test/CMakeLists.txt +++ b/log_manager/test/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(testlog testlog.c) -add_executable(testorder testorder.c) -target_link_libraries(testlog pthread log_manager utils) -target_link_libraries(testorder pthread log_manager utils) +add_executable(testorder testorder.c ../../server/core/random_jkiss.c) +target_link_libraries(testlog pthread log_manager utils fullcore) +target_link_libraries(testorder pthread log_manager utils fullcore) add_test(NAME Internal-TestLogOrder COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/logorder.sh 200 0 1000 ${CMAKE_CURRENT_BINARY_DIR}/logorder.log) diff --git a/query_classifier/test/CMakeLists.txt b/query_classifier/test/CMakeLists.txt index 44b66e461..66c56eca7 100644 --- a/query_classifier/test/CMakeLists.txt +++ b/query_classifier/test/CMakeLists.txt @@ -10,5 +10,5 @@ endif() add_subdirectory(canonical_tests) add_executable(classify classify.c) -target_link_libraries(classify query_classifier fullcore) +target_link_libraries(classify query_classifier ${CURL_LIBRARIES} utils log_manager pthread ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ssl aio rt crypt dl crypto inih z m stdc++ fullcore) add_test(Internal-TestQueryClassifier classify ${CMAKE_CURRENT_SOURCE_DIR}/input.sql ${CMAKE_CURRENT_SOURCE_DIR}/expected.sql) diff --git a/query_classifier/test/canonical_tests/CMakeLists.txt b/query_classifier/test/canonical_tests/CMakeLists.txt index 1dafc428e..925a3dd4f 100644 --- a/query_classifier/test/canonical_tests/CMakeLists.txt +++ b/query_classifier/test/canonical_tests/CMakeLists.txt @@ -7,7 +7,7 @@ else() file(COPY ${ERRMSG} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif() endif() -add_executable(canonizer canonizer.c) +add_executable(canonizer canonizer.c ${CMAKE_SOURCE_DIR}/server/core/random_jkiss.c) target_link_libraries(canonizer pthread query_classifier z dl ssl aio crypt crypto rt m ${EMBEDDED_LIB} fullcore stdc++) add_test(NAME Internal-TestCanonicalQuery COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/canontest.sh ${CMAKE_CURRENT_BINARY_DIR}/test.log diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 5ad84ce59..0f0b00884 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,5 +1,5 @@ if(BUILD_TESTS OR BUILD_TOOLS) - add_library(fullcore STATIC adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c random_jkiss.c) + add_library(fullcore STATIC random_jkiss.c adminusers.c atomic.c config.c buffer.c dbusers.c dcb.c filter.c gwbitmask.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c memlog.c modutil.c monitor.c poll.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c gwdirs.c externcmd.c) if(WITH_JEMALLOC) target_link_libraries(fullcore ${JEMALLOC_LIBRARIES}) elseif(WITH_TCMALLOC) diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 2d32d55b1..0c9f4201f 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -1,10 +1,10 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${ERRMSG} ${CMAKE_CURRENT_BINARY_DIR}) add_executable(test_mysql_users test_mysql_users.c) -add_executable(test_hash testhash.c) -add_executable(test_hint testhint.c) -add_executable(test_spinlock testspinlock.c) +add_executable(test_hash testhash.c ../random_jkiss.c) +add_executable(test_hint testhint.c ../random_jkiss.c) +add_executable(test_spinlock testspinlock.c ../random_jkiss.c) add_executable(test_filter testfilter.c) -add_executable(test_buffer testbuffer.c) +add_executable(test_buffer testbuffer.c ../random_jkiss.c) add_executable(test_dcb testdcb.c) add_executable(test_modutil testmodutil.c) add_executable(test_poll testpoll.c) @@ -12,7 +12,7 @@ add_executable(test_service testservice.c) add_executable(test_server testserver.c) add_executable(test_users testusers.c) add_executable(test_adminusers testadminusers.c) -add_executable(testmemlog testmemlog.c) +add_executable(testmemlog testmemlog.c ../random_jkiss.c) add_executable(testfeedback testfeedback.c) target_link_libraries(test_mysql_users MySQLClient fullcore) target_link_libraries(test_hash fullcore log_manager) From 0cf4b2cf68766637a85d96139cc0f7a144e7bb2f Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Tue, 15 Sep 2015 08:37:41 +0100 Subject: [PATCH 040/179] Fix to overcome failure on certain packets. --- server/modules/routing/binlog/blr_master.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 0a80a4d54..3001b2cef 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -1480,6 +1480,14 @@ char *rval; // Finally we have reached the row len = EXTRACT24(ptr); ptr += 4; + + /** The first EOF packet signals the start of the resultset rows and the second + EOF packet signals the end of the result set. If the resultset + contains a second EOF packet right after the first one, the result set is empty and + contains no rows. */ + if(len == 5 && *ptr == 0xfe) + return NULL; + while (--col > 0) { collen = *ptr++; From fdbe070e802077815e0f8c0d5b5583522176314a Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 15 Sep 2015 15:22:44 +0100 Subject: [PATCH 041/179] Change abort to error message when read connection router finds mismatch between router client session DCB and given backend DCB; improve order of actions when closing DCB in read-write router. --- server/modules/routing/readconnroute.c | 21 ++++++++++++------- .../routing/readwritesplit/readwritesplit.c | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 3db858932..e32bdd677 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -885,14 +885,21 @@ static void handleError( { spinlock_release(&session->ses_lock); } - - if (backend_dcb != router_cli_ses->backend_dcb) - { - /* Linkages have gone badly wrong - this may not be best solution */ - raise(SIGABRT); + + if (router_cli_ses->backend_dcb) { + if (backend_dcb != router_cli_ses->backend_dcb) + { + /* Linkages have gone badly wrong */ + LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, + "Read Connection Router error in handleError: router client " + "session DCB %p is not null, but does not match backend DCB %p " + "either. \n", + router_cli_ses->backend_dcb, + backend_dcb))); + } + router_cli_ses->backend_dcb = NULL; + dcb_close(backend_dcb); } - router_cli_ses->backend_dcb = NULL; - dcb_close(backend_dcb); /** false because connection is not available anymore */ *succp = false; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 0ad00886c..6b9dce74c 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3655,10 +3655,10 @@ static bool select_connect_backend_servers( ss_dassert(backend_ref[i].bref_backend->backend_conn_count > 0); /** disconnect opened connections */ - dcb_close(backend_ref[i].bref_dcb); bref_clear_state(&backend_ref[i], BREF_IN_USE); /** Decrease backend's connection counter. */ atomic_add(&backend_ref[i].bref_backend->backend_conn_count, -1); + dcb_close(backend_ref[i].bref_dcb); } } } From 30239f395a5650efe9fc65812ed8673e16af2206 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Tue, 15 Sep 2015 20:07:56 +0100 Subject: [PATCH 042/179] Fix bref when backend server fails, error message if fails. --- .../routing/readwritesplit/readwritesplit.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 6b9dce74c..ee1d6fb50 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4871,6 +4871,24 @@ static void handleError ( if (rses->rses_master_ref->bref_dcb == backend_dcb && !SERVER_IS_MASTER(srv)) { + backend_ref_t* bref; + bref = get_bref_from_dcb(rses, backend_dcb); + if (bref != NULL) + { + CHK_BACKEND_REF(bref); + bref_clear_state(bref, BREF_IN_USE); + bref_set_state(bref, BREF_CLOSED); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : server %s:%d lost the " + "master status but could not locate the " + "corresponding backend ref.", + srv->name, + srv->port))); + } if (!srv->master_err_is_logged) { LOGIF(LE, (skygw_log_write_flush( From 0cba9b797f0a7532b0c4622e4c1804c2c68d1ac2 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 08:15:32 +0100 Subject: [PATCH 043/179] Changes to deal with failed session creation by keeping the new session in existence until all related DCBs have closed; minor changes in response to reviews. --- server/core/random_jkiss.c | 5 +- server/core/session.c | 102 ++++++++++++++++++++------------ server/modules/protocol/httpd.c | 4 -- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/server/core/random_jkiss.c b/server/core/random_jkiss.c index 6eea33739..97a09fa34 100644 --- a/server/core/random_jkiss.c +++ b/server/core/random_jkiss.c @@ -100,10 +100,9 @@ random_jkiss_devrand(void) int fn; unsigned int r; if ((fn = open("/dev/urandom", O_RDONLY)) == -1) return 0; - if (read(fn, &r, 4) != 4) + if (read(fn, &r, sizeof(r)) != sizeof(r)) { - close(fn); - return 0; + r = 0; } close(fn); return r; diff --git a/server/core/session.c b/server/core/session.c index c46ffcf9b..dcda5af51 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -27,6 +27,7 @@ * 02/09/13 Massimiliano Pinto Added session refcounter * 29/05/14 Mark Riddoch Addition of filter mechanism * 23/08/15 Martin Brampton Tidying; slight improvement in safety + * 17/09/15 Martin Brampton Keep failed session in existence - leave DCBs to close * * @endverbatim */ @@ -82,14 +83,30 @@ session_alloc(SERVICE *service, DCB *client_dcb) if (session == NULL) { - char errbuf[STRERROR_BUFLEN]; + char errbuf[STRERROR_BUFLEN]; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Failed to allocate memory for " "session object due error %d, %s.", errno, strerror_r(errno, errbuf, sizeof(errbuf))))); - session_simple_free(session, client_dcb); + /* Does this possibly need a lock? */ + /* + * This is really not the right way to do this. The data in a DCB is + * router specific and should be freed by a function in the relevant + * router. This would be better achieved by placing a function reference + * in the DCB and having dcb_final_free call it to dispose of the data + * at the final destruction of the DCB. However, this piece of code is + * only run following a calloc failure, so the system is probably on + * the point of crashing anyway. + * + */ + if (dcb->data && !DCB_IS_CLONE(dcb)) + { + void * clientdata = dcb->data; + dcb->data = NULL; + free(clientdata); + } return NULL; } #if defined(SS_DEBUG) @@ -135,7 +152,7 @@ session_alloc(SERVICE *service, DCB *client_dcb) session->router_session = service->router->newSession(service->router_instance, session); if (session->router_session == NULL) { - session_simple_free(session, client_dcb); + session->state = SESSION_STATE_TO_BE_FREED; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, @@ -145,7 +162,6 @@ session_alloc(SERVICE *service, DCB *client_dcb) __func__, service->name))); - return NULL; } /* * Pending filter chain being setup set the head of the chain to @@ -165,53 +181,65 @@ session_alloc(SERVICE *service, DCB *client_dcb) session->tail.session = session; session->tail.clientReply = session_reply; - if (service->n_filters > 0) + if (SESSION_STATE_TO_BE_FREED != session->state + && service->n_filters > 0 + && !session_setup_filters(session)) { - if (!session_setup_filters(session)) - { - session_simple_free(session, client_dcb); + session->state = SESSION_STATE_TO_BE_FREED; LOGIF(LE, (skygw_log_write( LOGFILE_ERROR, "Error : Setting up filters failed. " "Terminating session %s.", service->name))); - return NULL; - } } } - session->state = SESSION_STATE_ROUTER_READY; + if (SESSION_STATE_TO_BE_FREED != session->state) + { + session->state = SESSION_STATE_ROUTER_READY; + + if (session->client->user == NULL) + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started session [%lu] for %s service ", + session->ses_id, + service->name))); + } + else + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Started %s client session [%lu] for '%s' from %s", + service->name, + session->ses_id, + session->client->user, + session->client->remote))); + } + } + else + { + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Start %s client session [%lu] for '%s' from %s failed, will be " + "closed as soon as all related DCBs have been closed.", + service->name, + session->ses_id, + session->client->user, + session->client->remote))); + } spinlock_acquire(&session_spin); /** Assign a session id and increase, insert session into list */ session->ses_id = ++session_id; session->next = allSessions; allSessions = session; spinlock_release(&session_spin); - - if (session->client->user == NULL) - { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started session [%lu] for %s service ", - session->ses_id, - service->name))); - } - else - { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started %s client session [%lu] for '%s' from %s", - service->name, - session->ses_id, - session->client->user, - session->client->remote))); - } atomic_add(&service->stats.n_sessions, 1); atomic_add(&service->stats.n_current, 1); CHK_SESSION(session); client_dcb->session = session; - return session; + return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session; } /** @@ -240,13 +268,6 @@ session_set_dummy(DCB *client_dcb) memset(&session->stats, 0, sizeof(SESSION_STATS)); session->stats.connect = 0; session->state = SESSION_STATE_DUMMY; - /*< - * Associate the session to the client DCB and set the reference count on - * the session to indicate that there is a single reference to the - * session. There is no need to protect this or use atomic add as the - * session has not been made available to the other threads at this - * point. - */ session->data = NULL; session->refcount = 1; session->ses_id = 0; @@ -352,6 +373,9 @@ int session_unlink_dcb( /** * Deallocate the specified session, minimal actions during session_alloc + * Since changes to keep new session in existence until all related DCBs + * have been destroyed, this function is redundant. Just left until we are + * sure of the direction taken. * * @param session The session to deallocate */ @@ -402,7 +426,7 @@ session_free(SESSION *session) * Remove one reference. If there are no references left, * free session. */ - if (atomic_add(&session->refcount, -1) - 1) + if (atomic_add(&session->refcount, -1) > 1) { /* Must be one or more references left */ return false; diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index 8a9cf0212..b0c40bc21 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -350,10 +350,6 @@ int n_connect = 0; client->remote = strdup(inet_ntoa(addr.sin_addr)); memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL)); - /* we don't need the session */ - /* But not clear that we have one! */ - /* client->session = NULL; */ - /* create the session data for HTTPD */ client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session)); client->data = client_data; From 91dd3bb9bd0eb994ad50345b3ae44534b323ebb7 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 08:18:47 +0100 Subject: [PATCH 044/179] Fix mistake. --- server/core/session.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/core/session.c b/server/core/session.c index dcda5af51..e9d45b8e7 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -101,10 +101,10 @@ session_alloc(SERVICE *service, DCB *client_dcb) * the point of crashing anyway. * */ - if (dcb->data && !DCB_IS_CLONE(dcb)) + if (client_dcb->data && !DCB_IS_CLONE(client_dcb)) { - void * clientdata = dcb->data; - dcb->data = NULL; + void * clientdata = client_dcb->data; + client_dcb->data = NULL; free(clientdata); } return NULL; From 583c9b62feca379224f21adf36521ef155de6487 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 11:58:19 +0100 Subject: [PATCH 045/179] Close DCB in handleError only if it can be found in a backend reference. --- server/modules/routing/readwritesplit/readwritesplit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index ee1d6fb50..beb16cb59 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4878,6 +4878,7 @@ static void handleError ( CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); + dcb_close(backend_dcb); } else { @@ -4934,7 +4935,6 @@ static void handleError ( break; } } - dcb_close(backend_dcb); } @@ -4961,6 +4961,7 @@ static void handle_error_reply_client( CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); + dcb_close(backend_dcb); } if (sesstate == SESSION_STATE_ROUTER_READY) @@ -5048,6 +5049,7 @@ static bool handle_error_new_connection( DCB_REASON_NOT_RESPONDING, &router_handle_state_switch, (void *)bref); + dcb_close(backend_dcb); router_nservers = router_get_servercount(inst); max_nslaves = rses_get_max_slavecount(myrses, router_nservers); From 357c4bcae548875f422abe37f4a22b6748b811f0 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 12:53:59 +0100 Subject: [PATCH 046/179] Add to or take from persistent pool only if server is running; add conditions to DCB close in read-write handleError to check backend reference was in use. --- server/core/dcb.c | 3 +++ .../routing/readwritesplit/readwritesplit.c | 20 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 508e869f2..1654aec3c 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1881,6 +1881,7 @@ dcb_maybe_add_persistent(DCB *dcb) && strlen(dcb->user) && dcb->server && dcb->server->persistpoolmax + && (dcb->server->status & SERVER_RUNNING) && !dcb->dcb_errhandle_called && !(dcb->flags & DCBF_HUNG) && (poolcount = dcb_persistent_clean_count(dcb, false)) < dcb->server->persistpoolmax) @@ -2815,6 +2816,8 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) if (cleanall || persistentdcb-> dcb_errhandle_called || count >= server->persistpoolmax + || persistentdcb->server == NULL + || !(persistentdcb->server->status & SERVER_RUNNING) || (time(NULL) - persistentdcb->persistentstart) > server->persistmaxtime) { /* Remove from persistent pool */ diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index beb16cb59..c9103fae9 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4875,10 +4875,12 @@ static void handleError ( bref = get_bref_from_dcb(rses, backend_dcb); if (bref != NULL) { + bool bref_was_in_use = BREF_IS_IN_USE(bref); CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); - dcb_close(backend_dcb); + if (bref_was_in_use) + dcb_close(backend_dcb); } else { @@ -4958,10 +4960,14 @@ static void handle_error_reply_client( */ if ((bref = get_bref_from_dcb(rses, backend_dcb)) != NULL) { + bool bref_was_in_use = BREF_IS_IN_USE(bref); CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); - dcb_close(backend_dcb); + if (bref_was_in_use) + { + dcb_close(backend_dcb); + } } if (sesstate == SESSION_STATE_ROUTER_READY) @@ -4991,13 +4997,14 @@ static bool handle_error_new_connection( DCB* backend_dcb, GWBUF* errmsg) { - ROUTER_CLIENT_SES* myrses; + ROUTER_CLIENT_SES* myrses; SESSION* ses; int router_nservers; int max_nslaves; int max_slave_rlag; backend_ref_t* bref; bool succp; + bool bref_was_in_use; myrses = *rses; ss_dassert(SPINLOCK_IS_LOCKED(&myrses->rses_lock)); @@ -5014,6 +5021,7 @@ static bool handle_error_new_connection( goto return_succp; } CHK_BACKEND_REF(bref); + bref_was_in_use = BREF_IS_IN_USE(bref); /** * If query was sent through the bref and it is waiting for reply from @@ -5049,8 +5057,10 @@ static bool handle_error_new_connection( DCB_REASON_NOT_RESPONDING, &router_handle_state_switch, (void *)bref); - dcb_close(backend_dcb); - + if (bref_was_in_use) + { + dcb_close(backend_dcb); + } router_nservers = router_get_servercount(inst); max_nslaves = rses_get_max_slavecount(myrses, router_nservers); max_slave_rlag = rses_get_max_replication_lag(myrses); From 1ad8e27c919517e6421fb90e0f607fa89e698525 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 13:27:25 +0100 Subject: [PATCH 047/179] Try a different arrangement of DCB closures in handleError of read-write split. --- .../modules/routing/readwritesplit/readwritesplit.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index c9103fae9..40b9f1ed1 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4890,7 +4890,8 @@ static void handleError ( "master status but could not locate the " "corresponding backend ref.", srv->name, - srv->port))); + srv->port))); + dcb_close(backend_dcb); } if (!srv->master_err_is_logged) { @@ -4969,6 +4970,10 @@ static void handle_error_reply_client( dcb_close(backend_dcb); } } + else + { + dcb_close(backend_dcb); + } if (sesstate == SESSION_STATE_ROUTER_READY) { @@ -5004,9 +5009,9 @@ static bool handle_error_new_connection( int max_slave_rlag; backend_ref_t* bref; bool succp; - bool bref_was_in_use; + bool bref_was_in_use; - myrses = *rses; + myrses = *rses; ss_dassert(SPINLOCK_IS_LOCKED(&myrses->rses_lock)); ses = backend_dcb->session; @@ -5018,6 +5023,7 @@ static bool handle_error_new_connection( if ((bref = get_bref_from_dcb(myrses, backend_dcb)) == NULL) { succp = true; + dcb_close(backend_dcb); goto return_succp; } CHK_BACKEND_REF(bref); From dc3b0b067b9d97655df0f52cf2ef2b6055e60c2d Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 13:35:18 +0100 Subject: [PATCH 048/179] Revert the dcb_close changes in handleError. --- .../routing/readwritesplit/readwritesplit.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 40b9f1ed1..46fce6cee 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4879,8 +4879,6 @@ static void handleError ( CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); - if (bref_was_in_use) - dcb_close(backend_dcb); } else { @@ -4938,6 +4936,7 @@ static void handleError ( break; } } + dcb_close(backend_dcb); } @@ -4965,15 +4964,7 @@ static void handle_error_reply_client( CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); - if (bref_was_in_use) - { - dcb_close(backend_dcb); - } } - else - { - dcb_close(backend_dcb); - } if (sesstate == SESSION_STATE_ROUTER_READY) { @@ -5023,7 +5014,6 @@ static bool handle_error_new_connection( if ((bref = get_bref_from_dcb(myrses, backend_dcb)) == NULL) { succp = true; - dcb_close(backend_dcb); goto return_succp; } CHK_BACKEND_REF(bref); @@ -5063,10 +5053,6 @@ static bool handle_error_new_connection( DCB_REASON_NOT_RESPONDING, &router_handle_state_switch, (void *)bref); - if (bref_was_in_use) - { - dcb_close(backend_dcb); - } router_nservers = router_get_servercount(inst); max_nslaves = rses_get_max_slavecount(myrses, router_nservers); max_slave_rlag = rses_get_max_replication_lag(myrses); From 31c6666278287c69192ccbcfa66c45e52f70663f Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 17 Sep 2015 14:38:56 +0100 Subject: [PATCH 049/179] Ensure DCB for closing session does not become persistent; remove bref_was_not_in_use. --- server/core/dcb.c | 14 ++++++++++++++ .../routing/readwritesplit/readwritesplit.c | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 1654aec3c..ddbdf19ca 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1838,6 +1838,15 @@ dcb_close(DCB *dcb) dcb_final_free(dcb); return; } + + /* + * If DCB is in persistent pool, mark it as an error and exit + */ + if (dcb->persistentstart) + { + dcb->dcb_errhandle_called = true; + return; + } spinlock_acquire(&zombiespin); if (!dcb->dcb_is_zombie) @@ -1879,6 +1888,8 @@ dcb_maybe_add_persistent(DCB *dcb) int poolcount = -1; if (dcb->user != NULL && strlen(dcb->user) + && dcb->session->state != SESSION_STATE_STOPPING + && dcb->session->state != SESSION_STATE_TO_BE_FREED && dcb->server && dcb->server->persistpoolmax && (dcb->server->status & SERVER_RUNNING) @@ -2817,6 +2828,8 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) || persistentdcb-> dcb_errhandle_called || count >= server->persistpoolmax || persistentdcb->server == NULL + || persistentdcb->session->state == SESSION_STATE_STOPPING + || persistentdcb->session->state == SESSION_STATE_TO_BE_FREED || !(persistentdcb->server->status & SERVER_RUNNING) || (time(NULL) - persistentdcb->persistentstart) > server->persistmaxtime) { @@ -2846,6 +2859,7 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) while (disposals) { nextdcb = disposals->nextpersistent; + disposals->persistentstart = 0; dcb_close_finish(disposals); dcb_close(disposals); disposals = nextdcb; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 46fce6cee..d8d8033f0 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4875,7 +4875,6 @@ static void handleError ( bref = get_bref_from_dcb(rses, backend_dcb); if (bref != NULL) { - bool bref_was_in_use = BREF_IS_IN_USE(bref); CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); @@ -4960,7 +4959,6 @@ static void handle_error_reply_client( */ if ((bref = get_bref_from_dcb(rses, backend_dcb)) != NULL) { - bool bref_was_in_use = BREF_IS_IN_USE(bref); CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); @@ -5000,7 +4998,6 @@ static bool handle_error_new_connection( int max_slave_rlag; backend_ref_t* bref; bool succp; - bool bref_was_in_use; myrses = *rses; ss_dassert(SPINLOCK_IS_LOCKED(&myrses->rses_lock)); @@ -5017,7 +5014,6 @@ static bool handle_error_new_connection( goto return_succp; } CHK_BACKEND_REF(bref); - bref_was_in_use = BREF_IS_IN_USE(bref); /** * If query was sent through the bref and it is waiting for reply from From c69658889cc7cd67f87c7d842bf210b7930fd7c8 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 18 Sep 2015 08:59:06 +0100 Subject: [PATCH 050/179] Handle client input case where no router session exists by sending error message to client. --- server/modules/protocol/mysql_client.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 1f983650c..edda2b888 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -758,9 +758,9 @@ int gw_read_client_event( router = session->service->router; router_instance = session->service->router_instance; rsession = session->router_session; - ss_dassert(rsession != NULL); - if (router_instance != NULL && rsession != NULL) { + if (router_instance != NULL && rsession != NULL) + { /** Ask what type of input the router expects */ cap = router->getCapabilities(router_instance, rsession); @@ -820,7 +820,17 @@ int gw_read_client_event( goto return_rc; } } - } + else + { + /** Send ERR 1045 to client */ + mysql_send_auth_error( + dcb, + 2, + 0, + "failed to create new session"); + return 0; + } + } if (stmt_input) { From f3560512ffec1b796f329a1d2450c66d23506283 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 18 Sep 2015 09:04:32 +0100 Subject: [PATCH 051/179] Suppress call to router error handling where there is no router session. --- server/modules/protocol/mysql_backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 85c90319d..29d7dc2b9 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -395,7 +395,8 @@ static int gw_read_backend_event(DCB *dcb) { "Authentication with backend failed. " "Session will be closed."); - router->handleError(router_instance, + if (rsession) + router->handleError(router_instance, rsession, errbuf, dcb, From e507933c4841b1ae3b3a4bcd42d0294ce4656ecf Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 18 Sep 2015 09:19:32 +0100 Subject: [PATCH 052/179] Need to mark the DCB dcb_errhandle_called indicator if the router error handler is not called. --- server/modules/protocol/mysql_backend.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 29d7dc2b9..94efb669c 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -396,12 +396,18 @@ static int gw_read_backend_event(DCB *dcb) { "Session will be closed."); if (rsession) + { router->handleError(router_instance, rsession, errbuf, dcb, ERRACT_REPLY_CLIENT, &succp); + } + else + { + dcb->dcb_errhandle_called = true; + } gwbuf_free(errbuf); LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, From b8af047a2528a294bb619ac5387124cfabe7becb Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 18 Sep 2015 11:03:23 +0100 Subject: [PATCH 053/179] Remove excessively tight conditions for selecting persistent connections, add more information to debug output when connection is rejected. --- server/core/dcb.c | 10 ++++------ server/core/server.c | 5 ++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index ddbdf19ca..4bbcc80c9 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1888,8 +1888,6 @@ dcb_maybe_add_persistent(DCB *dcb) int poolcount = -1; if (dcb->user != NULL && strlen(dcb->user) - && dcb->session->state != SESSION_STATE_STOPPING - && dcb->session->state != SESSION_STATE_TO_BE_FREED && dcb->server && dcb->server->persistpoolmax && (dcb->server->status & SERVER_RUNNING) @@ -1916,14 +1914,16 @@ dcb_maybe_add_persistent(DCB *dcb) { LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, - "%lu [dcb_maybe_add_persistent] Not adding DCB %p to persistent pool, user %s, " - "max for pool %d, error handle called %s, hung flag %s, pool count %d.\n", + "%lu [dcb_maybe_add_persistent] Not adding DCB %p to persistent pool, " + "user %s, max for pool %d, error handle called %s, hung flag %s, " + "server status %d, pool count %d.\n", pthread_self(), dcb, dcb->user ? dcb->user : "", (dcb->server && dcb->server->persistpoolmax) ? dcb->server->persistpoolmax : 0, dcb->dcb_errhandle_called ? "true" : "false", (dcb->flags & DCBF_HUNG) ? "true" : "false", + dcb->server ? dcb->server->status : 0, poolcount))); } return false; @@ -2828,8 +2828,6 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) || persistentdcb-> dcb_errhandle_called || count >= server->persistpoolmax || persistentdcb->server == NULL - || persistentdcb->session->state == SESSION_STATE_STOPPING - || persistentdcb->session->state == SESSION_STATE_TO_BE_FREED || !(persistentdcb->server->status & SERVER_RUNNING) || (time(NULL) - persistentdcb->persistentstart) > server->persistmaxtime) { diff --git a/server/core/server.c b/server/core/server.c index 2625cf1ce..b494ef257 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -153,7 +153,10 @@ server_get_persistent(SERVER *server, char *user, const char *protocol) { DCB *dcb, *previous = NULL; - if (server->persistent && dcb_persistent_clean_count(server->persistent, false) && server->persistent) + if (server->persistent + && dcb_persistent_clean_count(server->persistent, false) + && server->persistent + && (server->status & SERVER_RUNNING)) { spinlock_acquire(&server->persistlock); dcb = server->persistent; From 88716c35fba54ca95120ee2f579996cdcf967c67 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 21 Sep 2015 09:23:22 +0100 Subject: [PATCH 054/179] Various changes to block loopholes in different cases and tidy up. --- server/core/dcb.c | 147 ++++++++++++------ server/core/poll.c | 7 +- server/modules/protocol/mysql_backend.c | 16 +- server/modules/routing/readconnroute.c | 6 +- .../routing/readwritesplit/readwritesplit.c | 9 +- 5 files changed, 122 insertions(+), 63 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 4bbcc80c9..bd7d5677e 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -289,10 +289,10 @@ dcb_final_free(DCB *dcb) { DCB_CALLBACK *cb; - CHK_DCB(dcb); - ss_info_dassert(dcb->state == DCB_STATE_DISCONNECTED || - dcb->state == DCB_STATE_ALLOC, - "dcb not in DCB_STATE_DISCONNECTED not in DCB_STATE_ALLOC state."); + CHK_DCB(dcb); + ss_info_dassert(dcb->state == DCB_STATE_DISCONNECTED || + dcb->state == DCB_STATE_ALLOC, + "dcb not in DCB_STATE_DISCONNECTED not in DCB_STATE_ALLOC state."); if (DCB_POLL_BUSY(dcb)) { @@ -326,53 +326,58 @@ dcb_final_free(DCB *dcb) if (ptr) ptr->next = dcb->next; } - spinlock_release(&dcbspin); + spinlock_release(&dcbspin); - if (dcb->session) { - /*< - * Terminate client session. - */ - { - SESSION *local_session = dcb->session; - dcb->session = NULL; - CHK_SESSION(local_session); - /** - * Set session's client pointer NULL so that other threads - * won't try to call dcb_close for client DCB - * after this call. - */ - if (local_session->client == dcb) - { - spinlock_acquire(&local_session->ses_lock); - local_session->client = NULL; - spinlock_release(&local_session->ses_lock); - } - if (SESSION_STATE_DUMMY != local_session->state) - { - session_free(local_session); - } - } + if (dcb->session) { + /*< + * Terminate client session. + */ + SESSION *local_session = dcb->session; + dcb->session = NULL; + CHK_SESSION(local_session); + /** + * Set session's client pointer NULL so that other threads + * won't try to call dcb_close for client DCB + * after this call. + */ + if (local_session->client == dcb) + { + spinlock_acquire(&local_session->ses_lock); + local_session->client = NULL; + spinlock_release(&local_session->ses_lock); + } + if (SESSION_STATE_DUMMY != local_session->state) + { + session_free(local_session); + } } if (dcb->protocol && (!DCB_IS_CLONE(dcb))) free(dcb->protocol); - if (dcb->protoname) - free(dcb->protoname); + if (dcb->protoname) + free(dcb->protoname); if (dcb->remote) free(dcb->remote); if (dcb->user) free(dcb->user); - /* Clear write and read buffers */ - if (dcb->delayq) { - GWBUF *queue = dcb->delayq; - while ((queue = gwbuf_consume(queue, GWBUF_LENGTH(queue))) != NULL); - } - if (dcb->dcb_readqueue) - { - GWBUF* queue = dcb->dcb_readqueue; - while ((queue = gwbuf_consume(queue, GWBUF_LENGTH(queue))) != NULL); - } + /* Clear write and read buffers */ + if (dcb->delayq) { + GWBUF *queue = dcb->delayq; + while ((queue = gwbuf_consume(queue, GWBUF_LENGTH(queue))) != NULL); + dcb->delayq = NULL; + } + if (dcb->writeq) { + GWBUF *queue = dcb->writeq; + while ((queue = gwbuf_consume(queue, GWBUF_LENGTH(queue))) != NULL); + dcb->writeq = NULL; + } + if (dcb->dcb_readqueue) + { + GWBUF* queue = dcb->dcb_readqueue; + while ((queue = gwbuf_consume(queue, GWBUF_LENGTH(queue))) != NULL); + dcb->dcb_readqueue = NULL; + } spinlock_acquire(&dcb->cb_lock); while ((cb = dcb->callbacks) != NULL) @@ -549,10 +554,36 @@ dcb_process_victim_queue(DCB *listofdcb) dcb = dcb->memdata.next; continue; } + else + { + DCB *nextdcb; + poll_remove_dcb(dcb); + spinlock_acquire(&zombiespin); + bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); + nextdcb = dcb->memdata.next; + dcb->memdata.next = zombies; + zombies = dcb; + spinlock_release(&zombiespin); + if (dcb->server) + { + atomic_add(&dcb->server->stats.n_current, -1); + } + dcb = nextdcb; + continue; + } } - dcb_close_finish(dcb); } - + /** + * close protocol and router session + */ + if (dcb->func.close != NULL) + { + dcb->func.close(dcb); + } + /** Call possible callback for this DCB in case of close */ + dcb_call_callback(dcb, DCB_REASON_CLOSE); + + if (dcb->fd > 0) { /*< @@ -1826,7 +1857,7 @@ dcb_close(DCB *dcb) pthread_self(), dcb, STRDCBSTATE(dcb->state)))); - raise(SIGABRT); + raise(SIGABRT); } /** @@ -1902,6 +1933,20 @@ dcb_maybe_add_persistent(DCB *dcb) dcb->user))); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); + if (dcb->session) + /*< + * Terminate client session. + */ + { + SESSION *local_session = dcb->session; + session_set_dummy(dcb); + CHK_SESSION(local_session); + if (SESSION_STATE_DUMMY != local_session->state) + { + session_free(local_session); + } + } + dcb->callbacks = NULL; spinlock_acquire(&dcb->server->persistlock); dcb->nextpersistent = dcb->server->persistent; dcb->server->persistent = dcb; @@ -2063,6 +2108,15 @@ dprintOneDCB(DCB *pdcb, DCB *dcb) if (dcb->remote) dcb_printf(pdcb, "\tConnected to: %s\n", dcb->remote); + if (dcb->server) + { + if (dcb->server->name) + dcb_printf(pdcb, "\tServer name/IP: %s\n", + dcb->server->name); + if (dcb->server->port) + dcb_printf(pdcb, "\tPort number: %d\n", + dcb->server->port); + } if (dcb->user) dcb_printf(pdcb, "\tUsername: %s\n", dcb->user); @@ -2858,7 +2912,10 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) { nextdcb = disposals->nextpersistent; disposals->persistentstart = 0; - dcb_close_finish(disposals); + if (DCB_STATE_POLLING == dcb->state) + { + poll_remove_dcb(dcb); + } dcb_close(disposals); disposals = nextdcb; } diff --git a/server/core/poll.c b/server/core/poll.c index b3fb82920..2e6745987 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -860,7 +860,12 @@ unsigned long qtime; #endif /* FAKE_CODE */ ss_debug(spinlock_acquire(&dcb->dcb_initlock);) ss_dassert(dcb->state != DCB_STATE_ALLOC); - ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); + /* It isn't obvious that this is impossible */ + /* ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); */ + if (DCB_STATE_DISCONNECTED == dcb->state) + { + return 0; + } ss_debug(spinlock_release(&dcb->dcb_initlock);) LOGIF(LD, (skygw_log_write( diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 94efb669c..d72d6a639 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) { int rc = 0; CHK_DCB(dcb); - if (!dcb->session && dcb->persistentstart) + if (dcb->persistentstart) { dcb->dcb_errhandle_called = true; goto return_rc; @@ -407,16 +407,11 @@ static int gw_read_backend_event(DCB *dcb) { else { dcb->dcb_errhandle_called = true; + dcb_close(dcb); + rc = 1; + goto return_rc; } gwbuf_free(errbuf); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] " - "after calling handleError. Backend " - "DCB %p, session %p", - pthread_self(), - dcb, - dcb->session))); spinlock_acquire(&session->ses_lock); session->state = SESSION_STATE_STOPPING; @@ -1066,7 +1061,7 @@ gw_backend_hangup(DCB *dcb) session_state_t ses_state; CHK_DCB(dcb); - if (!dcb->session && dcb->persistentstart) + if (dcb->persistentstart) { dcb->dcb_errhandle_called = true; goto retblock; @@ -1124,6 +1119,7 @@ gw_backend_hangup(DCB *dcb) } } gwbuf_free(errbuf); + dcb_close(dcb); goto retblock; } #if defined(SS_DEBUG) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index e32bdd677..ceeb0a627 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -886,7 +886,7 @@ static void handleError( spinlock_release(&session->ses_lock); } - if (router_cli_ses->backend_dcb) { + if (router_cli_ses && router_cli_ses->backend_dcb) { if (backend_dcb != router_cli_ses->backend_dcb) { /* Linkages have gone badly wrong */ @@ -898,9 +898,9 @@ static void handleError( backend_dcb))); } router_cli_ses->backend_dcb = NULL; - dcb_close(backend_dcb); } - + dcb_close(backend_dcb); + /** false because connection is not available anymore */ *succp = false; } diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index d8d8033f0..1a42f1b12 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -990,7 +990,7 @@ static void closeSession( int i; /** * This sets router closed. Nobody is allowed to use router - * whithout checking this first. + * without checking this first. */ router_cli_ses->rses_closed = true; @@ -5306,8 +5306,6 @@ static int router_handle_state_switch( backend_ref_t* bref; int rc = 1; SERVER* srv; - ROUTER_CLIENT_SES* rses; - SESSION* ses; CHK_DCB(dcb); bref = (backend_ref_t *)data; CHK_BACKEND_REF(bref); @@ -5327,7 +5325,10 @@ static int router_handle_state_switch( srv->port, STRSRVSTATUS(srv)))); CHK_SESSION(((SESSION*)dcb->session)); - CHK_CLIENT_RSES(((ROUTER_CLIENT_SES *)dcb->session->router_session)); + if (dcb->session->router_session) + { + CHK_CLIENT_RSES(((ROUTER_CLIENT_SES *)dcb->session->router_session)); + } switch (reason) { case DCB_REASON_NOT_RESPONDING: From 7aa36b77ea4baef7c845a3fb83b6dc6e6c294faa Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 21 Sep 2015 14:25:12 +0100 Subject: [PATCH 055/179] Guarantee router session is present for call to clientReply; properly free callbacks; attempt to set all necessary values for dbusers; do more to ensure buffers freed. --- server/core/dbusers.c | 1 + server/core/dcb.c | 9 ++++++++- server/core/hashtable.c | 6 +++++- server/modules/protocol/maxscaled.c | 6 +++--- server/modules/protocol/mysql_backend.c | 3 ++- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 701d59764..f54f11048 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -1782,6 +1782,7 @@ static void *uh_keydup(void* key) { if (current_key->resource) rval->resource = strdup(current_key->resource); + else rval->resource = NULL; return (void *) rval; } diff --git a/server/core/dcb.c b/server/core/dcb.c index bd7d5677e..5dc3ee186 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1926,6 +1926,7 @@ dcb_maybe_add_persistent(DCB *dcb) && !(dcb->flags & DCBF_HUNG) && (poolcount = dcb_persistent_clean_count(dcb, false)) < dcb->server->persistpoolmax) { + DCB_CALLBACK *loopcallback; LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [dcb_maybe_add_persistent] Adding DCB to persistent pool, user %s.\n", @@ -1946,7 +1947,13 @@ dcb_maybe_add_persistent(DCB *dcb) session_free(local_session); } } - dcb->callbacks = NULL; + spinlock_acquire(&dcb->cb_lock); + while ((loopcallback = dcb->callbacks) != NULL) + { + dcb->callbacks = loopcallback->next; + free(loopcallback); + } + spinlock_release(&dcb->cb_lock); spinlock_acquire(&dcb->server->persistlock); dcb->nextpersistent = dcb->server->persistent; dcb->server->persistent = dcb; diff --git a/server/core/hashtable.c b/server/core/hashtable.c index c43b76916..4f7620349 100644 --- a/server/core/hashtable.c +++ b/server/core/hashtable.c @@ -762,7 +762,11 @@ char buf[40]; key = keyread(fd); value = valueread(fd); if (key == NULL || value == NULL) - break; + { + free(key); + free(value); + break; + } hashtable_add(table, key, value); rval++; } diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index 1f05498f1..a00a47d3c 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -156,7 +156,7 @@ char *password; maxscaled->username = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); maxscaled->state = MAXSCALED_STATE_PASSWD; dcb_printf(dcb, "PASSWORD"); - gwbuf_consume(head, GWBUF_LENGTH(head)); + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); break; case MAXSCALED_STATE_PASSWD: password = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head)); @@ -170,7 +170,7 @@ char *password; dcb_printf(dcb, "FAILED"); maxscaled->state = MAXSCALED_STATE_LOGIN; } - gwbuf_consume(head, GWBUF_LENGTH(head)); + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); free(password); break; case MAXSCALED_STATE_DATA: @@ -182,7 +182,7 @@ char *password; else { // Force the free of the buffer header - gwbuf_consume(head, 0); + while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL); } } } diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index d72d6a639..28c2d2a43 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -569,7 +569,8 @@ static int gw_read_backend_event(DCB *dcb) { */ if (dcb->session->state == SESSION_STATE_ROUTER_READY && dcb->session->client != NULL && - dcb->session->client->state == DCB_STATE_POLLING) + dcb->session->client->state == DCB_STATE_POLLING && + session->router_session) { client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol); From 15f042f083a718602977dc19eaf0258eb6f2d455 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 21 Sep 2015 15:49:57 +0100 Subject: [PATCH 056/179] On reflection, freeing keys and values in hashtable processing is not a good idea because we don't know what they are, and can put up with some small memory losses. --- server/core/hashtable.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/core/hashtable.c b/server/core/hashtable.c index 4f7620349..7fd45e898 100644 --- a/server/core/hashtable.c +++ b/server/core/hashtable.c @@ -763,8 +763,6 @@ char buf[40]; value = valueread(fd); if (key == NULL || value == NULL) { - free(key); - free(value); break; } hashtable_add(table, key, value); From 95a4daecc974ad1c60e2103d47093d5bb55e877c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 22 Sep 2015 11:54:47 +0100 Subject: [PATCH 057/179] Add GWBUF_POINTER_IN_BUFFER macro; add extra free calls to remove memory leaks. --- server/include/buffer.h | 3 +++ server/modules/protocol/mysql_backend.c | 1 + server/modules/protocol/mysql_client.c | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/server/include/buffer.h b/server/include/buffer.h index c0555bae4..6be9fc7aa 100644 --- a/server/include/buffer.h +++ b/server/include/buffer.h @@ -168,6 +168,9 @@ typedef struct gwbuf { /*< Consume a number of bytes in the buffer */ #define GWBUF_CONSUME(b, bytes) ((b)->start = bytes > ((char *)(b)->end - (char *)(b)->start) ? (b)->end : (void *)((char *)(b)->start + (bytes))); +/*< Check if a given pointer is within the buffer */ +#define GWBUF_POINTER_IN_BUFFER (ptr, b) ((char *)(ptr) >= (char *)(b)->start && (char *)(ptr) < (char *)(b)->end) + /*< Consume a complete buffer */ #define GWBUF_CONSUME_ALL(b) gwbuf_consume((b), GWBUF_LENGTH((b))) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 28c2d2a43..fe23c9778 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -406,6 +406,7 @@ static int gw_read_backend_event(DCB *dcb) { } else { + gwbuf_free(errbuf); dcb->dcb_errhandle_called = true; dcb_close(dcb); rc = 1; diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index edda2b888..861b20da0 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -817,6 +817,10 @@ int gw_read_client_event( "Session will be closed."))); } rc = 1; + while (read_buffer) + { + read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); + } goto return_rc; } } @@ -828,6 +832,10 @@ int gw_read_client_event( 2, 0, "failed to create new session"); + while (read_buffer) + { + read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); + } return 0; } } @@ -1204,6 +1212,10 @@ int gw_read_client_event( "Session will be closed."))); } + while (read_buffer) + { + read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); + } } } } From 89667294b36b2fb7cdad43bd2b17b50193003258 Mon Sep 17 00:00:00 2001 From: Martin Brampton Date: Thu, 24 Sep 2015 07:39:47 +0100 Subject: [PATCH 058/179] Fix exceptional cases in DCB dcb_call_callback and in MySQL backend gw_error_backend_event - close DCB and return. --- server/core/dcb.c | 5 +++++ server/modules/protocol/mysql_backend.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/server/core/dcb.c b/server/core/dcb.c index 5dc3ee186..e17b4126a 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -2672,6 +2672,11 @@ dcb_call_callback(DCB *dcb, DCB_REASON reason) { DCB_CALLBACK *cb, *nextcb; + if (NULL == dcb->session->router_session) + { + dcb_close(dcb); + return; + } spinlock_acquire(&dcb->cb_lock); cb = dcb->callbacks; while (cb) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index fe23c9778..6907db4d9 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -828,6 +828,11 @@ static int gw_error_backend_event(DCB *dcb) CHK_DCB(dcb); session = dcb->session; CHK_SESSION(session); + if (SESSION_STATE_DUMMY == session->state) + { + dcb_close(dcb); + return 1; + } rsession = session->router_session; router = session->service->router; router_instance = session->service->router_instance; From 2231d0870c5a992eec37cee4e1e8eb8e1a57782c Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 25 Sep 2015 12:17:11 +0100 Subject: [PATCH 059/179] Place checks in callback routines because DCB will not always contain a reference to a router session, and the associated data will be invalid in this case. --- server/core/dcb.c | 5 ----- server/modules/routing/binlog/blr_slave.c | 10 ++++++++++ server/modules/routing/readconnroute.c | 9 +++++++++ server/modules/routing/readwritesplit/readwritesplit.c | 10 ++++++++++ server/modules/routing/schemarouter/schemarouter.c | 10 ++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 4c643de53..01717667c 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -2574,11 +2574,6 @@ dcb_call_callback(DCB *dcb, DCB_REASON reason) { DCB_CALLBACK *cb, *nextcb; - if (NULL == dcb->session->router_session) - { - dcb_close(dcb); - return; - } spinlock_acquire(&dcb->cb_lock); cb = dcb->callbacks; while (cb) diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index e92beb277..a2a9ebb2a 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -38,6 +38,7 @@ * 19/03/2015 Massimiliano Pinto Addition of basic MariaDB 10 compatibility support * 07/05/2015 Massimiliano Pinto Added MariaDB 10 Compatibility * 11/05/2015 Massimiliano Pinto Only MariaDB 10 Slaves can register to binlog router with a MariaDB 10 Master + * 25/09/2015 Martin Brampton Block callback processing when no router session in the DCB * * @endverbatim */ @@ -1606,6 +1607,15 @@ blr_slave_callback(DCB *dcb, DCB_REASON reason, void *data) ROUTER_SLAVE *slave = (ROUTER_SLAVE *)data; ROUTER_INSTANCE *router = slave->router; + if (NULL == dcb->session->router_session) + { + /* + * The following processing will fail if there is no router session, + * because the "data" parameter will not contain meaningful data, + * so we have no choice but to stop here. + */ + return; + } if (reason == DCB_REASON_DRAINED) { if (slave->state == BLRS_DUMPING) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index ceeb0a627..2f7faba4f 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -69,6 +69,7 @@ * 27/06/2014 Mark Riddoch Addition of server weighting * 11/06/2015 Martin Brampton Remove decrement n_current (moved to dcb.c) * 09/09/2015 Martin Brampton Modify error handler + * 25/09/2015 Martin Brampton Block callback processing when no router session in the DCB * * @endverbatim */ @@ -1010,6 +1011,14 @@ static int handle_state_switch(DCB* dcb,DCB_REASON reason, void * routersession) SERVICE* service = session->service; ROUTER* router = (ROUTER *)service->router; + if (NULL == dcb->session->router_session && DCB_REASON_ERROR != reason) + { + /* + * We cannot handle a DCB that does not have a router session, + * except in the case where error processing is invoked. + */ + return; + } switch(reason) { case DCB_REASON_CLOSE: diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index e40031d24..074b40475 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -71,6 +71,7 @@ extern __thread log_info_t tls_log_info; * 17/07/2014 Massimiliano Pinto Server connection counter is updated in closeSession * * 09/09/2015 Martin Brampton Modify error handler + * 25/09/2015 Martin Brampton Block callback processing when no router session in the DCB * * @endverbatim */ @@ -5308,6 +5309,15 @@ static int router_handle_state_switch( int rc = 1; SERVER* srv; CHK_DCB(dcb); + if (NULL == dcb->session->router_session) + { + /* + * The following processing will fail if there is no router session, + * because the "data" parameter will not contain meaningful data, + * so we have no choice but to stop here. + */ + return; + } bref = (backend_ref_t *)data; CHK_BACKEND_REF(bref); diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index b2d1d9eb5..ed29d95e2 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -59,6 +59,7 @@ extern __thread log_info_t tls_log_info; * Date Who Description * 01/12/2014 Vilho Raatikka/Markus Mäkelä Initial implementation * 09/09/2015 Martin Brampton Modify error handler + * 25/09/2015 Martin Brampton Block callback processing when no router session in the DCB * * @endverbatim */ @@ -4404,6 +4405,15 @@ router_handle_state_switch( SERVER* srv; CHK_DCB(dcb); + if (NULL == dcb->session->router_session) + { + /* + * The following processing will fail if there is no router session, + * because the "data" parameter will not contain meaningful data, + * so we have no choice but to stop here. + */ + return; + } bref = (backend_ref_t *) data; CHK_BACKEND_REF(bref); From d582c5880c8700397c60ba7baf8981922997f5b1 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 29 Sep 2015 11:58:31 +0100 Subject: [PATCH 060/179] Impose locking on dcb_call_foreach DCB callback mechanism. Add counters and maxima for DCBs and zombies to aid diagnosis. --- server/core/dcb.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 01717667c..80dd84cec 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -56,6 +56,8 @@ * remove dcb_set_state etc, simplifications. * 10/07/2015 Martin Brampton Simplify, merge dcb_read and dcb_read_n * 04/09/2015 Martin Brampton Changes to ensure DCB always has session pointer + * 28/09/2015 Martin Brampton Add counters, maxima for DCBs and zombies + * 29/05/2015 Martin Brampton Impose locking in dcb_call_foreach callbacks * * @endverbatim */ @@ -87,7 +89,11 @@ extern size_t log_ses_count[]; extern __thread log_info_t tls_log_info; static DCB *allDCBs = NULL; /* Diagnostics need a list of DCBs */ +static int nDCBs = 0; +static int maxDCBs = 0; static DCB *zombies = NULL; +static int nzombies = 0; +static int maxzombies = 0; static SPINLOCK dcbspin = SPINLOCK_INIT; static SPINLOCK zombiespin = SPINLOCK_INIT; @@ -227,6 +233,8 @@ DCB *newdcb; ptr = ptr->next; ptr->next = newdcb; } + nDCBs++; + if (nDCBs > maxDCBs) maxDCBs = nDCBs; spinlock_release(&dcbspin); return newdcb; } @@ -328,6 +336,7 @@ dcb_final_free(DCB *dcb) if (ptr) ptr->next = dcb->next; } + nDCBs--; spinlock_release(&dcbspin); if (dcb->session) { @@ -492,6 +501,7 @@ DCB *listofdcb = NULL; * (listofdcb) is not NULL, then it follows that * dcb will also not be null. */ + nzombies--; zombiedcb->memdata.next = listofdcb; listofdcb = zombiedcb; } @@ -565,6 +575,8 @@ dcb_process_victim_queue(DCB *listofdcb) nextdcb = dcb->memdata.next; dcb->memdata.next = zombies; zombies = dcb; + nzombies++; + if (nzombies > maxzombies) maxzombies = nzombies; spinlock_release(&zombiespin); if (dcb->server) { @@ -1800,6 +1812,8 @@ dcb_close(DCB *dcb) dcb->dcb_is_zombie = true; dcb->memdata.next = zombies; zombies = dcb; + nzombies++; + if (nzombies > maxzombies) maxzombies = nzombies; /*< Set bit for each maxscale thread. This should be done before * the state is changed, so as to protect the DCB from premature * destruction. */ @@ -2695,17 +2709,21 @@ dcb_call_foreach(struct server* server, DCB_REASON reason) case DCB_REASON_NOT_RESPONDING: { DCB *dcb; - dcb = dcb_get_next(NULL); - + spinlock_acquire(&dcbspin); + dcb = allDCBs; + while (dcb != NULL) { + spinlock_acquire(&dcb->dcb_initlock); if (dcb->state == DCB_STATE_POLLING && dcb->server && - strcmp(dcb->server->unique_name,server->unique_name) == 0) + strcmp(dcb->server->unique_name,server->unique_name) == 0) { dcb_call_callback(dcb, DCB_REASON_NOT_RESPONDING); } - dcb = dcb_get_next(dcb); + spinlock_release(&dcb->dcb_initlock); + dcb = dcb->next; } + spinlock_release(&dcbspin); break; } From e38ea9d07d9c3ddaa6b45035b7a8129a6bab77bf Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 2 Oct 2015 16:19:59 +0100 Subject: [PATCH 061/179] Correct missing return value. --- server/modules/routing/binlog/blr_slave.c | 2 +- server/modules/routing/readconnroute.c | 2 +- server/modules/routing/readwritesplit/readwritesplit.c | 2 +- server/modules/routing/schemarouter/schemarouter.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index a2a9ebb2a..693aff5bc 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -1614,7 +1614,7 @@ ROUTER_INSTANCE *router = slave->router; * because the "data" parameter will not contain meaningful data, * so we have no choice but to stop here. */ - return; + return 0; } if (reason == DCB_REASON_DRAINED) { diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 2f7faba4f..65eb8e8d4 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -1017,7 +1017,7 @@ static int handle_state_switch(DCB* dcb,DCB_REASON reason, void * routersession) * We cannot handle a DCB that does not have a router session, * except in the case where error processing is invoked. */ - return; + return 0; } switch(reason) { diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 92332d8ec..113d57ea6 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -5309,7 +5309,7 @@ static int router_handle_state_switch( * because the "data" parameter will not contain meaningful data, * so we have no choice but to stop here. */ - return; + return 0; } bref = (backend_ref_t *)data; CHK_BACKEND_REF(bref); diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index ed29d95e2..55a15caa2 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -4412,7 +4412,7 @@ router_handle_state_switch( * because the "data" parameter will not contain meaningful data, * so we have no choice but to stop here. */ - return; + return 0; } bref = (backend_ref_t *) data; CHK_BACKEND_REF(bref); From 5c985b42ba7f0ed95f96d5dd36e695cdcdff17be Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 5 Oct 2015 16:36:07 +0100 Subject: [PATCH 062/179] Fix problem with persistent DCB disposal --- server/core/dcb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 80dd84cec..b9ccbbfd5 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -560,7 +560,7 @@ dcb_process_victim_queue(DCB *listofdcb) } else { /* Must be DCB_STATE_POLLING */ - if (dcb_maybe_add_persistent(dcb)) + if (0 == dcb->persistentstart && dcb_maybe_add_persistent(dcb)) { /* Have taken DCB into persistent pool, no further killing */ dcb = dcb->memdata.next; @@ -1787,7 +1787,7 @@ dcb_close(DCB *dcb) /* * If DCB is in persistent pool, mark it as an error and exit */ - if (dcb->persistentstart) + if (dcb->persistentstart > 0) { dcb->dcb_errhandle_called = true; return; @@ -1796,7 +1796,7 @@ dcb_close(DCB *dcb) spinlock_acquire(&zombiespin); if (!dcb->dcb_is_zombie) { - if (dcb->server && DCB_STATE_POLLING == dcb->state) + if (0 == dcb->persistentstart && dcb->server && DCB_STATE_POLLING == dcb->state) { /* May be a candidate for persistence, so save user name */ char *user; @@ -2838,7 +2838,7 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) while (disposals) { nextdcb = disposals->nextpersistent; - disposals->persistentstart = 0; + disposals->persistentstart = -1; if (DCB_STATE_POLLING == dcb->state) { poll_remove_dcb(dcb); From bb53eb0f6d865b103bf46589c3769c1d2c409830 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 7 Oct 2015 17:06:21 +0100 Subject: [PATCH 063/179] Put extra check in hashtable_fetch to return if zero entries (should never happen but will crash if not checked); remove dcb_close from mysql_backend where it closes backend DCBs, as these should be closed by the router. --- server/core/hashtable.c | 2 +- server/modules/protocol/mysql_backend.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/server/core/hashtable.c b/server/core/hashtable.c index 7fd45e898..dbcd56fd9 100644 --- a/server/core/hashtable.c +++ b/server/core/hashtable.c @@ -379,7 +379,7 @@ hashtable_fetch(HASHTABLE *table, void *key) unsigned int hashkey; HASHENTRIES *entry; - if(table == NULL || key == NULL) + if(table == NULL || key == NULL || 0 == table->hashsize) return NULL; hashkey = table->hashfn(key) % table->hashsize; diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 4874697fa..d6ada9fa8 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -44,6 +44,7 @@ * 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support * 10/11/2014 Massimiliano Pinto Client charset is passed to backend * 19/06/2015 Martin Brampton Persistent connection handling + * 07/10/2015 Martin Brampton Remove calls to dcb_close - should be done by routers * */ #include @@ -408,7 +409,12 @@ static int gw_read_backend_event(DCB *dcb) { { gwbuf_free(errbuf); dcb->dcb_errhandle_called = true; - dcb_close(dcb); + /* + * I'm pretty certain this is best removed and + * causes trouble if present, but have left it + * here just for now as a comment. Martin + */ + /* dcb_close(dcb); */ rc = 1; goto return_rc; } @@ -1129,7 +1135,12 @@ gw_backend_hangup(DCB *dcb) } } gwbuf_free(errbuf); - dcb_close(dcb); + /* + * I'm pretty certain this is best removed and + * causes trouble if present, but have left it + * here just for now as a comment. Martin + */ + /* dcb_close(dcb); */ goto retblock; } #if defined(SS_DEBUG) From cc42707dc0e23788f3bc4ccf739f03e4a92bc69e Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 13 Oct 2015 15:10:55 +0200 Subject: [PATCH 064/179] The read_buffer pointer must be set to null in situations where the buffer has been freed (or consumed). --- server/modules/protocol/mysql_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 3587eb8fb..eebe1f3d7 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1141,6 +1141,7 @@ int gw_read_client_event( /* Temporarily suppressed: SESSION_ROUTE_QUERY(session, read_buffer); */ /* Replaced with freeing the read buffer. */ gwbuf_free(read_buffer); + read_buffer = NULL; /** * Close router session which causes closing of backends. */ @@ -1163,12 +1164,14 @@ int gw_read_client_event( { /** add incomplete mysql packet to read queue */ dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + read_buffer = NULL; } } else { /** Feed whole packet to router */ rc = SESSION_ROUTE_QUERY(session, read_buffer); + read_buffer = NULL; } /** Routing succeed */ From efc0c7420e8784c558711b4a45b5bc1bb419b133 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 13 Oct 2015 16:19:24 +0200 Subject: [PATCH 065/179] Correct misplacement of decrementing current connections counter. --- server/core/dcb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index b9ccbbfd5..29ea757a1 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -578,15 +578,19 @@ dcb_process_victim_queue(DCB *listofdcb) nzombies++; if (nzombies > maxzombies) maxzombies = nzombies; spinlock_release(&zombiespin); - if (dcb->server) - { - atomic_add(&dcb->server->stats.n_current, -1); - } dcb = nextdcb; continue; } } } + /* + * Into the final close logic, so if DCB is for backend server, we + * must decrement the number of current connections. + */ + if (dcb->server) + { + atomic_add(&dcb->server->stats.n_current, -1); + } /** * close protocol and router session */ From d000af33f65c713ca687c96a99995710649b274d Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 13 Oct 2015 16:21:17 +0200 Subject: [PATCH 066/179] Remove obsolete function. --- server/core/dcb.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 29ea757a1..0027abbb1 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -106,7 +106,6 @@ static int dcb_null_auth(DCB *dcb, SERVER *server, SESSION *session, GWBUF *buf static inline int dcb_isvalid_nolock(DCB *dcb); static inline DCB * dcb_find_in_list(DCB *dcb); static inline void dcb_process_victim_queue(DCB *listofdcb); -static void dcb_close_finish(DCB *); static bool dcb_maybe_add_persistent(DCB *); static inline bool dcb_write_parameter_check(DCB *dcb, GWBUF *queue); #if defined(FAKE_CODE) @@ -1901,45 +1900,6 @@ dcb_maybe_add_persistent(DCB *dcb) return false; } -/** - * Final calls for DCB close - * - * @param dcb The DCB to print - * - */ -static void -dcb_close_finish(DCB *dcb) -{ - poll_remove_dcb(dcb); - /* - * Return will always be 0 or function will have crashed, so we - * threw away return value. - */ - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_close] Removed dcb %p in state %s from poll set.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); - /** - * Do a consistency check, then adjust counter if not from persistent pool - */ - if (dcb->server) - { - if (dcb->server->persistent) CHK_DCB(dcb->server->persistent); - if (0 == dcb->persistentstart) atomic_add(&dcb->server->stats.n_current, -1); - } - /** - * close protocol and router session - */ - if (dcb->func.close != NULL) - { - dcb->func.close(dcb); - } - /** Call possible callback for this DCB in case of close */ - dcb_call_callback(dcb, DCB_REASON_CLOSE); - } - /** * Diagnostic to print a DCB * From 12ceb0db0268056d852ea862127eee58bbf9eaa7 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Thu, 15 Oct 2015 14:17:49 +0200 Subject: [PATCH 067/179] Check for dummy session in mysql_backend protocol and ignore. --- server/modules/protocol/mysql_backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index d6ada9fa8..ba32b9882 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -286,7 +286,7 @@ static int gw_read_backend_event(DCB *dcb) { SESSION *session = dcb->session; int receive_rc = 0; - if (session == NULL) + if (SESSION_STATE_DUMMY == session->state) { rc = 0; goto return_with_lock; From 57f5dd15bc6168ccd6aeac554557c6dbf3041068 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Fri, 16 Oct 2015 17:55:07 +0100 Subject: [PATCH 068/179] Resolve problem of lingering backend database processes; alter MySQL monitor to insert fake events when backend server unavailable; fix problem with count of current connections. --- server/core/dcb.c | 81 ++++++++++++++++++++++++++++++++++------------ server/core/poll.c | 47 +++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 0027abbb1..c92e2e2de 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -106,6 +106,7 @@ static int dcb_null_auth(DCB *dcb, SERVER *server, SESSION *session, GWBUF *buf static inline int dcb_isvalid_nolock(DCB *dcb); static inline DCB * dcb_find_in_list(DCB *dcb); static inline void dcb_process_victim_queue(DCB *listofdcb); +static void dcb_stop_polling_and_shutdown (DCB *dcb); static bool dcb_maybe_add_persistent(DCB *); static inline bool dcb_write_parameter_check(DCB *dcb, GWBUF *queue); #if defined(FAKE_CODE) @@ -568,7 +569,7 @@ dcb_process_victim_queue(DCB *listofdcb) else { DCB *nextdcb; - poll_remove_dcb(dcb); + dcb_stop_polling_and_shutdown(dcb); spinlock_acquire(&zombiespin); bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); nextdcb = dcb->memdata.next; @@ -586,21 +587,11 @@ dcb_process_victim_queue(DCB *listofdcb) * Into the final close logic, so if DCB is for backend server, we * must decrement the number of current connections. */ - if (dcb->server) + if (dcb->server && 0 == dcb->persistentstart) { atomic_add(&dcb->server->stats.n_current, -1); } - /** - * close protocol and router session - */ - if (dcb->func.close != NULL) - { - dcb->func.close(dcb); - } - /** Call possible callback for this DCB in case of close */ - dcb_call_callback(dcb, DCB_REASON_CLOSE); - - + if (dcb->fd > 0) { /*< @@ -651,6 +642,26 @@ dcb_process_victim_queue(DCB *listofdcb) LOGIF(LT, tls_log_info.li_sesid = 0); } +/** + * Remove a DCB from the poll list and trigger shutdown mechanisms. + * + * @param dcb The DCB to be processed + */ +static void +dcb_stop_polling_and_shutdown (DCB *dcb) +{ + poll_remove_dcb(dcb); + /** + * close protocol and router session + */ + if (dcb->func.close != NULL) + { + dcb->func.close(dcb); + } + /** Call possible callback for this DCB in case of close */ + dcb_call_callback(dcb, DCB_REASON_CLOSE); +} + /** * Connect to a server * @@ -2697,6 +2708,36 @@ dcb_call_foreach(struct server* server, DCB_REASON reason) return; } +/** + * Call all the callbacks on all DCB's that match the server and the reason given + * + * @param reason The DCB_REASON that triggers the callback + */ +void +dcb_hangup_foreach(struct server* server) +{ + LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, + "%lu [dcb_hangup_foreach]", + pthread_self()))); + + DCB *dcb; + spinlock_acquire(&dcbspin); + dcb = allDCBs; + + while (dcb != NULL) + { + spinlock_acquire(&dcb->dcb_initlock); + if (dcb->state == DCB_STATE_POLLING && dcb->server && + strcmp(dcb->server->unique_name,server->unique_name) == 0) + { + poll_fake_hangup_event(dcb); + } + spinlock_release(&dcb->dcb_initlock); + dcb = dcb->next; + } + spinlock_release(&dcbspin); +} + /** * Null protocol write routine used for cloned dcb's. It merely consumes @@ -2770,11 +2811,11 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) CHK_DCB(persistentdcb); nextdcb = persistentdcb->nextpersistent; if (cleanall - || persistentdcb-> dcb_errhandle_called - || count >= server->persistpoolmax - || persistentdcb->server == NULL - || !(persistentdcb->server->status & SERVER_RUNNING) - || (time(NULL) - persistentdcb->persistentstart) > server->persistmaxtime) + || persistentdcb-> dcb_errhandle_called + || count >= server->persistpoolmax + || persistentdcb->server == NULL + || !(persistentdcb->server->status & SERVER_RUNNING) + || (time(NULL) - persistentdcb->persistentstart) > server->persistmaxtime) { /* Remove from persistent pool */ if (previousdcb) { @@ -2803,9 +2844,9 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall) { nextdcb = disposals->nextpersistent; disposals->persistentstart = -1; - if (DCB_STATE_POLLING == dcb->state) + if (DCB_STATE_POLLING == disposals->state) { - poll_remove_dcb(dcb); + dcb_stop_polling_and_shutdown(disposals); } dcb_close(disposals); disposals = nextdcb; diff --git a/server/core/poll.c b/server/core/poll.c index 2e6745987..41a66233c 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -1579,6 +1579,53 @@ uint32_t ev = EPOLLOUT; spinlock_release(&pollqlock); } +/* + * Insert a fake hangup event for a DCB into the polling queue. + * + * This is used when a monitor detects that a server is not responding. + * + * @param dcb DCB to emulate an EPOLLOUT event for + */ +void +poll_fake_hangup_event(DCB *dcb) +{ +uint32_t ev = EPOLLRDHUP; + + spinlock_acquire(&pollqlock); + if (DCB_POLL_BUSY(dcb)) + { + if (dcb->evq.pending_events == 0) + pollStats.evq_pending++; + dcb->evq.pending_events |= ev; + } + else + { + dcb->evq.pending_events = ev; + dcb->evq.inserted = hkheartbeat; + if (eventq) + { + dcb->evq.prev = eventq->evq.prev; + eventq->evq.prev->evq.next = dcb; + eventq->evq.prev = dcb; + dcb->evq.next = eventq; + } + else + { + eventq = dcb; + dcb->evq.prev = dcb; + dcb->evq.next = dcb; + } + pollStats.evq_length++; + pollStats.evq_pending++; + dcb->evq.inserted = hkheartbeat; + if (pollStats.evq_length > pollStats.evq_max) + { + pollStats.evq_max = pollStats.evq_length; + } + } + spinlock_release(&pollqlock); +} + /** * Print the event queue contents * From 482db5e84da4abc9da1bc1e09bb784c2fe283501 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Sat, 17 Oct 2015 20:00:05 +0100 Subject: [PATCH 069/179] User friendly bit mask display for DCB print; monitors to work via inserting hangups instead of callbacks. --- server/core/dcb.c | 20 ++++- server/core/gwbitmask.c | 124 +++++++++++++++++++++++++++-- server/include/gwbitmask.h | 3 + server/include/poll.h | 7 +- server/modules/monitor/galeramon.c | 5 +- server/modules/monitor/mmmon.c | 3 +- server/modules/monitor/mysql_mon.c | 4 +- 7 files changed, 152 insertions(+), 14 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index c92e2e2de..5c55be7dd 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -58,6 +58,7 @@ * 04/09/2015 Martin Brampton Changes to ensure DCB always has session pointer * 28/09/2015 Martin Brampton Add counters, maxima for DCBs and zombies * 29/05/2015 Martin Brampton Impose locking in dcb_call_foreach callbacks + * 17/10/2015 Martin Brampton Add hangup for each and bitmask display MaxAdmin * * @endverbatim */ @@ -544,6 +545,7 @@ dcb_process_victim_queue(DCB *listofdcb) /*< * Stop dcb's listening and modify state accordingly. */ + spinlock_acquire(&dcb->dcb_initlock); if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING) { if (dcb->state == DCB_STATE_LISTENING) @@ -560,6 +562,7 @@ dcb_process_victim_queue(DCB *listofdcb) } else { /* Must be DCB_STATE_POLLING */ + spinlock_release(&dcb->dcb_initlock); if (0 == dcb->persistentstart && dcb_maybe_add_persistent(dcb)) { /* Have taken DCB into persistent pool, no further killing */ @@ -635,6 +638,7 @@ dcb_process_victim_queue(DCB *listofdcb) dcb->state = DCB_STATE_DISCONNECTED; nextdcb = dcb->memdata.next; + spinlock_release(&dcb->dcb_initlock); dcb_final_free(dcb); dcb = nextdcb; } @@ -1831,7 +1835,10 @@ dcb_close(DCB *dcb) /*< Set bit for each maxscale thread. This should be done before * the state is changed, so as to protect the DCB from premature * destruction. */ - bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); + if (dcb->server) + { + bitmask_copy(&dcb->memdata.bitmask, poll_bitmask()); + } } spinlock_release(&zombiespin); } @@ -2036,6 +2043,15 @@ dprintOneDCB(DCB *pdcb, DCB *dcb) dcb_printf(pdcb, "\tRole: %s\n", rolename); free(rolename); } + if (!bitmask_isallclear(&dcb->memdata.bitmask)) + { + char *bitmasktext = bitmask_render_readable(&dcb->memdata.bitmask); + if (bitmasktext) + { + dcb_printf(pdcb, "\tBitMask: %s\n", bitmasktext); + free(bitmasktext); + } + } dcb_printf(pdcb, "\tStatistics:\n"); dcb_printf(pdcb, "\t\tNo. of Reads: %d\n", dcb->stats.n_reads); dcb_printf(pdcb, "\t\tNo. of Writes: %d\n", dcb->stats.n_writes); @@ -2245,7 +2261,7 @@ gw_dcb_state2string (int state) case DCB_STATE_POLLING: return "DCB in the polling loop"; case DCB_STATE_NOPOLLING: - return "DCB not in the polling loop"; + return "DCB not in polling loop"; case DCB_STATE_LISTENING: return "DCB for listening socket"; case DCB_STATE_DISCONNECTED: diff --git a/server/core/gwbitmask.c b/server/core/gwbitmask.c index 765864d72..294a64c0f 100644 --- a/server/core/gwbitmask.c +++ b/server/core/gwbitmask.c @@ -17,6 +17,7 @@ */ #include #include +#include #include /** @@ -47,10 +48,14 @@ * Date Who Description * 28/06/13 Mark Riddoch Initial implementation * 20/08/15 Martin Brampton Added caveats about limitations (above) + * 17/10/15 Martin Brampton Added display of bitmask * * @endverbatim */ +static int bitmask_isset_without_spinlock(GWBITMASK *bitmask, int bit); +static int bitmask_count_bits_set(GWBITMASK *bitmask); + /** * Initialise a bitmask * @@ -151,19 +156,42 @@ unsigned char mask; * Return a non-zero value if the bit at the specified bit * position in the bitmask is set. * The bitmask will automatically be extended if the bit is - * beyond the current bitmask length. This could be optimised - * by assuming that a bit beyond the length is unset. + * beyond the current bitmask length. The work is done in the function + * bitmask_isset_without_spinlock, which can be called when a spinlock + * has already been acquired. * * @param bitmask Pointer the bitmask - * @param bit Bit to clear + * @param bit Bit to test */ int bitmask_isset(GWBITMASK *bitmask, int bit) { +int result; + + spinlock_acquire(&bitmask->lock); + result = bitmask_isset_without_spinlock(bitmask, bit); + spinlock_release(&bitmask->lock); + return result; +} + +/** + * Return a non-zero value if the bit at the specified bit + * position in the bitmask is set. Should be called while holding a + * lock on the bitmask. + * + * The bitmask will automatically be extended if the bit is + * beyond the current bitmask length. This could be optimised + * by assuming that a bit beyond the length is unset. + * + * @param bitmask Pointer the bitmask + * @param bit Bit to test + */ +static int +bitmask_isset_without_spinlock(GWBITMASK *bitmask, int bit) +{ unsigned char *ptr; unsigned char mask; - spinlock_acquire(&bitmask->lock); if (bit >= bitmask->length) { bitmask->bits = realloc(bitmask->bits, @@ -174,7 +202,6 @@ unsigned char mask; } ptr = bitmask->bits + (bit / 8); mask = 1 << (bit % 8); - spinlock_release(&bitmask->lock); return *ptr & mask; } @@ -239,3 +266,90 @@ bitmask_copy(GWBITMASK *dest, GWBITMASK *src) spinlock_release(&src->lock); } +/** + * Return a comma separated list of the numbers of the bits that are set in + * a bitmask, numbering starting at zero. Constrained to reject requests that + * could require more than three digit numbers. The returned string must be + * freed by the caller (unless it is null on account of memory allocation + * failure). + * + * @param bitmask Bitmap to make readable + * @return pointer to the newly allocated string, or null if no memory + */ +char * +bitmask_render_readable(GWBITMASK *bitmask) +{ + char *toobig = "Bitmask is too large to render readable"; + char *empty = "No bits are set";t + char onebit[5]; + char *result; + int count_set = 0; + + spinlock_acquire(&bitmask->lock); + if (999 < bitmask->length) + { + result = malloc(strlen(toobig)); + if (result) + { + strcpy(result, toobig); + } + } + else + { + count_set = bitmask_count_bits_set(bitmask); + if (count_set) + { + result = malloc(1 + (4 * count_set)); + if (result) + { + result[0] = 0; + for (int i = 0; ilength; i++) + { + if (bitmask_isset_without_spinlock(bitmask, i)) + { + sprintf(onebit, "%d,", i); + strcat(result, onebit); + } + } + result[strlen(result)-1] = 0; + } + } + else + { + result = malloc(strlen(empty)); + if (result) + { + strcpy(result, empty); + } + } + } + spinlock_release(&bitmask->lock); + return result; +} + +/** + * Return a count of the number of bits set in a bitmask. Helpful for setting + * the size of string needed to show the set bits in readable form. + * + * @param bitmask Bitmap whose bits are to be counted + * @return int Number of set bits + */ +static int +bitmask_count_bits_set(GWBITMASK *bitmask) +{ + const unsigned char oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; + unsigned char partresults; + int result = 0; + unsigned char *ptr, *eptr; + + ptr = bitmask->bits; + eptr = ptr + (bitmask->length / 8); + while (ptr < eptr) + { + partresults = oneBits[*ptr&0x0f]; + partresults += oneBits[*ptr>>4]; + result += partresults; + ptr++; + } + return result; +} \ No newline at end of file diff --git a/server/include/gwbitmask.h b/server/include/gwbitmask.h index baeb1ef77..26d5e3621 100644 --- a/server/include/gwbitmask.h +++ b/server/include/gwbitmask.h @@ -27,6 +27,7 @@ * * Date Who Description * 28/06/13 Mark Riddoch Initial implementation + * 17/10/15 Martin Brampton Add bitmask_render_readable * * @endverbatim */ @@ -51,4 +52,6 @@ extern void bitmask_clear(GWBITMASK *, int); extern int bitmask_isset(GWBITMASK *, int); extern int bitmask_isallclear(GWBITMASK *); extern void bitmask_copy(GWBITMASK *, GWBITMASK *); +extern char *bitmask_render_readable(GWBITMASK *bitmask); + #endif diff --git a/server/include/poll.h b/server/include/poll.h index e778c580c..f054667d4 100644 --- a/server/include/poll.h +++ b/server/include/poll.h @@ -29,6 +29,7 @@ * * Date Who Description * 19/06/13 Mark Riddoch Initial implementation + * 17/10/15 Martin Brampton Declare fake event functions * * @endverbatim */ @@ -60,9 +61,11 @@ extern void poll_set_maxwait(unsigned int); extern void poll_set_nonblocking_polls(unsigned int); extern void dprintPollStats(DCB *); extern void dShowThreads(DCB *dcb); -void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf); +void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf); extern void dShowEventQ(DCB *dcb); extern void dShowEventStats(DCB *dcb); -extern int poll_get_stat(POLL_STAT stat); +extern int poll_get_stat(POLL_STAT stat); extern RESULTSET *eventTimesGetList(); +extern void poll_fake_hangup_event(DCB *dcb); +extern void poll_fake_write_event(DCB *dcb); #endif diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 2e3dd4ddd..5dde7a401 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -35,6 +35,7 @@ * 20/04/15 Guillaume Lefranc Added availableWhenDonor feature * 22/04/15 Martin Brampton Addition of disableMasterRoleSetting * 08/05/15 Markus Makela Addition of launchable scripts + * 17/10/15 Martin Brampton Change DCB callback to hangup * * @endverbatim */ @@ -541,13 +542,13 @@ monitor_event_t evtype; if (!(SERVER_IS_RUNNING(ptr->server)) || !(SERVER_IS_IN_CLUSTER(ptr->server))) { - dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING); + dcb_hangup_foreach(ptr->server); } if (SERVER_IS_DOWN(ptr->server)) { /** Increase this server'e error count */ - dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING); + dcb_hangup_foreach(ptr->server); ptr->mon_err_count += 1; } diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 248fb92fd..1ada6ad8d 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -25,6 +25,7 @@ * Date Who Description * 08/09/14 Massimiliano Pinto Initial implementation * 08/05/15 Markus Makela Addition of launchable scripts + * 17/10/15 Martin Brampton Change DCB callback to hangup * * @endverbatim */ @@ -625,7 +626,7 @@ detect_stale_master = handle->detectStaleMaster; if (mon_status_changed(ptr)) { - dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING); + dcb_hangup_foreach(ptr->server); } if (mon_status_changed(ptr) || diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 4bb8a59b5..aca071c21 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -47,6 +47,7 @@ * 18/11/14 Massimiliano Pinto One server only in configuration becomes master. * servers=server1 must be present in mysql_mon and in router sections as well. * 08/05/15 Markus Makela Added launchable scripts + * 17/10/15 Martin Brampton Change DCB callback to hangup * * @endverbatim */ @@ -861,8 +862,7 @@ detect_stale_master = handle->detectStaleMaster; if (!(SERVER_IS_RUNNING(ptr->server)) || !(SERVER_IS_IN_CLUSTER(ptr->server))) { - dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING); - + dcb_hangup_foreach(ptr->server); } From c74d320851307d8e0a332fdd99186103e228d725 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Sat, 17 Oct 2015 20:02:59 +0100 Subject: [PATCH 070/179] Remove stray character. --- server/core/gwbitmask.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/gwbitmask.c b/server/core/gwbitmask.c index 294a64c0f..0068c846f 100644 --- a/server/core/gwbitmask.c +++ b/server/core/gwbitmask.c @@ -280,7 +280,7 @@ char * bitmask_render_readable(GWBITMASK *bitmask) { char *toobig = "Bitmask is too large to render readable"; - char *empty = "No bits are set";t + char *empty = "No bits are set"; char onebit[5]; char *result; int count_set = 0; From 6040f1107098f4bd29dfdae5e6efc24e9e6dacb3 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Sat, 17 Oct 2015 20:06:37 +0100 Subject: [PATCH 071/179] Include DCB headers to remove warnings. --- server/modules/monitor/galeramon.c | 1 + server/modules/monitor/mmmon.c | 2 +- server/modules/monitor/mysql_mon.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 5dde7a401..cea0e27ef 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -42,6 +42,7 @@ #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 1ada6ad8d..794062e33 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -30,8 +30,8 @@ * @endverbatim */ - #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index aca071c21..d26ef8a75 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -54,6 +54,7 @@ #include +#include /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; From 6e9a2a89eb685d3dfcb3f118c9b2953d67454e2d Mon Sep 17 00:00:00 2001 From: counterpoint Date: Sat, 17 Oct 2015 20:09:05 +0100 Subject: [PATCH 072/179] Add dcb_hangup_foreach to DCB header. --- server/include/dcb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/server/include/dcb.h b/server/include/dcb.h index c9312a128..22e8d21aa 100644 --- a/server/include/dcb.h +++ b/server/include/dcb.h @@ -339,6 +339,7 @@ int dcb_count_by_usage(DCB_USAGE); /* Return counts of DCBs */ int dcb_persistent_clean_count(DCB *, bool); /* Clean persistent and return count */ void dcb_call_foreach (struct server* server, DCB_REASON reason); +void dcb_hangup_foreach (struct server* server); size_t dcb_get_session_id(DCB* dcb); bool dcb_get_ses_log_info(DCB* dcb, size_t* sesid, int* enabled_logs); char *dcb_role_name(DCB *); /* Return the name of a role */ From 5112d4118f154f3b8e96c3156e6ff2c852c26877 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 16 Oct 2015 09:24:43 +0300 Subject: [PATCH 073/179] Fix to MXS-409: https://mariadb.atlassian.net/browse/MXS-409 Prepared statements are sent to the master instead of all servers. The planned functionality to store the types of the prepared statements was not implemented and all executions of prepared statements are sent to the master. Because of this the preparations should be all sent to the master server instead of sending them to all servers. --- server/modules/routing/readwritesplit/readwritesplit.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 113d57ea6..7a6ccc7d2 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1381,8 +1381,6 @@ static route_target_t get_route_target ( * These queries are not affected by hints */ if (QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE) || - QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_STMT) || - QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) || /** Configured to allow writing variables to all nodes */ (use_sql_variables_in == TYPE_ALL && QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_WRITE)) || @@ -1432,6 +1430,8 @@ static route_target_t get_route_target ( QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ)|| /*< read user var */ QUERY_IS_TYPE(qtype, QUERY_TYPE_SYSVAR_READ) || /*< read sys var */ QUERY_IS_TYPE(qtype, QUERY_TYPE_EXEC_STMT) || /*< prepared stmt exec */ + QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_STMT) || + QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) || QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_READ))) /*< read global sys var */ { /** First set expected targets before evaluating hints */ @@ -1449,6 +1449,8 @@ static route_target_t get_route_target ( if (QUERY_IS_TYPE(qtype, QUERY_TYPE_MASTER_READ) || QUERY_IS_TYPE(qtype, QUERY_TYPE_EXEC_STMT) || + QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_STMT) || + QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) || /** Configured not to allow reading variables from slaves */ (use_sql_variables_in == TYPE_MASTER && (QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ) || From 33ba9e1bae07be51e5dd328e72e5527be4b158bb Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 16 Oct 2015 22:27:38 +0300 Subject: [PATCH 074/179] Added missing maxadmin tests. --- client/CMakeLists.txt | 4 ++ client/test/CMakeLists.txt | 4 ++ client/test/maxadmin_stress.sh | 0 client/test/maxadmin_test.sh | 82 ++++++++++++++-------------------- 4 files changed, 41 insertions(+), 49 deletions(-) create mode 100644 client/test/CMakeLists.txt mode change 100644 => 100755 client/test/maxadmin_stress.sh diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 32ab702ea..eb13ae659 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -8,3 +8,7 @@ else() message(STATUS "Could not find editline library. MaxAdmin will be built without it.") endif() install(TARGETS maxadmin DESTINATION ${MAXSCALE_BINDIR}) + +if(BUILD_TESTS) + add_subdirectory(test) +endif() diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt new file mode 100644 index 000000000..e59eaf7f0 --- /dev/null +++ b/client/test/CMakeLists.txt @@ -0,0 +1,4 @@ +install(PROGRAMS maxadmin_test.sh DESTINATION ${CMAKE_BINARY_DIR}) +install(PROGRAMS maxadmin_stress.sh DESTINATION ${CMAKE_BINARY_DIR}) +add_test(TestMaxAdmin ${CMAKE_BINARY_DIR}/maxadmin_test.sh) +add_test(TestMaxAdminStress ${CMAKE_BINARY_DIR}/maxadmin_stress.sh) diff --git a/client/test/maxadmin_stress.sh b/client/test/maxadmin_stress.sh old mode 100644 new mode 100755 diff --git a/client/test/maxadmin_test.sh b/client/test/maxadmin_test.sh index c58c1512e..03976bc90 100755 --- a/client/test/maxadmin_test.sh +++ b/client/test/maxadmin_test.sh @@ -96,61 +96,45 @@ fi # # Test enable|disable log debug|trace|message|error # -maxadmin -pmariadb enable log debug >& /dev/null -if [ $? -eq "1" ]; then - echo "Enable debug log: Failed" - failure=`expr $failure + 1` -else - passed=`expr $passed + 1` - echo "Enable debug log: Passed" -fi -maxadmin -pmariadb enable log trace >& /dev/null -if [ $? -eq "1" ]; then - echo "Enable trace log: Failed" - failure=`expr $failure + 1` -else - passed=`expr $passed + 1` - echo "Enable trace log: Passed" -fi +for action in enable disable +do + maxadmin -pmariadb $action log debug >& /dev/null + if [ $? -eq "1" ]; then + echo "$action debug log: Failed" + failure=`expr $failure + 1` + else + passed=`expr $passed + 1` + echo "$action debug log: Passed" + fi -maxadmin -pmariadb enable log message >& /dev/null -if [ $? -eq "1" ]; then - echo "Enable message log: Failed" + maxadmin -pmariadb $action log trace >& /dev/null + if [ $? -eq "1" ]; then + echo "$action trace log: Failed" + failure=`expr $failure + 1` + else + passed=`expr $passed + 1` + echo "$action trace log: Passed" + fi + + maxadmin -pmariadb $action log message >& /dev/null + if [ $? -eq "1" ]; then + echo "$action message log: Failed" failure=`expr $failure + 1` -else + else passed=`expr $passed + 1` - echo "Enable message log: Passed" -fi + echo "$action message log: Passed" + fi -maxadmin -pmariadb enable log error >& /dev/null -if [ $? -eq "1" ]; then - echo "Enable error log: Failed" + maxadmin -pmariadb $action log error >& /dev/null + if [ $? -eq "1" ]; then + echo "$action error log: Failed" failure=`expr $failure + 1` -else + else passed=`expr $passed + 1` - echo "Enable error log: Passed" -fi - - - -maxadmin -pmariadb disable log debug >& /dev/null -if [ $? -eq "1" ]; then - echo "Disable debug log: Failed" - failure=`expr $failure + 1` -else - passed=`expr $passed + 1` - echo "Disable debug log: Passed" -fi - -maxadmin -pmariadb disable log trace >& /dev/null -if [ $? -eq "1" ]; then - echo "Disable trace log: Failed" - failure=`expr $failure + 1` -else - passed=`expr $passed + 1` - echo "Disable trace log: Passed" -fi + echo "$action error log: Passed" + fi +done # # Test restart monitor|service without, with invalid and with long invalid argument @@ -186,7 +170,7 @@ do done # -# Test set server qwerty master withaout, with invalid and with long invalid arg +# Test set server qwerty master without, with invalid and with long invalid arg # maxadmin -pmariadb set server qwerty >& /dev/null if [ $? -eq "1" ]; then From 040587c82830eb4544ebfcd7b2866e6bf9956c2f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 16 Oct 2015 22:30:08 +0300 Subject: [PATCH 075/179] Fix to MXS-413: https://mariadb.atlassian.net/browse/MXS-413 Added missing terminating newlines so showSession and improved maxadmin logic. --- client/maxadmin.c | 3 ++- server/core/session.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/maxadmin.c b/client/maxadmin.c index dec941d2f..6f8899163 100644 --- a/client/maxadmin.c +++ b/client/maxadmin.c @@ -466,7 +466,8 @@ int i, j, newline = 1; { if (newline == 1 && buf[j] == 'O') newline = 2; - else if (newline == 2 && buf[j] == 'K' && j == i - 1) + else if ((newline == 2 && buf[j] == 'K' && j == i - 1) || + (j == i - 2 && buf[j] == 'O' && buf[j + 1] == 'K')) { return 1; } diff --git a/server/core/session.c b/server/core/session.c index e9d45b8e7..7a2429bd0 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -715,11 +715,11 @@ int i; ptr->client->user?ptr->client->user:"", ptr->client->user?"@":"", ptr->client->remote); - dcb_printf(dcb, "\tConnected: %s", + dcb_printf(dcb, "\tConnected: %s\n", asctime_r(localtime_r(&ptr->stats.connect, &result), buf)); if(ptr->client->state == DCB_STATE_POLLING) { - dcb_printf(dcb, "\tIdle: %.0f seconds",idle); + dcb_printf(dcb, "\tIdle: %.0f seconds\n",idle); } } From 06f6b280486aa32404b3c2a13e7954b3217708b7 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 17 Oct 2015 18:01:58 +0300 Subject: [PATCH 076/179] Fix to MXS-412: https://mariadb.atlassian.net/browse/MXS-412 service->user is now set to NULL after the users are freed. --- server/core/service.c | 9 ++++++--- server/modules/routing/debugcmd.c | 24 +++++++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/server/core/service.c b/server/core/service.c index 0515c5218..b209c99d4 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -258,8 +258,8 @@ GWPROTOCOL *funcs; } if (loaded == -1) { - hashtable_free(service->users->data); - free(service->users); + users_free(service->users); + service->users = NULL; dcb_close(port->listener); port->listener = NULL; goto retblock; @@ -346,6 +346,7 @@ GWPROTOCOL *funcs; == NULL) { users_free(service->users); + service->users = NULL; dcb_close(port->listener); port->listener = NULL; LOGIF(LE, (skygw_log_write_flush( @@ -380,7 +381,8 @@ GWPROTOCOL *funcs; service->name))); users_free(service->users); - dcb_close(port->listener); + service->users = NULL; + dcb_close(port->listener); port->listener = NULL; goto retblock; } @@ -394,6 +396,7 @@ GWPROTOCOL *funcs; port->protocol, service->name))); users_free(service->users); + service->users = NULL; dcb_close(port->listener); port->listener = NULL; } diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index b88a67a19..bd15b54ec 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -678,13 +678,14 @@ static struct { * Convert a string argument to a numeric, observing prefixes * for number bases, e.g. 0x for hex, 0 for octal * + * @param dcb The client DCB * @param mode The CLI mode * @param arg The string representation of the argument * @param arg_type The target type for the argument * @return The argument as a long integer */ static unsigned long -convert_arg(int mode, char *arg, int arg_type) +convert_arg(DCB* dcb, int mode, char *arg, int arg_type) { unsigned long rval; SERVICE *service; @@ -710,9 +711,18 @@ SERVICE *service; { service = service_find(arg); if (service) + { + if(service->users == NULL) + { + dcb_printf(dcb, "The dbusers for service %s are not loaded. " + "Reload the dbusers and try again.\n", service->name); + } return (unsigned long)(service->users); + } else + { return 0; + } } return rval; case ARG_TYPE_DCB: @@ -927,7 +937,7 @@ int nskip = 0; cmds[i].options[j].fn(dcb); break; case 1: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); + arg1 = convert_arg(dcb, cli->mode, args[2],cmds[i].options[j].arg_types[0]); if (arg1) cmds[i].options[j].fn(dcb, arg1); @@ -936,8 +946,8 @@ int nskip = 0; args[2]); break; case 2: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); - arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]); + arg1 = convert_arg(dcb, cli->mode, args[2],cmds[i].options[j].arg_types[0]); + arg2 = convert_arg(dcb, cli->mode, args[3],cmds[i].options[j].arg_types[1]); if (arg1 && arg2) cmds[i].options[j].fn(dcb, arg1, arg2); else if (arg1 == 0) @@ -948,9 +958,9 @@ int nskip = 0; args[3]); break; case 3: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); - arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]); - arg3 = convert_arg(cli->mode, args[4],cmds[i].options[j].arg_types[2]); + arg1 = convert_arg(dcb, cli->mode, args[2],cmds[i].options[j].arg_types[0]); + arg2 = convert_arg(dcb, cli->mode, args[3],cmds[i].options[j].arg_types[1]); + arg3 = convert_arg(dcb, cli->mode, args[4],cmds[i].options[j].arg_types[2]); if (arg1 && arg2 && arg3) cmds[i].options[j].fn(dcb, arg1, arg2, arg3); else if (arg1 == 0) From f18d921f4c3644ebd40b62f2e54e746cdda7d7a8 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 19 Oct 2015 18:17:12 +0300 Subject: [PATCH 077/179] Fixed internal service test failing due to old assumptions. --- server/core/test/testservice.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/server/core/test/testservice.c b/server/core/test/testservice.c index 5fa7e0436..5151fce44 100644 --- a/server/core/test/testservice.c +++ b/server/core/test/testservice.c @@ -84,28 +84,6 @@ init_test_env(NULL); result = serviceStartAll(); skygw_log_sync_all(); ss_info_dassert(0 != result, "Start all should succeed"); - - ss_dfprintf(stderr, "\t..done\nTiming out a session."); - - service->conn_timeout = 1; - result = serviceStart(service); - skygw_log_sync_all(); - ss_info_dassert(0 != result, "Start should succeed"); - serviceStop(service); - skygw_log_sync_all(); - ss_info_dassert(service->state == SERVICE_STATE_STOPPED, "Stop should succeed"); - - if((dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER)) == NULL) - return 1; - ss_info_dassert(dcb != NULL, "DCB allocation failed"); - - session = session_alloc(service,dcb); - ss_info_dassert(session != NULL, "Session allocation failed"); - dcb->state = DCB_STATE_POLLING; - sleep(15); - - ss_info_dassert(dcb->state != DCB_STATE_POLLING, "Session timeout failed"); - ss_dfprintf(stderr, "\t..done\nStopping Service."); serviceStop(service); ss_info_dassert(service->state == SERVICE_STATE_STOPPED, "Stop should succeed"); From bad61b074021e511b598f42c9978c026a14a8348 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 27 Oct 2015 14:17:06 +0000 Subject: [PATCH 078/179] Change binlog router to indicate it does not use router sessions via the getCapabilities interface. --- server/include/router.h | 6 ++++-- server/modules/protocol/mysql_backend.c | 3 ++- server/modules/routing/binlog/blr.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/server/include/router.h b/server/include/router.h index 4faa2ca81..5a7152d1b 100644 --- a/server/include/router.h +++ b/server/include/router.h @@ -30,6 +30,7 @@ * 15/07/2013 Massimiliano Pinto Added clientReply entry point * 16/07/2013 Massimiliano Pinto Added router commands values * 22/10/2013 Massimiliano Pinto Added router errorReply entry point + * 27/10/2015 Martin Brampton Add RCAP_TYPE_NO_RSESSION * */ #include @@ -100,8 +101,9 @@ typedef struct router_object { */ typedef enum router_capability_t { RCAP_TYPE_UNDEFINED = 0x00, - RCAP_TYPE_STMT_INPUT = 0x01, /*< statement per buffer */ - RCAP_TYPE_PACKET_INPUT = 0x02 /*< data as it was read from DCB */ + RCAP_TYPE_STMT_INPUT = 0x01, /*< statement per buffer */ + RCAP_TYPE_PACKET_INPUT = 0x02, /*< data as it was read from DCB */ + RCAP_TYPE_NO_RSESSION = 0x04 /*< router does not use router sessions */ } router_capability_t; diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index ba32b9882..29217e7e3 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -45,6 +45,7 @@ * 10/11/2014 Massimiliano Pinto Client charset is passed to backend * 19/06/2015 Martin Brampton Persistent connection handling * 07/10/2015 Martin Brampton Remove calls to dcb_close - should be done by routers + * 27/10/2015 Martin Brampton Test for RCAP_TYPE_NO_RSESSION before calling clientReply * */ #include @@ -577,7 +578,7 @@ static int gw_read_backend_event(DCB *dcb) { if (dcb->session->state == SESSION_STATE_ROUTER_READY && dcb->session->client != NULL && dcb->session->client->state == DCB_STATE_POLLING && - session->router_session) + (session->router_session || router->getCapabilities(router_instance, NULL) & RCAP_TYPE_NO_RSESSION)) { client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol); diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 51ee2b199..ce95f8895 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -38,6 +38,7 @@ * 07/05/2015 Massimiliano Pinto Addition of MariaDB 10 compatibility support * 12/06/2015 Massimiliano Pinto Addition of MariaDB 10 events in diagnostics() * 09/09/2015 Martin Brampton Modify error handler + * 27/10/2015 Martin Brampton Amend getCapabilities to return RCAP_TYPE_NO_RSESSION * * @endverbatim */ @@ -1178,7 +1179,7 @@ static void rses_end_locked_router_action(ROUTER_SLAVE * rses) static uint8_t getCapabilities(ROUTER *inst, void *router_session) { - return 0; + return RCAP_TYPE_NO_RSESSION; } /** From 42f5fe24850f198d5fded36c55f6a892fbe2f9b3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 2 Nov 2015 18:11:37 +0200 Subject: [PATCH 079/179] Removed unnecessary files. --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 1ee1402552ffa035c5c4d5247d97d0ac6503b656..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmZQzU|@7AO)+F(5MW?n;9!8zEL;p&0Z1N%F(jFwBK#opz-9z7crv&%crb)`=0N2} zsnHM^4S~TM0-(Ih$>7Z3&k(>6$$*r9^OKWu@{^!N!x;t!295t<0QL$mg9}4GLo!1t zLoP!qLmop3Ln1>7LncE$L!M_2vQEYzkWK~$2B!c23F%BKFD`)Ec`K$kNr^=<;hA|U`Q=XerFkjEF;Kzq%#@N0u%S=^PEJk^&UgW_ z>S_ZW1tW8#S{;RI3uAK~1ycjF+FF5jP7X5vkYftewdp@bnBHB6b}7#J8iz>xt7Q+5U)22TcO23H0@ zhF}I)Ow}lH$IXz#kk63L5YLdykjRk7kjRkEkjhYmrt1kP-jM7NU?^lL1*v1GWQb=- zX2@YkWGH4RX2@hnW5@)Fqv~h8!N9;U14%y{LlA>2gCm0rgD+MWBC8c)C}K!uC}7B8 z$Ye-Hq%4Mbut+gO2{_GRcQdj%Yz)N=$qYpdnG6LCC8+LWaARO#tUz&JF~}DTWgrrZ zTIBGS1*i8Uh8%`ehIpKAO$Ox#a0tO%oXk*(YBDHypu{9ALn$~P)MsPO-qz}|30nuRX42%q5 z?F@_zVD0dVl@X$yfe~smBeaLY2+_{K2+_{K2+DP<6}*s;43PKuW-}OppOZ h2`~pD2hs|v_Q6##BLk!+A8iQ0LTHp84FURx002oS5|01? From 1b04a0cf910fdfdd58f4bb5a49f5416b990d59cf Mon Sep 17 00:00:00 2001 From: counterpoint Date: Mon, 2 Nov 2015 16:27:44 +0000 Subject: [PATCH 080/179] Fix issues with error handling needing to cater for both client and backend DCBs. --- server/modules/routing/readconnroute.c | 35 +++++++++++--------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 65eb8e8d4..79d0032dc 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -125,7 +125,7 @@ static void handleError( ROUTER *instance, void *router_session, GWBUF *errbuf, - DCB *backend_dcb, + DCB *problem_dcb, error_action_t action, bool *succp); static uint8_t getCapabilities (ROUTER* inst, void* router_session); @@ -837,12 +837,12 @@ clientReply( /** * Error Handler routine * - * The routine will handle errors that occurred in backend writes. + * The routine will handle errors that occurred in writes. * * @param instance The router instance * @param router_session The router session * @param message The error message to reply - * @param backend_dcb The backend DCB + * @param problem_dcb The DCB related to the error * @param action The action: ERRACT_NEW_CONNECTION or ERRACT_REPLY_CLIENT * @param succp Result of action: true if router can continue * @@ -851,18 +851,18 @@ static void handleError( ROUTER *instance, void *router_session, GWBUF *errbuf, - DCB *backend_dcb, + DCB *problem_dcb, error_action_t action, bool *succp) { DCB *client_dcb; - SESSION *session = backend_dcb->session; + SESSION *session = problem_dcb->session; session_state_t sesstate; ROUTER_CLIENT_SES *router_cli_ses = (ROUTER_CLIENT_SES *)router_session; /** Don't handle same error twice on same DCB */ - if (backend_dcb->dcb_errhandle_called) + if (problem_dcb->dcb_errhandle_called) { /** we optimistically assume that previous call succeed */ *succp = true; @@ -870,7 +870,7 @@ static void handleError( } else { - backend_dcb->dcb_errhandle_called = true; + problem_dcb->dcb_errhandle_called = true; } spinlock_acquire(&session->ses_lock); sesstate = session->state; @@ -887,20 +887,15 @@ static void handleError( spinlock_release(&session->ses_lock); } - if (router_cli_ses && router_cli_ses->backend_dcb) { - if (backend_dcb != router_cli_ses->backend_dcb) - { - /* Linkages have gone badly wrong */ - LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Read Connection Router error in handleError: router client " - "session DCB %p is not null, but does not match backend DCB %p " - "either. \n", - router_cli_ses->backend_dcb, - backend_dcb))); - } - router_cli_ses->backend_dcb = NULL; + if (dcb_isclient(problem_dcb)) + { + dcb_close(problem_dcb); + } + else if (router_cli_ses && problem_dcb == router_cli_ses->backend_dcb) + { + router_cli_ses->backend_dcb = NULL; + dcb_close(problem_dcb); } - dcb_close(backend_dcb); /** false because connection is not available anymore */ *succp = false; From 9cd327a783e6317426f7d63411e5cd7ec2954c56 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 20 Oct 2015 11:56:17 +0300 Subject: [PATCH 081/179] Fix to MXS-417: https://mariadb.atlassian.net/browse/MXS-417 Added support for single-character wildcard in IP addresses. Single character wildcard addresses are now properly handled --- server/core/dbusers.c | 90 +++++++++++++++++++++++++- server/include/dbusers.h | 1 + server/modules/protocol/mysql_common.c | 4 ++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index bfb5bdc2e..95500691f 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -137,6 +137,27 @@ int add_wildcard_users(USERS *users, static int gw_mysql_set_timeouts(MYSQL* handle); +/** + * Check if the IP address of the user matches the one in the grant. This assumes + * that the grant has one or more single-character wildcards in it. + * @param userhost User host address + * @param wildcardhost Host address in the grant + * @return True if the host address matches + */ +bool host_matches_singlechar_wildcard(const char* user, const char* wild) +{ + while (*user != '\0' && *wild != '\0') + { + if (*user != *wild && *wild != '_') + { + return false; + } + user++; + wild++; + } + return true; +} + /** * Load the user/passwd form mysql.user table into the service users' hashtable * environment. @@ -252,6 +273,53 @@ HASHTABLE *oldresources; return i; } +/** + * Check if the IP address is a valid MySQL IP address. The IP address can contain + * single or multi-character wildcards as used by MySQL. + * @param host IP address to check + * @return True if the address is a valid, MySQL type IP address + */ +bool is_ipaddress(const char* host) +{ + while (*host != '\0') + { + if (!isdigit(*host) && *host != '.' && *host != '_' && *host != '%') + { + return false; + } + host++; + } + return true; +} + +/** + * Check if an IP address has single-character wildcards. A single-character + * wildcard is represented by an underscore in the MySQL hostnames. + * @param host Hostname to check + * @return True if the hostname is a valid IP address with a single character wildcard + */ +bool host_has_singlechar_wildcard(const char *host) +{ + const char* chrptr = host; + bool retval = false; + + while (*chrptr != '\0') + { + if (!isdigit(*chrptr) && *chrptr != '.') + { + if (*chrptr == '_') + { + retval = true; + } + else + { + return false; + } + } + chrptr++; + } + return retval; +} /** * Add a new MySQL user with host, password and netmask into the service users table @@ -308,6 +376,12 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p if (strcmp(host, "%") == 0) { strcpy(ret_ip, "0.0.0.0"); key.netmask = 0; + } else if (strnlen(host, MYSQL_HOST_MAXLEN + 1) <= MYSQL_HOST_MAXLEN && + is_ipaddress(host) && + host_has_singlechar_wildcard(host)) { + strcpy(key.hostname, host); + strcpy(ret_ip, "0.0.0.0"); + key.netmask = 0; } else { /* hostname without % wildcards has netmask = 32 */ key.netmask = normalize_hostname(host, ret_ip); @@ -1719,7 +1793,17 @@ static int uh_cmpfun( void* v1, void* v2) { if (hu1->user == NULL || hu2->user == NULL) return 0; - if (strcmp(hu1->user, hu2->user) == 0 && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr) && (hu1->netmask >= hu2->netmask)) { + /** If the stored user has the unmodified address stored, that means we were not able + * to resolve it at the time we loaded the users. We need to check if the + * address contains wildcards and if the user's address matches that. */ + + const bool wildcard_host = strlen(hu2->hostname) > 0 && strlen(hu1->hostname) > 0; + + if ((strcmp(hu1->user, hu2->user) == 0) && + /** Check for wildcard hostnames */ + ((wildcard_host && host_matches_singlechar_wildcard(hu1->hostname, hu2->hostname)) || + /** If no wildcard hostname is stored, check for network address. */ + (!wildcard_host && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr) && (hu1->netmask >= hu2->netmask)))) { /* if no database name was passed, auth is ok */ if (hu1->resource == NULL || (hu1->resource && !strlen(hu1->resource))) { @@ -1806,6 +1890,10 @@ static void *uh_keydup(void* key) { return NULL; } + ss_dassert(strnlen(rval->hostname, MYSQL_HOST_MAXLEN + 1) <= MYSQL_HOST_MAXLEN); + strncpy(rval->hostname, current_key->hostname, MYSQL_HOST_MAXLEN); + rval->hostname[MYSQL_HOST_MAXLEN] = '\0'; + memcpy(&rval->ipv4, ¤t_key->ipv4, sizeof(struct sockaddr_in)); memcpy(&rval->netmask, ¤t_key->netmask, sizeof(int)); diff --git a/server/include/dbusers.h b/server/include/dbusers.h index ab7ff1638..17e5b97ef 100644 --- a/server/include/dbusers.h +++ b/server/include/dbusers.h @@ -62,6 +62,7 @@ typedef struct mysql_user_host_key { struct sockaddr_in ipv4; int netmask; char *resource; + char hostname[MYSQL_HOST_MAXLEN + 1]; } MYSQL_USER_HOST; extern int load_mysql_users(SERVICE *service); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index c2bec47da..553af4090 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1463,6 +1463,10 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, memcpy(&key.ipv4, client, sizeof(struct sockaddr_in)); key.netmask = 32; key.resource = client_data->db; + if(strlen(dcb->remote) < MYSQL_HOST_MAXLEN) + { + strcpy(key.hostname, dcb->remote); + } LOGIF(LD, (skygw_log_write_flush( From 6d1c069d412d14926b0ff769eec814bd6c75f708 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 11:05:01 +0200 Subject: [PATCH 082/179] A bitmask of logfiles is now only logged once. --- log_manager/log_manager.cc | 217 ++++++++++++++++++++----------------- 1 file changed, 115 insertions(+), 102 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index ca1785674..0c20773c4 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1377,46 +1377,15 @@ static int log_write(logfile_id_t id, const char* str, enum log_flush flush) { - int rv = 0; + int rv = -1; if (logmanager_register(true)) { CHK_LOGMANAGER(lm); - int attempts = 0; - int successes = 0; - - for (int i = LOGFILE_FIRST; i <= LOGFILE_LAST; i <<= 1) - { - /** - * If a particular log is enabled in general and it is enabled for - * the current session, log the stuff. - */ - if (LOG_IS_ENABLED(i) && ((i & id) != 0)) - { - ++attempts; - - if (logmanager_write_log((logfile_id_t)i, - flush, - prefix_len, - len, str) == 0) - { - ++successes; - } - } - } + rv = logmanager_write_log(id, flush, prefix_len, len, str); logmanager_unregister(); - - // Only if logging was attempted and nothing succeeded, it is considered a failure. - if ((attempts != 0) && (successes == 0)) - { - rv = -1; - } - } - else - { - rv = -1; } return rv; @@ -1433,37 +1402,75 @@ const char PREFIX_NOTICE[] = "[Notice]: "; const char PREFIX_INFO[] = "[Info] : "; const char PREFIX_DEBUG[] = "[Debug] : "; -static log_prefix_t logfile_to_prefix(logfile_id_t id) +/** + * Returns the most "severe" file id. + * + * @param ids A single id or a bitmask of ids. + * @return A single id + */ +static logfile_id_t logfile_ids_to_id(logfile_id_t ids) { - log_prefix_t prefix; - // The id can be a bitmask, hence we choose the most "severe" one. - if (id & LOGFILE_ERROR) + if (ids & LOGFILE_ERROR) { - prefix.text = PREFIX_ERROR; - prefix.len = sizeof(PREFIX_ERROR); + return LOGFILE_ERROR; } - else if (id & LOGFILE_MESSAGE) + else if (ids & LOGFILE_MESSAGE) { - prefix.text = PREFIX_NOTICE; - prefix.len = sizeof(PREFIX_NOTICE); + return LOGFILE_MESSAGE; } - else if (id & LOGFILE_TRACE) + else if (ids & LOGFILE_TRACE) { - prefix.text = PREFIX_INFO; - prefix.len = sizeof(PREFIX_INFO); + return LOGFILE_TRACE; } - else if (id & LOGFILE_DEBUG) + else if (ids & LOGFILE_DEBUG) { - prefix.text = PREFIX_DEBUG; - prefix.len = sizeof(PREFIX_DEBUG); + return LOGFILE_DEBUG; } else { assert(!true); + return LOGFILE_ERROR; + } +} +/** + * Returns the prefix to be used for a specific logfile id. + * + * @param id A logfile id (not a mask) + * @return The corresponding prefix. + */ +static log_prefix_t logfile_id_to_prefix(logfile_id_t id) +{ + log_prefix_t prefix; + + switch (id) + { + case LOGFILE_ERROR: prefix.text = PREFIX_ERROR; prefix.len = sizeof(PREFIX_ERROR); + break; + + case LOGFILE_MESSAGE: + prefix.text = PREFIX_NOTICE; + prefix.len = sizeof(PREFIX_NOTICE); + break; + + case LOGFILE_TRACE: + prefix.text = PREFIX_INFO; + prefix.len = sizeof(PREFIX_INFO); + break; + + case LOGFILE_DEBUG: + prefix.text = PREFIX_DEBUG; + prefix.len = sizeof(PREFIX_DEBUG); + break; + + default: + assert(!true); + prefix.text = PREFIX_ERROR; + prefix.len = sizeof(PREFIX_ERROR); + break; } --prefix.len; // Remove trailing NULL. @@ -1479,80 +1486,86 @@ int skygw_log_write_context(logfile_id_t id, const char* str, ...) { - int err = 0; - va_list valist; + int err = 0; - /** - * Find out the length of log string (to be formatted str). - */ - va_start(valist, str); - int message_len = vsnprintf(NULL, 0, str, valist); - va_end(valist); + id = logfile_ids_to_id(id); // Pick the most severe one. - if (message_len >= 0) + if (LOG_IS_ENABLED(id)) { - log_prefix_t prefix = logfile_to_prefix(id); + va_list valist; - static const char FORMAT_FUNCTION[] = "(%s): "; + /** + * Find out the length of log string (to be formatted str). + */ + va_start(valist, str); + int message_len = vsnprintf(NULL, 0, str, valist); + va_end(valist); - int augmentation_len = 0; - - switch (log_augmentation) + if (message_len >= 0) { - case LOG_AUGMENT_WITH_FUNCTION: - augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0 - augmentation_len -= 2; // Remove the %s - augmentation_len += strlen(function); - break; + log_prefix_t prefix = logfile_id_to_prefix(id); - default: - break; - } + static const char FORMAT_FUNCTION[] = "(%s): "; - int buffer_len = prefix.len + augmentation_len + message_len + 1; // Trailing NULL - - if (buffer_len > MAX_LOGSTRLEN) - { - message_len -= (buffer_len - MAX_LOGSTRLEN); - buffer_len = MAX_LOGSTRLEN; - - assert(prefix.len + augmentation_len + message_len + 1 == buffer_len); - } - - char buffer[buffer_len]; - - char *prefix_text = buffer; - char *augmentation_text = buffer + prefix.len; - char *message_text = buffer + prefix.len + augmentation_len; - - strcpy(prefix_text, prefix.text); - - if (augmentation_len) - { - int len = 0; + int augmentation_len = 0; switch (log_augmentation) { case LOG_AUGMENT_WITH_FUNCTION: - len = sprintf(augmentation_text, FORMAT_FUNCTION, function); + augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0 + augmentation_len -= 2; // Remove the %s + augmentation_len += strlen(function); break; default: - assert(!true); + break; } - assert(len == augmentation_len); - } + int buffer_len = prefix.len + augmentation_len + message_len + 1; // Trailing NULL - va_start(valist, str); - vsnprintf(message_text, message_len + 1, str, valist); - va_end(valist); + if (buffer_len > MAX_LOGSTRLEN) + { + message_len -= (buffer_len - MAX_LOGSTRLEN); + buffer_len = MAX_LOGSTRLEN; - err = log_write(id, file, line, function, prefix.len, buffer_len, buffer, flush); + assert(prefix.len + augmentation_len + message_len + 1 == buffer_len); + } - if (err != 0) - { - fprintf(stderr, "skygw_log_write failed.\n"); + char buffer[buffer_len]; + + char *prefix_text = buffer; + char *augmentation_text = buffer + prefix.len; + char *message_text = buffer + prefix.len + augmentation_len; + + strcpy(prefix_text, prefix.text); + + if (augmentation_len) + { + int len = 0; + + switch (log_augmentation) + { + case LOG_AUGMENT_WITH_FUNCTION: + len = sprintf(augmentation_text, FORMAT_FUNCTION, function); + break; + + default: + assert(!true); + } + + assert(len == augmentation_len); + } + + va_start(valist, str); + vsnprintf(message_text, message_len + 1, str, valist); + va_end(valist); + + err = log_write(id, file, line, function, prefix.len, buffer_len, buffer, flush); + + if (err != 0) + { + fprintf(stderr, "skygw_log_write failed.\n"); + } } } From 18c53bebf19146ff854df1836e90790ad08508ab Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 28 Oct 2015 15:23:43 +0200 Subject: [PATCH 083/179] Fix to MXS-430: https://mariadb.atlassian.net/browse/MXS-430 Added caching of the hashtables used to map databases to servers. --- server/modules/include/schemarouter.h | 25 +- .../routing/schemarouter/schemarouter.c | 486 +++++++++++++----- 2 files changed, 382 insertions(+), 129 deletions(-) diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index 16fb8640b..b988df8bd 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -56,6 +56,26 @@ typedef enum showdb_response SHOWDB_DUPLICATE_DATABASES, SHOWDB_FATAL_ERROR } showdb_response_t; + +enum shard_map_state +{ + SHMAP_UNINIT, /*< No databases have been added to this shard map */ + SHMAP_READY, /*< All available databases have been added */ + SHMAP_STALE /*< The shard map has old data or has not been updated recently */ +}; + +/** + * A map of the shards tied to a single user. + */ +typedef struct shard_map +{ + HASHTABLE *hash; /*< A hashtable of database names and the servers which + * have these databases. */ + SPINLOCK lock; + time_t last_updated; + enum shard_map_state state; /*< State of the shard map */ +}shard_map_t; + /** * The state of the backend server reference */ @@ -274,6 +294,8 @@ typedef struct { double ses_longest; /*< Longest session */ double ses_shortest; /*< Shortest session */ double ses_average; /*< Average session length */ + int shmap_cache_hit; /*< Shard map was found from the cache */ + int shmap_cache_miss;/*< No shard map found from the cache */ } ROUTER_STATS; /** @@ -299,7 +321,7 @@ struct router_client_session { bool rses_transaction_active; /*< Is a transaction active */ struct router_instance *router; /*< The router instance */ struct router_client_session* next; /*< List of router sessions */ - HASHTABLE* dbhash; /*< Database hash containing names of the databases mapped to the servers that contain them */ + shard_map_t* shardmap; /*< Database hash containing names of the databases mapped to the servers that contain them */ char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */ init_mask_t init; /*< Initialization state bitmask */ GWBUF* queue; /*< Query that was received before the session was ready */ @@ -318,6 +340,7 @@ struct router_client_session { * The per instance data for the router. */ typedef struct router_instance { + HASHTABLE* shard_maps; /*< Shard maps hashed by user name */ SERVICE* service; /*< Pointer to service */ ROUTER_CLIENT_SES* connections; /*< List of client connections */ SPINLOCK lock; /*< Lock for the instance data */ diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 22330c24d..d2e076254 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -41,6 +41,9 @@ /** Size of the hashtable used to store ignored databases */ #define SCHEMAROUTER_HASHSIZE 100 +/** Hashtable size for the per user shard maps */ +#define SCHEMAROUTER_USERHASH_SIZE 10 + MODULE_INFO info = { MODULE_API_ROUTER, MODULE_BETA_RELEASE, @@ -223,6 +226,7 @@ int inspect_backend_mapping_states(ROUTER_CLIENT_SES *router_cli_ses, GWBUF** wbuf); bool handle_default_db(ROUTER_CLIENT_SES *router_cli_ses); void route_queued_query(ROUTER_CLIENT_SES *router_cli_ses); +void synchronize_shard_map(ROUTER_CLIENT_SES *client); static int hashkeyfun(void* key) { if(key == NULL){ @@ -247,7 +251,39 @@ static int hashcmpfun( return strcmp(i1,i2); } +void* keyfreefun(void* data) +{ + free(data); + return NULL; +} +/** + * Allocate a shard map and initialize it. + * @return Pointer to new shard_map_t or NULL if memory allocation failed + */ +shard_map_t* create_shard_map() +{ + shard_map_t *rval; + + if ((rval = (shard_map_t*) malloc(sizeof(shard_map_t)))) + { + if ((rval->hash = hashtable_alloc(SCHEMAROUTER_HASHSIZE, hashkeyfun, hashcmpfun))) + { + HASHMEMORYFN kcopy = (HASHMEMORYFN)strdup; + HASHMEMORYFN kfree = (HASHMEMORYFN)keyfreefun; + hashtable_memory_fns(rval->hash, kcopy, NULL, kfree, NULL); + spinlock_init(&rval->lock); + rval->last_updated = 0; + rval->state = SHMAP_UNINIT; + } + else + { + free(rval); + rval = NULL; + } + } + return rval; +} /** * Convert a length encoded string into a C string. @@ -363,6 +399,7 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* ptr += gw_mysql_get_byte3(ptr) + 4; } + spinlock_acquire(&rses->shardmap->lock); while (ptr < (unsigned char*) buf->end && !PTR_IS_EOF(ptr)) { int payloadlen = gw_mysql_get_byte3(ptr); @@ -371,7 +408,7 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* if (data) { - if (hashtable_add(rses->dbhash, data, target)) + if (hashtable_add(rses->shardmap->hash, data, target)) { skygw_log_write(LOGFILE_TRACE, "schemarouter: <%s, %s>", target, data); } @@ -385,7 +422,7 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* { duplicate_found = true; skygw_log_write(LE, "Error: Database '%s' found on servers '%s' and '%s' for user %s@%s.", - data, target, hashtable_fetch(rses->dbhash, data), + data, target, hashtable_fetch(rses->shardmap->hash, data), rses->rses_client_dcb->user, rses->rses_client_dcb->remote); } @@ -394,6 +431,7 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* } ptr += packetlen; } + spinlock_release(&rses->shardmap->lock); if (ptr < (unsigned char*) buf->end && PTR_IS_EOF(ptr) && bref->n_mapping_eof == 1) @@ -478,8 +516,8 @@ int gen_databaselist(ROUTER_INSTANCE* inst, ROUTER_CLIENT_SES* session) * @param buffer Query to inspect * @return Name of the backend or NULL if the query contains no known databases. */ -char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF* buffer,skygw_query_type_t qtype){ - HASHTABLE* ht = client->dbhash; +char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, GWBUF* buffer,skygw_query_type_t qtype) +{ int sz = 0,i,j; char** dbnms = NULL; char* rval = NULL,*query, *tmp = NULL; @@ -491,6 +529,9 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, dbnms = skygw_get_database_names(buffer,&sz); + spinlock_acquire(&client->shardmap->lock); + HASHTABLE* ht = client->shardmap->hash; + if(sz > 0){ for(i = 0; i < sz; i++){ char* name; @@ -553,6 +594,7 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, } + spinlock_release(&client->shardmap->lock); return rval; } @@ -584,7 +626,8 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->rses_mysql_session->db); } } - + + spinlock_release(&client->shardmap->lock); return rval; } @@ -765,6 +808,17 @@ createInstance(SERVICE *service, char **options) (HASHMEMORYFN)free, NULL); + if ((router->shard_maps = hashtable_alloc(SCHEMAROUTER_USERHASH_SIZE, hashkeyfun, hashcmpfun)) == NULL) + { + skygw_log_write(LE, "Error: Memory allocation failed when allocating schemarouter database ignore list."); + hashtable_free(router->ignored_dbs); + free(router); + return NULL; + } + + hashtable_memory_fns(router->shard_maps,(HASHMEMORYFN)strdup, + NULL, (HASHMEMORYFN)keyfreefun, NULL); + /** Add default system databases to ignore */ hashtable_add(router->ignored_dbs,"mysql",""); hashtable_add(router->ignored_dbs,"information_schema",""); @@ -1007,7 +1061,7 @@ static void* newSession( memset(db,0,MYSQL_DATABASE_MAXLEN+1); - spinlock_acquire(&protocol->protocol_lock); + spinlock_acquire(&session->ses_lock); /* To enable connecting directly to a sharded database we first need * to disable it for the client DCB's protocol so that we can connect to them*/ @@ -1028,7 +1082,7 @@ static void* newSession( LOGIF(LT,(skygw_log_write(LT,"schemarouter: Client'%s' connecting with empty database.",data->user))); } - spinlock_release(&protocol->protocol_lock); + spinlock_release(&session->ses_lock); client_rses = (ROUTER_CLIENT_SES *)calloc(1, sizeof(ROUTER_CLIENT_SES)); @@ -1045,7 +1099,44 @@ static void* newSession( client_rses->router = router; client_rses->rses_mysql_session = (MYSQL_session*)session->data; client_rses->rses_client_dcb = (DCB*)session->client; - + + spinlock_acquire(&router->lock); + + shard_map_t *map = hashtable_fetch(router->shard_maps, session->client->user); + enum shard_map_state state; + + if (map) + { + spinlock_acquire(&map->lock); + double tdiff = difftime(time(NULL), map->last_updated); + if (tdiff > router->schemarouter_config.refresh_min_interval) + { + map->state = SHMAP_STALE; + } + state = map->state; + spinlock_release(&map->lock); + } + + spinlock_release(&router->lock); + + if (map == NULL || state != SHMAP_READY) + { + if ((map = create_shard_map()) == NULL) + { + skygw_log_write(LE, "Error: Failed to allocate enough memory to create" + "new shard mapping. Session will be closed."); + free(client_rses); + return NULL; + } + client_rses->init = INIT_UNINT; + } + else + { + client_rses->init = INIT_READY; + atomic_add(&router->stats.shmap_cache_hit, 1); + } + + client_rses->shardmap = map; client_rses->dcb_reply = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); client_rses->dcb_reply->func.read = internalReply; client_rses->dcb_reply->state = DCB_STATE_POLLING; @@ -1057,7 +1148,7 @@ static void* newSession( client_rses->dcb_route->state = DCB_STATE_POLLING; client_rses->dcb_route->session = session; client_rses->rses_config.last_refresh = time(NULL); - client_rses->init = INIT_UNINT; + if(using_db) client_rses->init |= INIT_USE_DB; /** @@ -1131,12 +1222,6 @@ static void* newSession( router_nservers, session, router); - - client_rses->dbhash = hashtable_alloc(SCHEMAROUTER_HASHSIZE, hashkeyfun, hashcmpfun); - hashtable_memory_fns(client_rses->dbhash,(HASHMEMORYFN)strdup, - (HASHMEMORYFN)strdup, - (HASHMEMORYFN)free, - (HASHMEMORYFN)free); rses_end_locked_router_action(client_rses); @@ -1366,7 +1451,6 @@ static void freeSession( * all the memory and other resources associated * to the client session. */ - hashtable_free(router_cli_ses->dbhash); free(router_cli_ses->rses_backend_ref); free(router_cli_ses); return; @@ -1744,8 +1828,6 @@ GWBUF* gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client) { GWBUF* rval = NULL; - HASHTABLE* ht = client->dbhash; - HASHITERATOR* iter = hashtable_iterator(ht); backend_ref_t *bref = client->rses_backend_ref; BACKEND** backends = router->servers; unsigned int coldef_len = 0; @@ -1845,44 +1927,55 @@ gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client) int j = 0,ndbs = 0, bufsz = 10; char** dbs; - if((dbs = malloc(sizeof(char*)*bufsz)) == NULL) + if((dbs = malloc(sizeof(char*) * bufsz)) == NULL) { gwbuf_free(rval); - hashtable_iterator_free(iter); return NULL; } - while((value = (char*) hashtable_next(iter))) + spinlock_acquire(&client->shardmap->lock); + + if(client->shardmap->state == SHMAP_READY) { - char* bend = hashtable_fetch(ht, value); + HASHTABLE* ht = client->shardmap->hash; + HASHITERATOR* iter = hashtable_iterator(ht); - for(i = 0; backends[i]; i++) + while((value = (char*) hashtable_next(iter))) { - if(strcmp(bref[i].bref_backend->backend_server->unique_name, bend) == 0 && - BREF_IS_IN_USE(&bref[i]) && !BREF_IS_CLOSED(&bref[i])) + char* bend = hashtable_fetch(ht, value); + for(i = 0; backends[i]; i++) { - ndbs++; - - if(ndbs >= bufsz) - { - bufsz += bufsz / 2; - char** tmp = realloc(dbs,sizeof(char*)*bufsz); - if(tmp == NULL) - { - gwbuf_free(rval); - hashtable_iterator_free(iter); - for(i=0;ibackend_server->unique_name, bend) == 0 && + BREF_IS_IN_USE(&bref[i]) && !BREF_IS_CLOSED(&bref[i])) + { + ndbs++; + if(ndbs >= bufsz) + { + bufsz += bufsz / 2; + char** tmp = realloc(dbs,sizeof(char*) * bufsz); + if(tmp == NULL) + { + gwbuf_free(rval); + hashtable_iterator_free(iter); + for (i = 0; i < ndbs - 1; i++) + { + free(dbs[i]); + } + free(dbs); + spinlock_release(&client->shardmap->lock); + return NULL; + } + dbs = tmp; + } + dbs[j++] = strdup(value); + } } } + hashtable_iterator_free(iter); } + spinlock_release(&client->shardmap->lock); + qsort(&dbs[0],(size_t)ndbs,sizeof(char*),cmpfn); for(j = 0;jstart, eof, sizeof(eof)); rval = gwbuf_append(rval, last_packet); - - rval = gwbuf_make_contiguous(rval); - hashtable_iterator_free(iter); free(dbs); return rval; } @@ -1987,9 +2077,15 @@ static int routeQuery( } - if(router_cli_ses->init & INIT_MAPPING) + /** + * If the databases are still being mapped or if the client connected + * with a default database but no database mapping was performed we need + * to store the query. Once the databases have been mapped and/or the + * default database is taken into use we can send the query forward. + */ + if(router_cli_ses->init & (INIT_MAPPING|INIT_USE_DB)) { - + int init_rval = 1; char* querystr = modutil_get_SQL(querybuf); skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"schemarouter: Storing query for session %p: %s", router_cli_ses->rses_client_dcb->session, @@ -2012,14 +2108,26 @@ static int routeQuery( ptr->next = querybuf; } + + if(router_cli_ses->init == (INIT_READY|INIT_USE_DB)) + { + /** + * This state is possible if a client connects with a default database + * and the shard map was found from the router cache + */ + if (!handle_default_db(router_cli_ses)) + { + init_rval = 0; + } + } rses_end_locked_router_action(router_cli_ses); - return 1; + return init_rval; } } rses_end_locked_router_action(router_cli_ses); - + packet = GWBUF_DATA(querybuf); packet_type = packet[4]; @@ -2139,9 +2247,12 @@ static int routeQuery( if (packet_type == MYSQL_COM_INIT_DB || op == QUERY_OP_CHANGE_DB) { - if (!(change_successful = change_current_db(router_cli_ses->rses_mysql_session, - router_cli_ses->dbhash, - querybuf))) + spinlock_acquire(&router_cli_ses->shardmap->lock); + change_successful = change_current_db(router_cli_ses->rses_mysql_session, + router_cli_ses->shardmap->hash, + querybuf); + spinlock_release(&router_cli_ses->shardmap->lock); + if (!change_successful) { time_t now = time(NULL); if(router_cli_ses->rses_config.refresh_databases && @@ -2149,22 +2260,21 @@ static int routeQuery( router_cli_ses->rses_config.refresh_min_interval) { rses_begin_locked_router_action(router_cli_ses); + router_cli_ses->rses_config.last_refresh = now; router_cli_ses->queue = querybuf; - hashtable_free(router_cli_ses->dbhash); - if((router_cli_ses->dbhash = hashtable_alloc(SCHEMAROUTER_HASHSIZE, hashkeyfun, hashcmpfun)) == NULL) - { - skygw_log_write(LE,"Error: Hashtable allocation failed."); - rses_end_locked_router_action(router_cli_ses); - return 1; - } - hashtable_memory_fns(router_cli_ses->dbhash,(HASHMEMORYFN)strdup, - (HASHMEMORYFN)strdup, - (HASHMEMORYFN)free, - (HASHMEMORYFN)free); - gen_databaselist(inst,router_cli_ses); + int rc_refresh = 1; + + if((router_cli_ses->shardmap = create_shard_map())) + { + gen_databaselist(inst,router_cli_ses); + } + else + { + rc_refresh = 0; + } rses_end_locked_router_action(router_cli_ses); - return 1; + return rc_refresh; } extract_database(querybuf,db); snprintf(errbuf,25+MYSQL_DATABASE_MAXLEN,"Unknown database: %s",db); @@ -2207,8 +2317,11 @@ static int routeQuery( op == QUERY_OP_CHANGE_DB) { route_target = TARGET_UNDEFINED; - tname = hashtable_fetch(router_cli_ses->dbhash,router_cli_ses->rses_mysql_session->db); - + + spinlock_acquire(&router_cli_ses->shardmap->lock); + tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->rses_mysql_session->db); + spinlock_release(&router_cli_ses->shardmap->lock); + if(tname) { skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB for database '%s' on server '%s'", @@ -2556,6 +2669,8 @@ diagnostic(ROUTER *instance, DCB *dcb) dcb_printf(dcb,"Shortest session: %.2lf seconds\n",router->stats.ses_shortest); dcb_printf(dcb,"Average session length: %.2lf seconds\n",router->stats.ses_average); } + dcb_printf(dcb,"Shard map cache hits: %d\n",router->stats.shmap_cache_hit); + dcb_printf(dcb,"Shard map cache misses: %d\n",router->stats.shmap_cache_miss); dcb_printf(dcb,"\n"); } @@ -2633,6 +2748,21 @@ static void clientReply(ROUTER* instance, if (rc == 1) { + spinlock_acquire(&router_cli_ses->shardmap->lock); + + router_cli_ses->shardmap->state = SHMAP_READY; + router_cli_ses->shardmap->last_updated = time(NULL); + spinlock_release(&router_cli_ses->shardmap->lock); + + rses_end_locked_router_action(router_cli_ses); + + synchronize_shard_map(router_cli_ses); + + if (!rses_begin_locked_router_action(router_cli_ses)) + { + return; + } + /* * Check if the session is reconnecting with a database name * that is not in the hashtable. If the database is not found @@ -2653,6 +2783,7 @@ static void clientReply(ROUTER* instance, if (router_cli_ses->queue) { + ss_dassert(router_cli_ses->init == INIT_READY); route_queued_query(router_cli_ses); } skygw_log_write_flush(LOGFILE_DEBUG, @@ -2669,11 +2800,6 @@ static void clientReply(ROUTER* instance, return; } - if (router_cli_ses->queue) - { - route_queued_query(router_cli_ses); - } - if (router_cli_ses->init & INIT_USE_DB) { skygw_log_write(LOGFILE_DEBUG, "schemarouter: Reply to USE '%s' received for session %p", @@ -2682,6 +2808,12 @@ static void clientReply(ROUTER* instance, router_cli_ses->init &= ~INIT_USE_DB; strcpy(router_cli_ses->rses_mysql_session->db, router_cli_ses->connect_db); ss_dassert(router_cli_ses->init == INIT_READY); + + if (router_cli_ses->queue) + { + route_queued_query(router_cli_ses); + } + rses_end_locked_router_action(router_cli_ses); if (writebuf) { @@ -2690,6 +2822,14 @@ static void clientReply(ROUTER* instance, return; } + if (router_cli_ses->queue) + { + ss_dassert(router_cli_ses->init == INIT_READY); + route_queued_query(router_cli_ses); + rses_end_locked_router_action(router_cli_ses); + return; + } + CHK_BACKEND_REF(bref); scur = &bref->bref_sescmd_cur; /** @@ -4447,7 +4587,7 @@ RESULT_ROW* shard_list_cb(struct resultset* rset, void* data) RESULT_ROW* rval = NULL; if((key = hashtable_next(sl->iter)) && - (value = hashtable_fetch(sl->rses->dbhash,key))) + (value = hashtable_fetch(sl->rses->shardmap->hash,key))) { if((rval = resultset_make_row(sl->rset))) { @@ -4465,23 +4605,32 @@ RESULT_ROW* shard_list_cb(struct resultset* rset, void* data) */ int process_show_shards(ROUTER_CLIENT_SES* rses) { - HASHITERATOR* iter = hashtable_iterator(rses->dbhash); - struct shard_list sl; + int rval = 0; - sl.iter = iter; - sl.rses = rses; - if((sl.rset = resultset_create(shard_list_cb,&sl)) == NULL) + spinlock_acquire(&rses->shardmap->lock); + if(rses->shardmap->state == SHMAP_READY) { - skygw_log_write(LE,"[%s] Error: Failed to create resultset.",__FUNCTION__); - return -1; - } + HASHITERATOR* iter = hashtable_iterator(rses->shardmap->hash); + struct shard_list sl; - resultset_add_column(sl.rset,"Database",MYSQL_DATABASE_MAXLEN,COL_TYPE_VARCHAR); - resultset_add_column(sl.rset,"Server",MYSQL_DATABASE_MAXLEN,COL_TYPE_VARCHAR); - resultset_stream_mysql(sl.rset,rses->rses_client_dcb); - resultset_free(sl.rset); - hashtable_iterator_free(iter); - return 0; + sl.iter = iter; + sl.rses = rses; + if ((sl.rset = resultset_create(shard_list_cb, &sl)) == NULL) + { + skygw_log_write(LE, "[%s] Error: Failed to create resultset.", __FUNCTION__); + rval = -1; + } + else + { + resultset_add_column(sl.rset, "Database", MYSQL_DATABASE_MAXLEN, COL_TYPE_VARCHAR); + resultset_add_column(sl.rset, "Server", MYSQL_DATABASE_MAXLEN, COL_TYPE_VARCHAR); + resultset_stream_mysql(sl.rset, rses->rses_client_dcb); + resultset_free(sl.rset); + hashtable_iterator_free(iter); + } + } + spinlock_release(&rses->shardmap->lock); + return rval; } /** @@ -4514,10 +4663,53 @@ void write_error_to_client(DCB* dcb, int errnum, const char* mysqlstate, const c */ bool handle_default_db(ROUTER_CLIENT_SES *router_cli_ses) { - char* target; + bool rval = false; + char* target = NULL; - if ((target = hashtable_fetch(router_cli_ses->dbhash, - router_cli_ses->connect_db)) == NULL) + spinlock_acquire(&router_cli_ses->shardmap->lock); + if(router_cli_ses->shardmap->state == SHMAP_READY) + { + target = hashtable_fetch(router_cli_ses->shardmap->hash, router_cli_ses->connect_db); + } + spinlock_release(&router_cli_ses->shardmap->lock); + + if (target) + { + /* Send a COM_INIT_DB packet to the server with the right database + * and set it as the client's active database */ + + unsigned int qlen = strlen(router_cli_ses->connect_db); + GWBUF* buffer = gwbuf_alloc(qlen + 5); + + if (buffer) + { + gw_mysql_set_byte3((unsigned char*) buffer->start, qlen + 1); + gwbuf_set_type(buffer, GWBUF_TYPE_MYSQL); + *((unsigned char*) buffer->start + 3) = 0x0; + *((unsigned char*) buffer->start + 4) = 0x2; + memcpy(buffer->start + 5, router_cli_ses->connect_db, qlen); + DCB* dcb = NULL; + + if (get_shard_dcb(&dcb, router_cli_ses, target)) + { + dcb->func.write(dcb, buffer); + skygw_log_write(LOGFILE_DEBUG, "schemarouter: USE '%s' sent to %s for session %p", + router_cli_ses->connect_db, + target, + router_cli_ses->rses_client_dcb->session); + rval = true; + } + else + { + skygw_log_write_flush(LOGFILE_TRACE, "schemarouter: Couldn't find target DCB for '%s'.", target); + } + } + else + { + skygw_log_write_flush(LOGFILE_ERROR, "Error : Buffer allocation failed."); + } + } + else { /** Unknown database, hang up on the client*/ skygw_log_write_flush(LOGFILE_TRACE, "schemarouter: Connecting to a non-existent database '%s'", @@ -4526,50 +4718,16 @@ bool handle_default_db(ROUTER_CLIENT_SES *router_cli_ses) sprintf(errmsg, "Unknown database '%s'", router_cli_ses->connect_db); if (router_cli_ses->rses_config.debug) { - sprintf(errmsg + strlen(errmsg), " ([%lu]: DB not found on connect)", router_cli_ses->rses_client_dcb->session->ses_id); + sprintf(errmsg + strlen(errmsg), " ([%lu]: DB not found on connect)", + router_cli_ses->rses_client_dcb->session->ses_id); } write_error_to_client(router_cli_ses->rses_client_dcb, SCHEMA_ERR_DBNOTFOUND, SCHEMA_ERRSTR_DBNOTFOUND, errmsg); - return false; } - /* Send a COM_INIT_DB packet to the server with the right database - * and set it as the client's active database */ - - unsigned int qlen; - GWBUF* buffer; - - qlen = strlen(router_cli_ses->connect_db); - buffer = gwbuf_alloc(qlen + 5); - if (buffer == NULL) - { - skygw_log_write_flush(LOGFILE_ERROR, "Error : Buffer allocation failed."); - return false; - } - - gw_mysql_set_byte3((unsigned char*) buffer->start, qlen + 1); - gwbuf_set_type(buffer, GWBUF_TYPE_MYSQL); - *((unsigned char*) buffer->start + 3) = 0x0; - *((unsigned char*) buffer->start + 4) = 0x2; - memcpy(buffer->start + 5, router_cli_ses->connect_db, qlen); - DCB* dcb = NULL; - - if (get_shard_dcb(&dcb, router_cli_ses, target)) - { - dcb->func.write(dcb, buffer); - skygw_log_write(LOGFILE_DEBUG, "schemarouter: USE '%s' sent to %s for session %p", - router_cli_ses->connect_db, - target, - router_cli_ses->rses_client_dcb->session); - } - else - { - skygw_log_write_flush(LOGFILE_TRACE, "schemarouter: Couldn't find target DCB for '%s'.", target); - return false; - } - return true; + return rval; } void route_queued_query(ROUTER_CLIENT_SES *router_cli_ses) @@ -4684,3 +4842,75 @@ int inspect_backend_mapping_states(ROUTER_CLIENT_SES *router_cli_ses, *wbuf = writebuf; return mapped ? 1 : 0; } + +/** + * Replace a shard map with another one. This function copies the contents of + * the source shard map to the target and frees the source memory. + * @param target Target shard map to replace + * @param source Source shard map to use + */ +void replace_shard_map(shard_map_t **target, shard_map_t **source) +{ + shard_map_t *tgt = *target; + shard_map_t *src = *source; + tgt->last_updated = src->last_updated; + tgt->state = src->state; + hashtable_free(tgt->hash); + tgt->hash = src->hash; + free(src); + *source = NULL; +} + +/** + * Synchronize the router client session shard map with the global shard map for + * this user. + * + * If the router doesn't have a shard map for this user then the current shard map + * of the client session is added to the router. If the shard map in the router is + * out of date, its contents are replaced with the contents of the current client + * session. If the router has a usable shard map, the current shard map of the client + * is discarded and the router's shard map is used. + * @param client Router session + */ +void synchronize_shard_map(ROUTER_CLIENT_SES *client) +{ + spinlock_acquire(&client->router->lock); + + client->router->stats.shmap_cache_miss++; + + shard_map_t *map = hashtable_fetch(client->router->shard_maps, + client->rses_client_dcb->user); + if (map) + { + spinlock_acquire(&map->lock); + if (map->state == SHMAP_STALE) + { + replace_shard_map(&map, &client->shardmap); + } + else if (map->state != SHMAP_READY) + { + skygw_log_write(LE, "Warning: Shard map state is not ready but" + "it is in use. Replacing it with a newer one."); + replace_shard_map(&map, &client->shardmap); + } + else + { + /** + * Another thread has already updated the shard map for this user + */ + hashtable_free(client->shardmap->hash); + free(client->shardmap); + } + spinlock_release(&map->lock); + client->shardmap = map; + } + else + { + hashtable_add(client->router->shard_maps, + client->rses_client_dcb->user, + client->shardmap); + ss_dassert(hashtable_fetch(client->router->shard_maps, + client->rses_client_dcb->user) == client->shardmap); + } + spinlock_release(&client->router->lock); +} From d5c38b93f6a57bc58bf038dcc744bd4cd8511b76 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 29 Oct 2015 20:24:26 +0200 Subject: [PATCH 084/179] Fix to MXS-431: https://mariadb.atlassian.net/browse/MXS-431 Replaced the use of the shared MySQLSession structure with an internal variable that tracks the currently active database. --- server/modules/include/schemarouter.h | 1 + server/modules/include/sharding_common.h | 4 +- server/modules/include/shardrouter.h | 1 + .../routing/schemarouter/schemarouter.c | 48 +++++++------------ .../routing/schemarouter/sharding_common.c | 10 ++-- .../routing/schemarouter/shardrouter.c | 19 +------- 6 files changed, 27 insertions(+), 56 deletions(-) diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index b988df8bd..d583dd5c3 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -323,6 +323,7 @@ struct router_client_session { struct router_client_session* next; /*< List of router sessions */ shard_map_t* shardmap; /*< Database hash containing names of the databases mapped to the servers that contain them */ char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */ + char current_db[MYSQL_DATABASE_MAXLEN + 1]; /*< Current active database */ init_mask_t init; /*< Initialization state bitmask */ GWBUF* queue; /*< Query that was received before the session was ready */ DCB* dcb_route; /*< Internal DCB used to trigger re-routing of buffers */ diff --git a/server/modules/include/sharding_common.h b/server/modules/include/sharding_common.h index dd30a74ea..b0d917f0a 100644 --- a/server/modules/include/sharding_common.h +++ b/server/modules/include/sharding_common.h @@ -12,8 +12,6 @@ bool extract_database(GWBUF* buf, char* str); void create_error_reply(char* fail_str,DCB* dcb); -bool change_current_db(MYSQL_session* mysql_session, - HASHTABLE* dbhash, - GWBUF* buf); +bool change_current_db(char* dest, HASHTABLE* dbhash, GWBUF* buf); #endif diff --git a/server/modules/include/shardrouter.h b/server/modules/include/shardrouter.h index 63572671e..3fc70fcc1 100644 --- a/server/modules/include/shardrouter.h +++ b/server/modules/include/shardrouter.h @@ -204,6 +204,7 @@ struct router_client_session { SESSION* session; GWBUF* queue; char connect_db[MYSQL_DATABASE_MAXLEN+1]; /*< Database the user was trying to connect to */ + char current_db[MYSQL_DATABASE_MAXLEN + 1]; /*< Current active database */ shard_init_mask_t init; /*< Initialization state bitmask */ #if defined(SS_DEBUG) skygw_chk_t rses_chk_tail; diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index d2e076254..e7e378021 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -583,9 +583,9 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, if(tmp == NULL) { - rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db); + rval = (char*) hashtable_fetch(ht, client->current_db); skygw_log_write(LOGFILE_TRACE,"schemarouter: SHOW TABLES query, current database '%s' on server '%s'", - client->rses_mysql_session->db,rval); + client->current_db,rval); } else { @@ -613,17 +613,17 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, } } - if(rval == NULL && !has_dbs && client->rses_mysql_session->db[0] != '\0') + if(rval == NULL && !has_dbs && client->current_db[0] != '\0') { /** * If the target name has not been found and the session has an * active database, set is as the target */ - rval = (char*) hashtable_fetch(ht, client->rses_mysql_session->db); + rval = (char*) hashtable_fetch(ht, client->current_db); if(rval) { - skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->rses_mysql_session->db); + skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->current_db); } } @@ -1585,7 +1585,7 @@ ROUTER* instance, rses_property_t* rses_prop_tmp; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - dbname = router_cli_ses->rses_mysql_session->db; + dbname = router_cli_ses->current_db; if (is_drop_table_query(querybuf)) { @@ -1643,7 +1643,7 @@ ROUTER* instance, rses_property_t* rses_prop_tmp; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - dbname = router_cli_ses->rses_mysql_session->db; + dbname = router_cli_ses->current_db; if (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) || QUERY_IS_TYPE(qtype, QUERY_TYPE_LOCAL_READ) || @@ -1722,7 +1722,7 @@ void check_create_tmp_table( HASHTABLE* h; rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES]; - dbname = router_cli_ses->rses_mysql_session->db; + dbname = router_cli_ses->current_db; if (QUERY_IS_TYPE(type, QUERY_TYPE_CREATE_TMP_TABLE)) @@ -2248,7 +2248,7 @@ static int routeQuery( op == QUERY_OP_CHANGE_DB) { spinlock_acquire(&router_cli_ses->shardmap->lock); - change_successful = change_current_db(router_cli_ses->rses_mysql_session, + change_successful = change_current_db(router_cli_ses->current_db, router_cli_ses->shardmap->hash, querybuf); spinlock_release(&router_cli_ses->shardmap->lock); @@ -2259,6 +2259,10 @@ static int routeQuery( difftime(now,router_cli_ses->rses_config.last_refresh) > router_cli_ses->rses_config.refresh_min_interval) { + spinlock_acquire(&router_cli_ses->shardmap->lock); + router_cli_ses->shardmap->state = SHMAP_STALE; + spinlock_release(&router_cli_ses->shardmap->lock); + rses_begin_locked_router_action(router_cli_ses); router_cli_ses->rses_config.last_refresh = now; @@ -2319,13 +2323,13 @@ static int routeQuery( route_target = TARGET_UNDEFINED; spinlock_acquire(&router_cli_ses->shardmap->lock); - tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->rses_mysql_session->db); + tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->current_db); spinlock_release(&router_cli_ses->shardmap->lock); if(tname) { skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB for database '%s' on server '%s'", - router_cli_ses->rses_mysql_session->db,tname); + router_cli_ses->current_db,tname); route_target = TARGET_NAMED_SERVER; } else @@ -2361,9 +2365,9 @@ static int routeQuery( if( (tname == NULL && packet_type != MYSQL_COM_INIT_DB && - router_cli_ses->rses_mysql_session->db[0] == '\0') || + router_cli_ses->current_db[0] == '\0') || packet_type == MYSQL_COM_FIELD_LIST || - (router_cli_ses->rses_mysql_session->db[0] != '\0')) + (router_cli_ses->current_db[0] != '\0')) { /** * No current database and no databases in query or @@ -2806,7 +2810,7 @@ static void clientReply(ROUTER* instance, router_cli_ses->connect_db, router_cli_ses->rses_client_dcb->session); router_cli_ses->init &= ~INIT_USE_DB; - strcpy(router_cli_ses->rses_mysql_session->db, router_cli_ses->connect_db); + strcpy(router_cli_ses->current_db, router_cli_ses->connect_db); ss_dassert(router_cli_ses->init == INIT_READY); if (router_cli_ses->queue) @@ -3728,22 +3732,6 @@ static bool execute_sescmd_in_backend( sescmd_cursor_clone_querybuf(scur)); break; - case MYSQL_COM_INIT_DB: - { - /** - * Record database name and store to session. - */ - GWBUF* tmpbuf; - MYSQL_session* data; - unsigned int qlen; - - data = dcb->session->data; - tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf; - qlen = MYSQL_GET_PACKET_LEN((unsigned char*)tmpbuf->start); - memset(data->db,0,MYSQL_DATABASE_MAXLEN+1); - strncpy(data->db,tmpbuf->start+5,qlen - 1); - } - /** Fallthrough */ case MYSQL_COM_QUERY: default: /** diff --git a/server/modules/routing/schemarouter/sharding_common.c b/server/modules/routing/schemarouter/sharding_common.c index cf6bf2c12..067edae3f 100644 --- a/server/modules/routing/schemarouter/sharding_common.c +++ b/server/modules/routing/schemarouter/sharding_common.c @@ -100,17 +100,17 @@ void create_error_reply(char* fail_str,DCB* dcb) } /** - * Read new database name from MYSQL_COM_INIT_DB packet or a literal USE ... COM_QUERY packet, check that it exists - * in the hashtable and copy its name to MYSQL_session. + * Read new database name from MYSQL_COM_INIT_DB packet or a literal USE ... COM_QUERY + * packet, check that it exists in the hashtable and copy its name to MYSQL_session. * - * @param mysql_session The MySQL session structure + * @param dest Destination where the database name will be written * @param dbhash Hashtable containing valid databases * @param buf Buffer containing the database change query * * @return true if new database is set, false if non-existent database was tried * to be set */ -bool change_current_db(MYSQL_session* mysql_session, +bool change_current_db(char* dest, HASHTABLE* dbhash, GWBUF* buf) { @@ -139,7 +139,7 @@ bool change_current_db(MYSQL_session* mysql_session, } else { - strncpy(mysql_session->db,db,MYSQL_DATABASE_MAXLEN); + strncpy(dest,db,MYSQL_DATABASE_MAXLEN); skygw_log_write(LOGFILE_TRACE,"change_current_db: database is on server: '%s'.",target); succp = true; goto retblock; diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 9efcd20e9..a9b033962 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -1698,7 +1698,7 @@ routeQuery(ROUTER* instance, if(packet_type == MYSQL_COM_INIT_DB) { - if(!(change_successful = change_current_db(router_cli_ses->rses_mysql_session, + if(!(change_successful = change_current_db(router_cli_ses->current_db, router_cli_ses->dbhash, querybuf))) { @@ -2471,23 +2471,6 @@ execute_sescmd_in_backend(SUBSERVICE* subsvc) rc = SESSION_ROUTE_QUERY(subsvc->session,sescmd_cursor_clone_querybuf(scur)); break; - case MYSQL_COM_INIT_DB: - { - /** - * Record database name and store to session. - */ - GWBUF* tmpbuf; - MYSQL_session* data; - unsigned int qlen; - - data = subsvc->session->data; - tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf; - qlen = MYSQL_GET_PACKET_LEN((unsigned char*) tmpbuf->start); - memset(data->db, 0, MYSQL_DATABASE_MAXLEN + 1); - strncpy(data->db, tmpbuf->start + 5, qlen - 1); - rc = SESSION_ROUTE_QUERY(subsvc->session,sescmd_cursor_clone_querybuf(scur)); - } - /** Fallthrough */ case MYSQL_COM_QUERY: default: /** From 50b0a9b71b7fec653a218457855531d8c849d847 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 30 Oct 2015 16:54:59 +0200 Subject: [PATCH 085/179] Code changes based on review of 1e8afe5063134b7c56492b3777ae1248b1587ba4 --- server/modules/include/schemarouter.h | 2 +- .../routing/schemarouter/schemarouter.c | 107 ++++++++++++------ 2 files changed, 71 insertions(+), 38 deletions(-) diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index d583dd5c3..e184e96e3 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -74,7 +74,7 @@ typedef struct shard_map SPINLOCK lock; time_t last_updated; enum shard_map_state state; /*< State of the shard map */ -}shard_map_t; +} shard_map_t; /** * The state of the backend server reference diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index e7e378021..c89cb7b5f 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -261,7 +261,7 @@ void* keyfreefun(void* data) * Allocate a shard map and initialize it. * @return Pointer to new shard_map_t or NULL if memory allocation failed */ -shard_map_t* create_shard_map() +shard_map_t* shard_map_alloc() { shard_map_t *rval; @@ -271,7 +271,7 @@ shard_map_t* create_shard_map() { HASHMEMORYFN kcopy = (HASHMEMORYFN)strdup; HASHMEMORYFN kfree = (HASHMEMORYFN)keyfreefun; - hashtable_memory_fns(rval->hash, kcopy, NULL, kfree, NULL); + hashtable_memory_fns(rval->hash, kcopy, kcopy, kfree, kfree); spinlock_init(&rval->lock); rval->last_updated = 0; rval->state = SHMAP_UNINIT; @@ -529,7 +529,6 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, dbnms = skygw_get_database_names(buffer,&sz); - spinlock_acquire(&client->shardmap->lock); HASHTABLE* ht = client->shardmap->hash; if(sz > 0){ @@ -591,13 +590,10 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, { rval = tmp; has_dbs = true; - - } - spinlock_release(&client->shardmap->lock); - return rval; } - + else + { if(buffer->hint && buffer->hint->type == HINT_ROUTE_TO_NAMED_SERVER) { for(i = 0; i < client->rses_nbackends; i++) @@ -625,9 +621,9 @@ char* get_shard_target_name(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client, { skygw_log_write(LOGFILE_TRACE,"schemarouter: Using active database '%s'",client->current_db); } + } } - spinlock_release(&client->shardmap->lock); return rval; } @@ -1033,6 +1029,25 @@ retblock: return (ROUTER *)router; } +/** + * Check if the shard map is out of date and update its state if necessary. + * @param router Router instance + * @param map Shard map to update + * @return Current state of the shard map + */ +enum shard_map_state shard_map_update_state(ROUTER_INSTANCE* router, shard_map_t *map) +{ + spinlock_acquire(&map->lock); + double tdiff = difftime(time(NULL), map->last_updated); + if (tdiff > router->schemarouter_config.refresh_min_interval) + { + map->state = SHMAP_STALE; + } + enum shard_map_state state = map->state; + spinlock_release(&map->lock); + return state; +} + /** * Associate a new session with this instance of the router. * @@ -1107,21 +1122,14 @@ static void* newSession( if (map) { - spinlock_acquire(&map->lock); - double tdiff = difftime(time(NULL), map->last_updated); - if (tdiff > router->schemarouter_config.refresh_min_interval) - { - map->state = SHMAP_STALE; - } - state = map->state; - spinlock_release(&map->lock); + state = shard_map_update_state(router, map); } spinlock_release(&router->lock); if (map == NULL || state != SHMAP_READY) { - if ((map = create_shard_map()) == NULL) + if ((map = shard_map_alloc()) == NULL) { skygw_log_write(LE, "Error: Failed to allocate enough memory to create" "new shard mapping. Session will be closed."); @@ -2047,8 +2055,9 @@ static int routeQuery( route_target_t route_target = TARGET_UNDEFINED; bool succp = false; char* tname = NULL; + char* targetserver = NULL; GWBUF* querybuf = qbuf; - char db[MYSQL_DATABASE_MAXLEN + 1]; + char db[MYSQL_DATABASE_MAXLEN + 1]; char errbuf[26+MYSQL_DATABASE_MAXLEN]; CHK_CLIENT_RSES(router_cli_ses); @@ -2083,7 +2092,7 @@ static int routeQuery( * to store the query. Once the databases have been mapped and/or the * default database is taken into use we can send the query forward. */ - if(router_cli_ses->init & (INIT_MAPPING|INIT_USE_DB)) + if (router_cli_ses->init & (INIT_MAPPING | INIT_USE_DB)) { int init_rval = 1; char* querystr = modutil_get_SQL(querybuf); @@ -2109,7 +2118,7 @@ static int routeQuery( } - if(router_cli_ses->init == (INIT_READY|INIT_USE_DB)) + if (router_cli_ses->init == (INIT_READY | INIT_USE_DB)) { /** * This state is possible if a client connects with a default database @@ -2269,7 +2278,7 @@ static int routeQuery( router_cli_ses->queue = querybuf; int rc_refresh = 1; - if((router_cli_ses->shardmap = create_shard_map())) + if((router_cli_ses->shardmap = shard_map_alloc())) { gen_databaselist(inst,router_cli_ses); } @@ -2324,27 +2333,37 @@ static int routeQuery( spinlock_acquire(&router_cli_ses->shardmap->lock); tname = hashtable_fetch(router_cli_ses->shardmap->hash,router_cli_ses->current_db); - spinlock_release(&router_cli_ses->shardmap->lock); + if(tname) { skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB for database '%s' on server '%s'", router_cli_ses->current_db,tname); route_target = TARGET_NAMED_SERVER; + targetserver = strdup(tname); } else { skygw_log_write(LOGFILE_TRACE,"schemarouter: INIT_DB with unknown database"); } + spinlock_release(&router_cli_ses->shardmap->lock); } - else if(route_target != TARGET_ALL && - (tname = get_shard_target_name(inst,router_cli_ses,querybuf,qtype)) != NULL) + else if (route_target != TARGET_ALL) { + /** If no database is found in the query and there is no active database + * or hints in the query we need to route the query to the first available + * server. This isn't ideal for monitoring server status but works if + * we just want the server to send an error back. */ + + spinlock_acquire(&router_cli_ses->shardmap->lock); + if ((tname = get_shard_target_name(inst,router_cli_ses,querybuf,qtype)) != NULL) + { bool shard_ok = check_shard_status(inst,tname); if(shard_ok) { route_target = TARGET_NAMED_SERVER; + targetserver = strdup(tname); } else { @@ -2355,12 +2374,14 @@ static int routeQuery( * for an alternate backend with the database. If this is not found * the target is undefined and an error will be returned to the client. */ - } + } + } + spinlock_release(&router_cli_ses->shardmap->lock); } if(TARGET_IS_UNDEFINED(route_target)) { - + spinlock_acquire(&router_cli_ses->shardmap->lock); tname = get_shard_target_name(inst,router_cli_ses,querybuf,qtype); if( (tname == NULL && @@ -2379,7 +2400,11 @@ static int routeQuery( } else - { + { + if (tname) + { + targetserver = strdup(tname); + } if(!change_successful) { /** @@ -2395,11 +2420,11 @@ static int routeQuery( /** Something else went wrong, terminate connection */ ret = 0; } - + spinlock_release(&router_cli_ses->shardmap->lock); goto retblock; } - + spinlock_release(&router_cli_ses->shardmap->lock); } if (TARGET_IS_ALL(route_target)) @@ -2442,8 +2467,8 @@ static int routeQuery( { if(SERVER_IS_RUNNING(inst->servers[z]->backend_server)) { - tname = inst->servers[z]->backend_server->unique_name; route_target = TARGET_NAMED_SERVER; + targetserver = strdup(inst->servers[z]->backend_server->unique_name); break; } } @@ -2466,14 +2491,14 @@ static int routeQuery( /** * Query is routed to one of the backends */ - if (TARGET_IS_NAMED_SERVER(route_target)) + if (TARGET_IS_NAMED_SERVER(route_target) && targetserver != NULL) { /** * Search backend server by name or replication lag. * If it fails, then try to find valid slave or master. */ - succp = get_shard_dcb(&target_dcb, router_cli_ses, tname); + succp = get_shard_dcb(&target_dcb, router_cli_ses, targetserver); if (!succp) { @@ -2482,7 +2507,7 @@ static int routeQuery( "Was supposed to route to named server " "%s but couldn't find the server in a " "suitable state.", - tname))); + targetserver))); } } @@ -2539,7 +2564,7 @@ static int routeQuery( } rses_end_locked_router_action(router_cli_ses); retblock: - + free(targetserver); gwbuf_free(querybuf); return ret; @@ -4600,7 +4625,8 @@ int process_show_shards(ROUTER_CLIENT_SES* rses) { HASHITERATOR* iter = hashtable_iterator(rses->shardmap->hash); struct shard_list sl; - + if (iter) + { sl.iter = iter; sl.rses = rses; if ((sl.rset = resultset_create(shard_list_cb, &sl)) == NULL) @@ -4616,6 +4642,13 @@ int process_show_shards(ROUTER_CLIENT_SES* rses) resultset_free(sl.rset); hashtable_iterator_free(iter); } + } + else + { + skygw_log_write(LE, "Error: hashtable_iterator creation failed. " + "This is caused by a memory allocation failure."); + rval = -1; + } } spinlock_release(&rses->shardmap->lock); return rval; @@ -4852,7 +4885,7 @@ void replace_shard_map(shard_map_t **target, shard_map_t **source) /** * Synchronize the router client session shard map with the global shard map for * this user. - * + * * If the router doesn't have a shard map for this user then the current shard map * of the client session is added to the router. If the shard map in the router is * out of date, its contents are replaced with the contents of the current client From 3903c4a35d23c16befdb564cd350cab586cac926 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 11:56:56 +0200 Subject: [PATCH 086/179] Renamed and moved variables around Renamed variables to make more sense and reordered them to be more in line with the function's purpose. --- server/modules/routing/schemarouter/schemarouter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index c89cb7b5f..ae4cbc934 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -1035,16 +1035,16 @@ retblock: * @param map Shard map to update * @return Current state of the shard map */ -enum shard_map_state shard_map_update_state(ROUTER_INSTANCE* router, shard_map_t *map) +enum shard_map_state shard_map_update_state(shard_map_t *self, ROUTER_INSTANCE* router) { - spinlock_acquire(&map->lock); - double tdiff = difftime(time(NULL), map->last_updated); + spinlock_acquire(&self->lock); + double tdiff = difftime(time(NULL), self->last_updated); if (tdiff > router->schemarouter_config.refresh_min_interval) { - map->state = SHMAP_STALE; + self->state = SHMAP_STALE; } - enum shard_map_state state = map->state; - spinlock_release(&map->lock); + enum shard_map_state state = self->state; + spinlock_release(&self->lock); return state; } From a969de7d50a64ceeab4ac9e8ca35704d4186ebc2 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 2 Nov 2015 11:26:59 +0200 Subject: [PATCH 087/179] Changed unnecessary strncpy to strcpy. --- server/modules/routing/schemarouter/sharding_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/schemarouter/sharding_common.c b/server/modules/routing/schemarouter/sharding_common.c index 067edae3f..813e9f826 100644 --- a/server/modules/routing/schemarouter/sharding_common.c +++ b/server/modules/routing/schemarouter/sharding_common.c @@ -139,7 +139,7 @@ bool change_current_db(char* dest, } else { - strncpy(dest,db,MYSQL_DATABASE_MAXLEN); + strcpy(dest,db); skygw_log_write(LOGFILE_TRACE,"change_current_db: database is on server: '%s'.",target); succp = true; goto retblock; From 99ac4876f4159a1b80474a61cec8a861520423f5 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 12:15:42 +0200 Subject: [PATCH 088/179] Fixed wrong variables being passed. --- server/modules/routing/schemarouter/schemarouter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index ae4cbc934..9bbf6b357 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -1122,7 +1122,7 @@ static void* newSession( if (map) { - state = shard_map_update_state(router, map); + state = shard_map_update_state(map, router); } spinlock_release(&router->lock); From 2d0a96848cf04199e2f9c66ada02bcadb85edc99 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 14:12:17 +0200 Subject: [PATCH 089/179] Added table of contents to configuration guide. --- .../Getting-Started/Configuration-Guide.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index a4af5529c..7b145d7cb 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -22,6 +22,23 @@ connection failover| When a connection currently being used between MaxScale and backend database | A term used to refer to a database that sits behind MaxScale and is accessed by applications via MaxScale. filter | A module that can be placed between the client and the MaxScale router module. All client data passes through the filter module and may be examined or modified by the filter modules. Filters may be chained together to form processing pipelines. +# Table of Contents + +* [Configuration](#configuration) + * [Global Settings](#global-settings) + * [Service](#service) + * [Service and SSL](#service-and-ssl) + * [Server](#server) + * [Listener](#listener) + * [Filter](#filter) + * [Monitor](#monitor) + * [Protocol](#protocol) +* [Router Modules](#router-modules) +* [Monitor Modules](#monitor-modules) +* [Filter Modules](#filter-modules) +* [Reloading Configuration](#reloading-configuration) +* [Authentication](#authentication) +* [Error Reporting](#error-reporting) ## Configuration @@ -696,7 +713,7 @@ Default value is `1`. Read Timeout is the timeout in seconds for each attempt to Default value is `2`. Write Timeout is the timeout in seconds for each attempt to write to the server. There is a retry if necessary, so the total effective timeout value is two times the option value. That's for `mysql_real_connect` C API. -## Protocol Modules +## Protocol The protocols supported by MaxScale are implemented as external modules that are loaded dynamically into the MaxScale core. These modules reside in the directory `/usr/lib64/maxscale`. The location can be overridden with the `libdir=PATH` parameter under the `[maxscale]` section. It may also be set by passing the `-B PATH` or `--libdir=PATH` option on the MaxScale command line. From 2594c83117e7500ca50baad11bb8f8bdedec1c5b Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 13:44:34 +0200 Subject: [PATCH 090/179] Missing format specified added. --- server/modules/routing/binlog/blr_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/binlog/blr_file.c b/server/modules/routing/binlog/blr_file.c index 38901cf7d..efb9dc88c 100644 --- a/server/modules/routing/binlog/blr_file.c +++ b/server/modules/routing/binlog/blr_file.c @@ -1637,7 +1637,7 @@ char err_msg[STRERROR_BUFLEN]; snprintf(filename,(PATH_MAX - 4), "%s/master.ini", path); - snprintf(tmp_file, (PATH_MAX -4), filename); + snprintf(tmp_file, (PATH_MAX - 4), "%s", filename); strcat(tmp_file, ".tmp"); From 9ba6ad81b016805f8c8085910627cde3060abc06 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 13:52:52 +0200 Subject: [PATCH 091/179] Some gotos removed. --- log_manager/log_manager.cc | 68 +++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 0c20773c4..1f949b27e 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1224,61 +1224,55 @@ static blockbuf_t* blockbuf_init(logfile_id_t id) int skygw_log_enable(logfile_id_t id) { - bool err = 0; + bool rval = -1; - if (!logmanager_register(true)) + if (logmanager_register(true)) { - err = -1; - goto return_err; - } - CHK_LOGMANAGER(lm); + CHK_LOGMANAGER(lm); - if (logfile_set_enabled(id, true)) - { - lm->lm_enabled_logfiles |= id; - /** - * Set global variable - */ - lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; + if (logfile_set_enabled(id, true)) + { + lm->lm_enabled_logfiles |= id; + /** + * Set global variable + */ + lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; + } + + logmanager_unregister(); + rval = 0; } - logmanager_unregister(); -return_err: - return err; + return rval; } int skygw_log_disable(logfile_id_t id) /*< no locking */ { - int rc; - - rc = skygw_log_disable_raw(id, false); - - return rc; + return skygw_log_disable_raw(id, false); } static int skygw_log_disable_raw(logfile_id_t id, bool emergency) /*< no locking */ { - bool err = 0; + bool rval = -1; - if (!logmanager_register(true)) + if (logmanager_register(true)) { - err = -1; - goto return_err; - } - CHK_LOGMANAGER(lm); + CHK_LOGMANAGER(lm); - if (emergency || logfile_set_enabled(id, false)) - { - lm->lm_enabled_logfiles &= ~id; - /** - * Set global variable - */ - lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; + if (emergency || logfile_set_enabled(id, false)) + { + lm->lm_enabled_logfiles &= ~id; + /** + * Set global variable + */ + lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; + } + + logmanager_unregister(); + rval = 0; } - logmanager_unregister(); -return_err: - return err; + return rval; } From 9050fce3d488595b65ae1b9b87f4e8fc4242a02a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 14:23:31 +0200 Subject: [PATCH 092/179] It only makes sense to flush/rotate the error log. The other log files are not used. --- log_manager/log_manager.cc | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 1f949b27e..3ba977b49 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1571,24 +1571,29 @@ int skygw_log_flush(logfile_id_t id) { int err = -1; - if (logmanager_register(false)) + if (id == LOGFILE_ERROR) { - CHK_LOGMANAGER(lm); - - if (logmanager_is_valid_id(id)) + if (logmanager_register(false)) { + CHK_LOGMANAGER(lm); + logfile_t *lf = logmanager_get_logfile(lm, id); CHK_LOGFILE(lf); logfile_flush(lf); err = 0; - } - logmanager_unregister(); + logmanager_unregister(); + } + else + { + ss_dfprintf(stderr, "Can't register to logmanager, flushing failed.\n"); + } } else { - ss_dfprintf(stderr, "Can't register to logmanager, flushing failed.\n"); + // We'll pretend everything went ok. + err = 0; } return err; @@ -1602,12 +1607,12 @@ int skygw_log_rotate(logfile_id_t id) { int err = -1; - if (logmanager_register(false)) + if (id == LOGFILE_ERROR) { - CHK_LOGMANAGER(lm); - - if (logmanager_is_valid_id(id)) + if (logmanager_register(false)) { + CHK_LOGMANAGER(lm); + logfile_t *lf = logmanager_get_logfile(lm, id); CHK_LOGFILE(lf); @@ -1615,13 +1620,18 @@ int skygw_log_rotate(logfile_id_t id) logfile_rotate(lf); err = 0; - } - logmanager_unregister(); + logmanager_unregister(); + } + else + { + ss_dfprintf(stderr, "Can't register to logmanager, rotating failed.\n"); + } } else { - ss_dfprintf(stderr, "Can't register to logmanager, rotating failed.\n"); + // We'll pretend everything went ok. + err = 0; } return err; From 4de363e8ddd8e0c5e2dc5dc534e7386924964d28 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 15:59:27 +0200 Subject: [PATCH 093/179] Some log refactoring. Some log manager refactoring to make it easier to later remove all files but the error log. Basically all that was done was to move everything inside the for-loop of thr_filewriter_fun into a separate function called thr_flush_file. Otherwise no changes in functionality was made. --- log_manager/log_manager.cc | 354 ++++++++++++++++++------------------- 1 file changed, 177 insertions(+), 177 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 3ba977b49..d8ced8ec4 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -2836,6 +2836,173 @@ static void filewriter_done(filewriter_t* fw) } } +static bool thr_flush_file(skygw_thread_t* thr, logmanager_t *lm, filewriter_t *fwr, logfile_id_t id) +{ + /** + * Get file pointer of current logfile. + */ + bool do_flushall = thr_flushall_check(); + skygw_file_t *file = fwr->fwr_file[id]; + logfile_t *lf = &lm->lm_logfile[id]; + + /** + * read and reset logfile's flush- and rotateflag + */ + acquire_lock(&lf->lf_spinlock); + bool flush_logfile = lf->lf_flushflag; + bool rotate_logfile = lf->lf_rotateflag; + lf->lf_flushflag = false; + lf->lf_rotateflag = false; + release_lock(&lf->lf_spinlock); + /** + * Log rotation : + * Close current, and open a new file for the log. + */ + if (rotate_logfile) + { + bool succp; + + lf->lf_name_seqno += 1; /*< new sequence number */ + + if (!(succp = logfile_create(lf))) + { + lf->lf_name_seqno -= 1; /*< restore */ + } + else if ((succp = logfile_open_file(fwr, lf))) + { + if (use_stdout) + { + skygw_file_free (file); + } + else + { + skygw_file_close(file, false); /*< close old file */ + } + } + + if (!succp) + { + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "Error : Log rotation failed. " + "Creating replacement file %s " + "failed. Continuing " + "logging to existing file.", + lf->lf_full_file_name))); + } + return true; + } + /** + * get logfile's block buffer list + */ + mlist_t *bb_list = &lf->lf_blockbuf_list; +#if defined(SS_DEBUG) + simple_mutex_lock(&bb_list->mlist_mutex, true); + CHK_MLIST(bb_list); + simple_mutex_unlock(&bb_list->mlist_mutex); +#endif + mlist_node_t *node = bb_list->mlist_first; + + while (node != NULL) + { + int err = 0; + + CHK_MLIST_NODE(node); + blockbuf_t *bb = (blockbuf_t *)node->mlnode_data; + CHK_BLOCKBUF(bb); + + /** Lock block buffer */ + simple_mutex_lock(&bb->bb_mutex, true); + + blockbuf_state_t flush_blockbuf = bb->bb_state; + + if (bb->bb_buf_used != 0 && + ((flush_blockbuf == BB_FULL) || flush_logfile || do_flushall)) + { + /** + * buffer is at least half-full + * -> write to disk + */ + while (bb->bb_refcount > 0) + { + simple_mutex_unlock(&bb->bb_mutex); + simple_mutex_lock(&bb->bb_mutex, true); + } + err = skygw_file_write(file, + (void *)bb->bb_buf, + bb->bb_buf_used, + (flush_logfile || do_flushall)); + if (err) + { + char errbuf[STRERROR_BUFLEN]; + fprintf(stderr, + "Error : Write to %s log " + ": %s failed due to %d, " + "%s. Disabling the log.", + STRLOGNAME(id), + lf->lf_full_file_name, + err, + strerror_r(err, errbuf, sizeof(errbuf))); + /** Force log off */ + skygw_log_disable_raw(id, true); + } + /** + * Reset buffer's counters and mark + * not full. + */ + bb->bb_buf_left = bb->bb_buf_size; + bb->bb_buf_used = 0; + memset(bb->bb_buf, 0, bb->bb_buf_size); + bb->bb_state = BB_CLEARED; +#if defined(SS_LOG_DEBUG) + sprintf(bb->bb_buf,"[block:%d]", atomic_add(&block_start_index, 1)); + bb->bb_buf_used += strlen(bb->bb_buf); + bb->bb_buf_left -= strlen(bb->bb_buf); +#endif + + } + /** Release lock to block buffer */ + simple_mutex_unlock(&bb->bb_mutex); + + size_t vn1; + size_t vn2; + /** Consistent lock-free read on the list */ + do + { + while ((vn1 = bb_list->mlist_versno) % 2 != 0) + { + continue; + } + node = node->mlnode_next; + vn2 = bb_list->mlist_versno; + } + while (vn1 != vn2 && node); + + } /* while (node != NULL) */ + + /** + * Writer's exit flag was set after checking it. + * Loop is restarted to ensure that all logfiles are + * flushed. + */ + + bool all_done = true; + + if (flushall_started_flag) + { + flushall_started_flag = false; + flushall_done_flag = true; + all_done = false; + } + + if (!thr_flushall_check() && skygw_thread_must_exit(thr)) + { + flushall_logfiles(true); + all_done = false; + } + + return all_done; +} /** * @node Writes block buffers of logfiles to physical log files on disk. @@ -2882,24 +3049,9 @@ static void filewriter_done(filewriter_t* fw) */ static void* thr_filewriter_fun(void* data) { - skygw_thread_t* thr; - filewriter_t* fwr; - skygw_file_t* file; - logfile_t* lf; + skygw_thread_t* thr = (skygw_thread_t *)data; + filewriter_t* fwr = (filewriter_t *)skygw_thread_get_data(thr); - mlist_t* bb_list; - blockbuf_t* bb; - mlist_node_t* node; - int i; - blockbuf_state_t flush_blockbuf; /**< flush single block buffer. */ - bool flush_logfile; /**< flush logfile */ - bool do_flushall = false; - bool rotate_logfile; /*< close current and open new file */ - size_t vn1; - size_t vn2; - - thr = (skygw_thread_t *)data; - fwr = (filewriter_t *)skygw_thread_get_data(thr); flushall_logfiles(false); CHK_FILEWRITER(fwr); @@ -2907,7 +3059,6 @@ static void* thr_filewriter_fun(void* data) /** Inform log manager about the state. */ skygw_message_send(fwr->fwr_clientmes); - while (!skygw_thread_must_exit(thr)) { /** @@ -2921,171 +3072,20 @@ static void* thr_filewriter_fun(void* data) } /** Process all logfiles which have buffered writes. */ - for (i = LOGFILE_FIRST; i <= LOGFILE_LAST; i <<= 1) + int i = LOGFILE_FIRST; + + do { - retry_flush_on_exit: - /** - * Get file pointer of current logfile. - */ - - do_flushall = thr_flushall_check(); - file = fwr->fwr_file[i]; - lf = &lm->lm_logfile[(logfile_id_t)i]; - - /** - * read and reset logfile's flush- and rotateflag - */ - acquire_lock(&lf->lf_spinlock); - flush_logfile = lf->lf_flushflag; - rotate_logfile = lf->lf_rotateflag; - lf->lf_flushflag = false; - lf->lf_rotateflag = false; - release_lock(&lf->lf_spinlock); - /** - * Log rotation : - * Close current, and open a new file for the log. - */ - if (rotate_logfile) + if (thr_flush_file(thr, lm, fwr, (logfile_id_t) i)) { - bool succp; - - lf->lf_name_seqno += 1; /*< new sequence number */ - - if (!(succp = logfile_create(lf))) - { - lf->lf_name_seqno -= 1; /*< restore */ - } - else if ((succp = logfile_open_file(fwr, lf))) - { - if (use_stdout) - { - skygw_file_free (file); - } - else - { - skygw_file_close(file, false); /*< close old file */ - } - } - - if (!succp) - { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Log rotation failed. " - "Creating replacement file %s " - "failed. Continuing " - "logging to existing file.", - lf->lf_full_file_name))); - } - continue; + i <<= 1; } - /** - * get logfile's block buffer list - */ - bb_list = &lf->lf_blockbuf_list; -#if defined(SS_DEBUG) - simple_mutex_lock(&bb_list->mlist_mutex, true); - CHK_MLIST(bb_list); - simple_mutex_unlock(&bb_list->mlist_mutex); -#endif - node = bb_list->mlist_first; - - while (node != NULL) + else { - int err = 0; - - CHK_MLIST_NODE(node); - bb = (blockbuf_t *)node->mlnode_data; - CHK_BLOCKBUF(bb); - - /** Lock block buffer */ - simple_mutex_lock(&bb->bb_mutex, true); - - flush_blockbuf = bb->bb_state; - - if (bb->bb_buf_used != 0 && - ((flush_blockbuf == BB_FULL) || flush_logfile || do_flushall)) - { - /** - * buffer is at least half-full - * -> write to disk - */ - while (bb->bb_refcount > 0) - { - simple_mutex_unlock(&bb->bb_mutex); - simple_mutex_lock(&bb->bb_mutex, true); - } - err = skygw_file_write(file, - (void *)bb->bb_buf, - bb->bb_buf_used, - (flush_logfile || do_flushall)); - if (err) - { - char errbuf[STRERROR_BUFLEN]; - fprintf(stderr, - "Error : Write to %s log " - ": %s failed due to %d, " - "%s. Disabling the log.", - STRLOGNAME((logfile_id_t)i), - lf->lf_full_file_name, - err, - strerror_r(err, errbuf, sizeof(errbuf))); - /** Force log off */ - skygw_log_disable_raw((logfile_id_t)i, true); - } - /** - * Reset buffer's counters and mark - * not full. - */ - bb->bb_buf_left = bb->bb_buf_size; - bb->bb_buf_used = 0; - memset(bb->bb_buf, 0, bb->bb_buf_size); - bb->bb_state = BB_CLEARED; -#if defined(SS_LOG_DEBUG) - sprintf(bb->bb_buf,"[block:%d]", atomic_add(&block_start_index, 1)); - bb->bb_buf_used += strlen(bb->bb_buf); - bb->bb_buf_left -= strlen(bb->bb_buf); -#endif - - } - /** Release lock to block buffer */ - simple_mutex_unlock(&bb->bb_mutex); - - /** Consistent lock-free read on the list */ - do - { - while ((vn1 = bb_list->mlist_versno) % 2 != 0) - { - continue; - } - node = node->mlnode_next; - vn2 = bb_list->mlist_versno; - } - while (vn1 != vn2 && node); - - } /* while (node != NULL) */ - - /** - * Writer's exit flag was set after checking it. - * Loop is restarted to ensure that all logfiles are - * flushed. - */ - - if (flushall_started_flag) - { - flushall_started_flag = false; - flushall_done_flag = true; i = LOGFILE_FIRST; - goto retry_flush_on_exit; } - - if (!thr_flushall_check() && skygw_thread_must_exit(thr)) - { - flushall_logfiles(true); - i = LOGFILE_FIRST; - goto retry_flush_on_exit; - } - }/* for */ + } + while (i <= LOGFILE_LAST); if (flushall_done_flag) { From 8798475a46da8904a6ef17ffe0c160b8e4377366 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 21:42:21 +0200 Subject: [PATCH 094/179] Some re-arranging of functionality. Some thread specific functionality moved from thr_flush_file to the caller thr_filewriter_fun. --- log_manager/log_manager.cc | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index d8ced8ec4..acf8920fa 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -2836,7 +2836,7 @@ static void filewriter_done(filewriter_t* fw) } } -static bool thr_flush_file(skygw_thread_t* thr, logmanager_t *lm, filewriter_t *fwr, logfile_id_t id) +static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr, logfile_id_t id) { /** * Get file pointer of current logfile. @@ -2986,22 +2986,16 @@ static bool thr_flush_file(skygw_thread_t* thr, logmanager_t *lm, filewriter_t * * flushed. */ - bool all_done = true; + bool done = true; if (flushall_started_flag) { flushall_started_flag = false; flushall_done_flag = true; - all_done = false; + done = false; } - if (!thr_flushall_check() && skygw_thread_must_exit(thr)) - { - flushall_logfiles(true); - all_done = false; - } - - return all_done; + return done; } /** @@ -3076,7 +3070,15 @@ static void* thr_filewriter_fun(void* data) do { - if (thr_flush_file(thr, lm, fwr, (logfile_id_t) i)) + bool done = thr_flush_file(lm, fwr, (logfile_id_t) i); + + if (!thr_flushall_check() && skygw_thread_must_exit(thr)) + { + flushall_logfiles(true); + done = false; + } + + if (done) { i <<= 1; } From 3348fab3c41d3925e460dcc9e199963eb58d47dd Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 22:27:13 +0200 Subject: [PATCH 095/179] Only error log is created. Only the error log is created anymore. The data structures for the other files still exist, but they are to be removed next. --- log_manager/log_manager.cc | 167 +++++++++++++++---------------------- 1 file changed, 68 insertions(+), 99 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index acf8920fa..6d9dbe116 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -282,7 +282,7 @@ static void fnames_conf_free_memory(fnames_conf_t* fn); static char* fname_conf_get_prefix(fnames_conf_t* fn, logfile_id_t id); static char* fname_conf_get_suffix(fnames_conf_t* fn, logfile_id_t id); static void* thr_filewriter_fun(void* data); -static logfile_t* logmanager_get_logfile(logmanager_t* lm, logfile_id_t id); +static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); static void logmanager_unregister(void); static bool logmanager_init_nomutex(int argc, char* argv[]); @@ -530,12 +530,9 @@ static void logmanager_done_nomutex(void) /** Free filewriter memory. */ filewriter_done(fwr); - for (i = LOGFILE_FIRST; i <= LOGFILE_LAST; i++) - { - lf = logmanager_get_logfile(lm, (logfile_id_t)i); - /** Release logfile memory */ - logfile_done(lf); - } + lf = logmanager_get_logfile(lm); + /** Release logfile memory */ + logfile_done(lf); if (syslog_id_str) { @@ -601,12 +598,11 @@ return_void: release_lock(&lmlock); } -static logfile_t* logmanager_get_logfile(logmanager_t* lmgr, logfile_id_t id) +static logfile_t* logmanager_get_logfile(logmanager_t* lmgr) { logfile_t* lf; CHK_LOGMANAGER(lmgr); - ss_dassert(id >= LOGFILE_FIRST && id <= LOGFILE_LAST); - lf = &lmgr->lm_logfile[id]; + lf = &lmgr->lm_logfile[LOGFILE_ERROR]; if (lf->lf_state == RUN) { @@ -1286,8 +1282,11 @@ static bool logfile_set_enabled(logfile_id_t id, bool val) { if (use_stdout == 0) { - logfile_t *lf = logmanager_get_logfile(lm, id); - lf->lf_enabled = val; + if (id == LOGFILE_ERROR) + { + logfile_t *lf = logmanager_get_logfile(lm); + lf->lf_enabled = val; + } const char *name; @@ -1577,7 +1576,7 @@ int skygw_log_flush(logfile_id_t id) { CHK_LOGMANAGER(lm); - logfile_t *lf = logmanager_get_logfile(lm, id); + logfile_t *lf = logmanager_get_logfile(lm); CHK_LOGFILE(lf); logfile_flush(lf); @@ -1613,7 +1612,7 @@ int skygw_log_rotate(logfile_id_t id) { CHK_LOGMANAGER(lm); - logfile_t *lf = logmanager_get_logfile(lm, id); + logfile_t *lf = logmanager_get_logfile(lm); CHK_LOGFILE(lf); MXS_NOTICE("Log rotation is called for %s.", lf->lf_full_file_name); @@ -2000,8 +1999,6 @@ static char* fname_conf_get_suffix(fnames_conf_t* fn, logfile_id_t id) static bool logfiles_init(logmanager_t* lm) { bool succp = true; - int lid = LOGFILE_FIRST; - int i = 0; bool store_shmem; bool write_syslog; @@ -2011,51 +2008,46 @@ static bool logfiles_init(logmanager_t* lm) openlog(syslog_ident_str, LOG_PID | LOG_NDELAY, LOG_USER); } /** - * Initialize log files, pass softlink flag if necessary. + * Initialize log file, pass softlink flag if necessary. */ - while (lid <= LOGFILE_LAST && succp) + + /** + * Check if the file is stored in shared memory. If so, + * a symbolic link will be created to log directory. + */ + if (shmem_id_str != NULL && + strcasestr(shmem_id_str, STRLOGID(LOGFILE_ERROR)) != NULL) { - /** - * Check if the file is stored in shared memory. If so, - * a symbolic link will be created to log directory. - */ - if (shmem_id_str != NULL && - strcasestr(shmem_id_str, STRLOGID(logfile_id_t(lid))) != NULL) - { - store_shmem = true; - } - else - { - store_shmem = false; - } - /** - * Check if file is also written to syslog. - */ - if (syslog_id_str != NULL && - strcasestr(syslog_id_str, STRLOGID(logfile_id_t(lid))) != NULL) - { - write_syslog = true; - } - else - { - write_syslog = false; - } - - succp = logfile_init(&lm->lm_logfile[lid], - (logfile_id_t)lid, - lm, - store_shmem, - write_syslog); - - if (!succp) - { - fprintf(stderr, "*\n* Error : Initializing log files failed.\n"); - break; - } - - lid <<= 1; - i += 1; + store_shmem = true; } + else + { + store_shmem = false; + } + /** + * Check if file is also written to syslog. + */ + if (syslog_id_str != NULL && + strcasestr(syslog_id_str, STRLOGID(LOGFILE_ERROR)) != NULL) + { + write_syslog = true; + } + else + { + write_syslog = false; + } + + succp = logfile_init(&lm->lm_logfile[LOGFILE_ERROR], + LOGFILE_ERROR, + lm, + store_shmem, + write_syslog); + + if (!succp) + { + fprintf(stderr, "*\n* Error : Initializing log files failed.\n"); + } + return succp; } @@ -2756,8 +2748,6 @@ static bool filewriter_init(logmanager_t* logmanager, { bool succp = false; logfile_t* lf; - logfile_id_t id; - int i; CHK_LOGMANAGER(logmanager); @@ -2777,20 +2767,16 @@ static bool filewriter_init(logmanager_t* logmanager, goto return_succp; } - for (i = LOGFILE_FIRST; i <= LOGFILE_LAST; i <<= 1) - { - id = (logfile_id_t)i; - lf = logmanager_get_logfile(logmanager, id); + lf = logmanager_get_logfile(logmanager); - if (!(succp = logfile_open_file(fw, lf))) - { - fprintf(stderr, - "Error : opening log file %s failed. Exiting " - "MaxScale\n", - lf->lf_full_file_name); - goto return_succp; - } - } /*< for */ + if (!(succp = logfile_open_file(fw, lf))) + { + fprintf(stderr, + "Error : opening log file %s failed. Exiting " + "MaxScale\n", + lf->lf_full_file_name); + goto return_succp; + } fw->fwr_state = RUN; CHK_FILEWRITER(fw); succp = true; @@ -2806,9 +2792,6 @@ return_succp: static void filewriter_done(filewriter_t* fw) { - int i; - logfile_id_t id; - switch (fw->fwr_state) { case RUN: @@ -2816,17 +2799,13 @@ static void filewriter_done(filewriter_t* fw) case INIT: fw->fwr_logmes = NULL; fw->fwr_clientmes = NULL; - for (i = LOGFILE_FIRST; i <= LOGFILE_LAST; i++) + if (use_stdout) { - id = (logfile_id_t)i; - if (use_stdout) - { - skygw_file_free(fw->fwr_file[id]); - } - else - { - skygw_file_close(fw->fwr_file[id], true); - } + skygw_file_free(fw->fwr_file[LOGFILE_ERROR]); + } + else + { + skygw_file_close(fw->fwr_file[LOGFILE_ERROR], true); } fw->fwr_state = DONE; case DONE: @@ -3066,28 +3045,18 @@ static void* thr_filewriter_fun(void* data) } /** Process all logfiles which have buffered writes. */ - int i = LOGFILE_FIRST; + bool done = false; - do + while (!done) { - bool done = thr_flush_file(lm, fwr, (logfile_id_t) i); + done = thr_flush_file(lm, fwr, LOGFILE_ERROR); if (!thr_flushall_check() && skygw_thread_must_exit(thr)) { flushall_logfiles(true); done = false; } - - if (done) - { - i <<= 1; - } - else - { - i = LOGFILE_FIRST; - } } - while (i <= LOGFILE_LAST); if (flushall_done_flag) { From 633f06cddd464e826634771de1742342eb0fa54a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 22:52:20 +0200 Subject: [PATCH 096/179] The notion of a particular file being enabled is removed. The one and only message file is always enabled. --- log_manager/log_manager.cc | 51 +++----------------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 6d9dbe116..9ea3a9313 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -174,7 +174,6 @@ struct logfile #endif flat_obj_state_t lf_state; bool lf_init_started; - bool lf_enabled; bool lf_store_shmem; bool lf_write_syslog; logmanager_t* lf_lmgr; @@ -1282,12 +1281,6 @@ static bool logfile_set_enabled(logfile_id_t id, bool val) { if (use_stdout == 0) { - if (id == LOGFILE_ERROR) - { - logfile_t *lf = logmanager_get_logfile(lm); - lf->lf_enabled = val; - } - const char *name; switch (id) @@ -2229,9 +2222,7 @@ return_succp: */ static bool logfile_open_file(filewriter_t* fw, logfile_t* lf) { - bool succp; - char* start_msg_str; - int err; + bool rv = true; if (use_stdout) { @@ -2252,45 +2243,10 @@ static bool logfile_open_file(filewriter_t* fw, logfile_t* lf) if (fw->fwr_file[lf->lf_id] == NULL) { fprintf(stderr, "Error : opening logfile %s failed.\n", lf->lf_full_file_name); - succp = false; - goto return_succp; + rv = false; } - if (use_stdout == 0) - { - if (lf->lf_enabled) - { - start_msg_str = strdup("---\tLogging is enabled.\n"); - } - else - { - start_msg_str = strdup("---\tLogging is disabled.\n"); - } - err = skygw_file_write(fw->fwr_file[lf->lf_id], - (void *)start_msg_str, - strlen(start_msg_str), - true); - - if (err != 0) - { - char errbuf[STRERROR_BUFLEN]; - fprintf(stderr, - "Error : writing to file %s failed due to %d, %s. " - "Exiting MaxScale.\n", - lf->lf_full_file_name, - err, - strerror_r(err, errbuf, sizeof(errbuf))); - succp = false; - goto return_succp; - } - - free(start_msg_str); - } - - succp = true; - -return_succp: - return succp; + return rv; } @@ -2588,7 +2544,6 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_store_shmem = store_shmem; logfile->lf_write_syslog = write_syslog; logfile->lf_buf_size = MAX_LOGSTRLEN; - logfile->lf_enabled = logmanager->lm_enabled_logfiles & logfile_id; /** * If file is stored in shared memory in /dev/shm, a link * pointing to shm file is created and located to the file From f17803e89276fb908c8093968800a22cc8db2f64 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 3 Nov 2015 23:05:07 +0200 Subject: [PATCH 097/179] Only one log_file. The array of log_files replaced with single instance. --- log_manager/log_manager.cc | 68 ++++++++++++++++---------------------- utils/skygw_debug.h | 3 -- 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 9ea3a9313..187962b7a 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -129,7 +129,7 @@ struct filewriter flat_obj_state_t fwr_state; logmanager_t* fwr_logmgr; /** Physical files */ - skygw_file_t* fwr_file[LOGFILE_LAST + 1]; + skygw_file_t* fwr_file; /** fwr_logmes is for messages from log clients */ skygw_message_t* fwr_logmes; /** fwr_clientmes is for messages to log clients */ @@ -149,7 +149,6 @@ typedef struct blockbuf #if defined(SS_DEBUG) skygw_chk_t bb_chk_top; #endif - logfile_id_t bb_fileid; blockbuf_state_t bb_state; /**State of the block buffer*/ simple_mutex_t bb_mutex; /**< bb_buf_used, bb_isfull */ int bb_refcount; /**< protected by list mutex. #of clients */ @@ -179,7 +178,6 @@ struct logfile logmanager_t* lf_lmgr; /** fwr_logmes is for messages from log clients */ skygw_message_t* lf_logmes; - logfile_id_t lf_id; char* lf_filepath; /**< path to file used for logging */ char* lf_linkpath; /**< path to symlink file. */ char* lf_name_prefix; @@ -236,7 +234,7 @@ struct logmanager /** fwr_clientmes is for messages to log clients */ skygw_message_t* lm_clientmes; fnames_conf_t lm_fnames_conf; - logfile_t lm_logfile[LOGFILE_LAST + 1]; + logfile_t lm_logfile; filewriter_t lm_filewriter; #if defined(SS_DEBUG) skygw_chk_t lm_chk_tail; @@ -258,7 +256,6 @@ typedef struct strpart /** Static function declarations */ static bool logfiles_init(logmanager_t* lmgr); static bool logfile_init(logfile_t* logfile, - logfile_id_t logfile_id, logmanager_t* logmanager, bool store_shmem, bool write_syslog); @@ -294,10 +291,9 @@ static int logmanager_write_log(logfile_id_t id, size_t len, const char* str); -static blockbuf_t* blockbuf_init(logfile_id_t id); +static blockbuf_t* blockbuf_init(); static void blockbuf_node_done(void* bb_data); static char* blockbuf_get_writepos(blockbuf_t** p_bb, - logfile_id_t id, size_t str_len, bool flush); @@ -601,7 +597,7 @@ static logfile_t* logmanager_get_logfile(logmanager_t* lmgr) { logfile_t* lf; CHK_LOGMANAGER(lmgr); - lf = &lmgr->lm_logfile[LOGFILE_ERROR]; + lf = &lmgr->lm_logfile; if (lf->lf_state == RUN) { @@ -687,7 +683,7 @@ static int logmanager_write_log(logfile_id_t id, goto return_err; } // All messages are now logged to the error log file. - lf = &lm->lm_logfile[LOGFILE_ERROR]; + lf = &lm->lm_logfile; CHK_LOGFILE(lf); /** @@ -774,7 +770,7 @@ static int logmanager_write_log(logfile_id_t id, if (do_maxscalelog) { // All messages are now logged to the error log file. - wp = blockbuf_get_writepos(&bb, LOGFILE_ERROR, safe_str_len, flush); + wp = blockbuf_get_writepos(&bb, safe_str_len, flush); } else { @@ -894,7 +890,7 @@ static void blockbuf_unregister(blockbuf_t* bb) CHK_BLOCKBUF(bb); ss_dassert(bb->bb_refcount >= 1); - lf = &lm->lm_logfile[bb->bb_fileid]; + lf = &lm->lm_logfile; CHK_LOGFILE(lf); /** * if this is the last client in a full buffer, send write request. @@ -927,7 +923,6 @@ static void blockbuf_unregister(blockbuf_t* bb) * */ static char* blockbuf_get_writepos(blockbuf_t** p_bb, - logfile_id_t id, size_t str_len, bool flush) { @@ -941,7 +936,7 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, #endif CHK_LOGMANAGER(lm); - lf = &lm->lm_logfile[id]; + lf = &lm->lm_logfile; CHK_LOGFILE(lf); bb_list = &lf->lf_blockbuf_list; @@ -1007,7 +1002,7 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, /** * New node is created */ - if ((bb = blockbuf_init(id)) == NULL) + if ((bb = blockbuf_init()) == NULL) { return NULL; } @@ -1107,7 +1102,7 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, * Create the first block buffer to logfile's blockbuf list. */ - if ((bb = blockbuf_init(id)) == NULL) + if ((bb = blockbuf_init()) == NULL) { return NULL; } @@ -1188,13 +1183,12 @@ static void blockbuf_node_done(void* bb_data) } -static blockbuf_t* blockbuf_init(logfile_id_t id) +static blockbuf_t* blockbuf_init() { blockbuf_t* bb; if ((bb = (blockbuf_t *) calloc(1, sizeof (blockbuf_t)))) { - bb->bb_fileid = id; #if defined(SS_DEBUG) bb->bb_chk_top = CHK_NUM_BLOCKBUF; bb->bb_chk_tail = CHK_NUM_BLOCKBUF; @@ -2030,8 +2024,7 @@ static bool logfiles_init(logmanager_t* lm) write_syslog = false; } - succp = logfile_init(&lm->lm_logfile[LOGFILE_ERROR], - LOGFILE_ERROR, + succp = logfile_init(&lm->lm_logfile, lm, store_shmem, write_syslog); @@ -2226,21 +2219,21 @@ static bool logfile_open_file(filewriter_t* fw, logfile_t* lf) if (use_stdout) { - fw->fwr_file[lf->lf_id] = skygw_file_alloc(lf->lf_full_file_name); - fw->fwr_file[lf->lf_id]->sf_file = stdout; + fw->fwr_file = skygw_file_alloc(lf->lf_full_file_name); + fw->fwr_file->sf_file = stdout; } else if (lf->lf_store_shmem) { /** Create symlink pointing to log file */ - fw->fwr_file[lf->lf_id] = skygw_file_init(lf->lf_full_file_name, lf->lf_full_link_name); + fw->fwr_file = skygw_file_init(lf->lf_full_file_name, lf->lf_full_link_name); } else { /** Create normal disk-resident log file */ - fw->fwr_file[lf->lf_id] = skygw_file_init(lf->lf_full_file_name, NULL); + fw->fwr_file = skygw_file_init(lf->lf_full_file_name, NULL); } - if (fw->fwr_file[lf->lf_id] == NULL) + if (fw->fwr_file == NULL) { fprintf(stderr, "Error : opening logfile %s failed.\n", lf->lf_full_file_name); rv = false; @@ -2511,7 +2504,6 @@ static bool file_is_symlink(char* filename) * * Parameters: * @param logfile log file - * @param logfile_id identifier for log file * @param logmanager log manager pointer * @param store_shmem flag to indicate whether log is physically written to shmem * @param write_syslog flag to indicate whether log is also written to syslog @@ -2519,7 +2511,6 @@ static bool file_is_symlink(char* filename) * @return true if succeed, false otherwise */ static bool logfile_init(logfile_t* logfile, - logfile_id_t logfile_id, logmanager_t* logmanager, bool store_shmem, bool write_syslog) @@ -2532,9 +2523,8 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_chk_tail = CHK_NUM_LOGFILE; #endif logfile->lf_logmes = logmanager->lm_logmes; - logfile->lf_id = logfile_id; - logfile->lf_name_prefix = fname_conf_get_prefix(fn, logfile_id); - logfile->lf_name_suffix = fname_conf_get_suffix(fn, logfile_id); + logfile->lf_name_prefix = fname_conf_get_prefix(fn, LOGFILE_ERROR); + logfile->lf_name_suffix = fname_conf_get_suffix(fn, LOGFILE_ERROR); logfile->lf_npending_writes = 0; logfile->lf_name_seqno = 1; logfile->lf_lmgr = logmanager; @@ -2607,14 +2597,14 @@ static bool logfile_init(logfile_t* logfile, if (store_shmem && !use_stdout) { fprintf(stderr, "%s\t: %s->%s\n", - STRLOGNAME(logfile_id), + STRLOGNAME(LOGFILE_ERROR), logfile->lf_full_link_name, logfile->lf_full_file_name); } else if (!use_stdout) { fprintf(stderr, "%s\t: %s\n", - STRLOGNAME(logfile_id), + STRLOGNAME(LOGFILE_ERROR), logfile->lf_full_file_name); } #endif @@ -2756,11 +2746,11 @@ static void filewriter_done(filewriter_t* fw) fw->fwr_clientmes = NULL; if (use_stdout) { - skygw_file_free(fw->fwr_file[LOGFILE_ERROR]); + skygw_file_free(fw->fwr_file); } else { - skygw_file_close(fw->fwr_file[LOGFILE_ERROR], true); + skygw_file_close(fw->fwr_file, true); } fw->fwr_state = DONE; case DONE: @@ -2770,14 +2760,14 @@ static void filewriter_done(filewriter_t* fw) } } -static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr, logfile_id_t id) +static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) { /** * Get file pointer of current logfile. */ bool do_flushall = thr_flushall_check(); - skygw_file_t *file = fwr->fwr_file[id]; - logfile_t *lf = &lm->lm_logfile[id]; + skygw_file_t *file = fwr->fwr_file; + logfile_t *lf = &lm->lm_logfile; /** * read and reset logfile's flush- and rotateflag @@ -2873,12 +2863,12 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr, logfile_id_t id) "Error : Write to %s log " ": %s failed due to %d, " "%s. Disabling the log.", - STRLOGNAME(id), + STRLOGNAME(LOGFILE_ERROR), lf->lf_full_file_name, err, strerror_r(err, errbuf, sizeof(errbuf))); /** Force log off */ - skygw_log_disable_raw(id, true); + skygw_log_disable_raw(LOGFILE_ERROR, true); } /** * Reset buffer's counters and mark @@ -3004,7 +2994,7 @@ static void* thr_filewriter_fun(void* data) while (!done) { - done = thr_flush_file(lm, fwr, LOGFILE_ERROR); + done = thr_flush_file(lm, fwr); if (!thr_flushall_check() && skygw_thread_must_exit(thr)) { diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index f9b586a0c..2fa094ffb 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -408,9 +408,6 @@ typedef enum skygw_chk_t { lf->lf_name_suffix != NULL && \ lf->lf_full_file_name != NULL, \ "NULL in name variable\n"); \ - ss_info_dassert(lf->lf_id >= LOGFILE_FIRST && \ - lf->lf_id <= LOGFILE_LAST, \ - "Invalid logfile id\n"); \ ss_debug( \ (lf->lf_chk_top != CHK_NUM_LOGFILE || \ lf->lf_chk_tail != CHK_NUM_LOGFILE ? \ From d6230e68ef6bcfcf9d53a02c5a418ad4098735c3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 10:09:37 +0200 Subject: [PATCH 098/179] Moved warnings about session command history limits to message log. --- server/modules/routing/readwritesplit/readwritesplit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 15ad5ca42..dfbc6a01d 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4544,7 +4544,7 @@ static bool route_session_write( if (router_cli_ses->rses_config.rw_max_sescmd_history_size > 0 && router_cli_ses->rses_nsescmd >= router_cli_ses->rses_config.rw_max_sescmd_history_size) { - skygw_log_write(LE, "Warning: Router session exceeded session command history limit. " + skygw_log_write(LM, "Warning: Router session exceeded session command history limit. " "Slave recovery is disabled and only slave servers with consistent session state are used " "for the duration of the session."); router_cli_ses->rses_config.rw_disable_sescmd_hist = true; From d57b4cd531fd50dd92eb090b4c1b04f5f4b9a774 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 11:03:47 +0200 Subject: [PATCH 099/179] Fix to MXS-54: https://mariadb.atlassian.net/browse/MXS-54 Added a new configuration parameter that allows the user to control whether authentication warning messages are logged. --- .../Getting-Started/Configuration-Guide.md | 6 +++ server/core/config.c | 16 ++++++ server/core/dbusers.c | 51 ++++++++++--------- server/core/service.c | 3 +- server/include/service.h | 2 +- server/modules/protocol/mysql_client.c | 4 +- 6 files changed, 54 insertions(+), 28 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 7b145d7cb..b41d51391 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -371,6 +371,12 @@ Enabling this feature will transform wildcard grants to individual database gran The retry_on_failure parameter controls whether MaxScale will try to restart failed services and accepts a boolean value. This functionality is enabled by default to prevent services being permanently disabled if the starting of the service failed due to a network outage. Disabling the restarting of the failed services will cause them to be permanently disabled if the services can't be started when MaxScale is started. +#### `log_auth_warnings` + +Enable or disable the logging of authentication failures and warnings. This parameter takes a boolean value. + +MaxScale normally suppresses warning messages about failed authentication. Enabling this option will log those messages into the message log with details about who tried to connect to MaxScale and from where. + #### `connection_timeout` The connection_timeout parameter is used to disconnect sessions to MaxScale that have been idle for too long. The session timeouts are disabled by default. To enable them, define the timeout in seconds in the service's configuration section. diff --git a/server/core/config.c b/server/core/config.c index 457e257af..eb5ed0109 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -498,6 +498,13 @@ process_config_context(CONFIG_CONTEXT *context) subservices, 1,STRING_TYPE); } + char *log_auth_warnings = config_get_value(obj->parameters, + "log_auth_warnings"); + int truthval; + if (log_auth_warnings && (truthval = config_truth_value(log_auth_warnings)) != -1) + { + ((SERVICE*) obj->element)->log_auth_warnings = (bool) truthval; + } CONFIG_PARAMETER* param; if((param = config_get_param(obj->parameters, "ignore_databases"))) @@ -1781,6 +1788,14 @@ SERVER *server; version_string = config_get_value(obj->parameters, "version_string"); allow_localhost_match_wildcard_host = config_get_value(obj->parameters, "localhost_match_wildcard_host"); + char *log_auth_warnings = config_get_value(obj->parameters, + "log_auth_warnings"); + int truthval; + if (log_auth_warnings && (truthval = config_truth_value(log_auth_warnings)) != -1) + { + service->log_auth_warnings = (bool)truthval; + } + CONFIG_PARAMETER* param; if((param = config_get_param(obj->parameters, "ignore_databases"))) @@ -2199,6 +2214,7 @@ static char *service_params[] = "ssl_cert_verify_depth", "ignore_databases", "ignore_databases_regex", + "log_auth_warnings", NULL }; diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 95500691f..721f9c4ab 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -1122,19 +1122,21 @@ getAllUsers(SERVICE *service, USERS *users) } else if(rc == -1) { /** Duplicate user*/ - LOGIF(LT,(skygw_log_write(LT, - "Duplicate MySQL user found for service [%s]: %s@%s%s%s", - service->name, - row[0],row[1],havedb?" for database: ":"", - havedb ?dbnm:""))); + if (service->log_auth_warnings) + { + skygw_log_write(LM, "Duplicate MySQL user found for service" + " [%s]: %s@%s%s%s", service->name, row[0], + row[1], havedb ? " for database: " : "", + havedb ? dbnm : ""); + } } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR|LOGFILE_TRACE, - "Warning: Failed to add user %s@%s for service [%s]. " - "This user will be unavailable via MaxScale.", - row[0], - row[1], - service->name))); + if (service->log_auth_warnings) + { + skygw_log_write_flush(LM, "Warning: Failed to add user %s@%s" + " for service [%s]. This user will be " + "unavailable via MaxScale.", row[0], + row[1], service->name); + } } } @@ -1657,19 +1659,20 @@ getUsers(SERVICE *service, USERS *users) } else if(rc == -1) { /** Duplicate user*/ - LOGIF(LE,(skygw_log_write(LT|LE, - "Warning: Duplicate MySQL user found for service [%s]: %s@%s%s%s", - service->name, - row[0],row[1],db_grants?" for database: ":"", - db_grants ?row[5]:""))); + if (service->log_auth_warnings) + { + skygw_log_write(LM, "Warning: Duplicate MySQL user found for " + "service [%s]: %s@%s%s%s", service->name, row[0], + row[1], db_grants ? " for database: " : "", + db_grants ? row[5] : ""); + } } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR|LOGFILE_TRACE, - "Warning: Failed to add user %s@%s for service [%s]. " - "This user will be unavailable via MaxScale.", - row[0], - row[1], - service->name))); + if (service->log_auth_warnings) + { + skygw_log_write_flush(LM, "Warning: Failed to add user %s@%s for" + " service [%s]. This user will be unavailable" + " via MaxScale.", row[0], row[1], service->name); + } } } diff --git a/server/core/service.c b/server/core/service.c index 617ee7926..4ee1394eb 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -149,6 +149,7 @@ SERVICE *service; service->ssl_ca_cert = NULL; service->ssl_cert = NULL; service->ssl_key = NULL; + service->log_auth_warnings = true; service->ssl_cert_verify_depth = DEFAULT_SSL_CERT_VERIFY_DEPTH; /** Support the highest possible SSL/TLS methods available as the default */ service->ssl_method_type = SERVICE_SSL_TLS_MAX; @@ -2118,4 +2119,4 @@ void service_interal_restart(void *data) { SERVICE* service = (SERVICE*)data; serviceStartAllPorts(service); -} \ No newline at end of file +} diff --git a/server/include/service.h b/server/include/service.h index 7064468df..da72a781a 100644 --- a/server/include/service.h +++ b/server/include/service.h @@ -192,7 +192,7 @@ typedef struct service { char* ssl_ca_cert; /*< SSL CA certificate */ bool ssl_init_done; /*< If SSL has already been initialized for this service */ bool retry_start; /*< If starting of the service should be retried later */ - + bool log_auth_warnings; /*< Log authentication failures and warnings */ } SERVICE; typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t; diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index db580e69a..025a519d3 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -599,8 +599,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { /* on succesful auth set user into dcb field */ if (auth_ret == 0) { dcb->user = strdup(client_data->user); - } - else + } + else if (dcb->service->log_auth_warnings) { skygw_log_write(LM, "%s: login attempt for user '%s', authentication failed.", dcb->service->name, username); From d7af979ad910f996321c678f4a731ae78d67ae25 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 4 Nov 2015 09:08:49 +0200 Subject: [PATCH 100/179] Removed obsolete functionality. No need for debug, trace or messages prefixes or suffixes. --- log_manager/log_manager.cc | 148 +++---------------------------------- log_manager/log_manager.h | 4 - 2 files changed, 11 insertions(+), 141 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 187962b7a..65b9d7674 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -206,12 +206,6 @@ struct fnames_conf skygw_chk_t fn_chk_top; #endif flat_obj_state_t fn_state; - char* fn_debug_prefix; - char* fn_debug_suffix; - char* fn_trace_prefix; - char* fn_trace_suffix; - char* fn_msg_prefix; - char* fn_msg_suffix; char* fn_err_prefix; char* fn_err_suffix; char* fn_logpath; @@ -275,8 +269,8 @@ static void filewriter_done(filewriter_t* filewriter); static bool fnames_conf_init(fnames_conf_t* fn, int argc, char* argv[]); static void fnames_conf_done(fnames_conf_t* fn); static void fnames_conf_free_memory(fnames_conf_t* fn); -static char* fname_conf_get_prefix(fnames_conf_t* fn, logfile_id_t id); -static char* fname_conf_get_suffix(fnames_conf_t* fn, logfile_id_t id); +static char* fname_conf_get_prefix(fnames_conf_t* fn); +static char* fname_conf_get_suffix(fnames_conf_t* fn); static void* thr_filewriter_fun(void* data); static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); @@ -317,36 +311,6 @@ const char* get_suffix_default(void) return ".log"; } -const char* get_debug_prefix_default(void) -{ - return "debug"; -} - -const char* get_debug_suffix_default(void) -{ - return get_suffix_default(); -} - -const char* get_trace_prefix_default(void) -{ - return "trace"; -} - -const char* get_trace_suffix_default(void) -{ - return get_suffix_default(); -} - -const char* get_msg_prefix_default(void) -{ - return "messages"; -} - -const char* get_msg_suffix_default(void) -{ - return get_suffix_default(); -} - const char* get_err_prefix_default(void) { return "error"; @@ -1746,12 +1710,6 @@ static bool fnames_conf_init(fnames_conf_t* fn, bool succp = false; const char* argstr = "-h - help\n" - "-a ............(\"skygw_debug\")\n" - "-b ............(\".log\")\n" - "-c ............(\"skygw_trace\")\n" - "-d ............(\".log\")\n" - "-e ............(\"skygw_msg\")\n" - "-f ............(\".log\")\n" "-g ............(\"skygw_err\")\n" "-i ............(\".log\")\n" "-j ............(\"/tmp\")\n" @@ -1776,28 +1734,6 @@ static bool fnames_conf_init(fnames_conf_t* fn, case 'o': use_stdout = 1; break; - case 'a': - fn->fn_debug_prefix = strndup(optarg, MAX_PREFIXLEN); - break; - - case 'b': - fn->fn_debug_suffix = strndup(optarg, MAX_SUFFIXLEN); - break; - case 'c': - fn->fn_trace_prefix = strndup(optarg, MAX_PREFIXLEN); - break; - - case 'd': - fn->fn_trace_suffix = strndup(optarg, MAX_SUFFIXLEN); - break; - - case 'e': - fn->fn_msg_prefix = strndup(optarg, MAX_PREFIXLEN); - break; - - case 'f': - fn->fn_msg_suffix = strndup(optarg, MAX_SUFFIXLEN); - break; case 'g': fn->fn_err_prefix = strndup(optarg, MAX_PREFIXLEN); @@ -1842,18 +1778,6 @@ static bool fnames_conf_init(fnames_conf_t* fn, } /** switch (opt) */ } /** If log file name is not specified in call arguments, use default. */ - fn->fn_debug_prefix = (fn->fn_debug_prefix == NULL) ? - strdup(get_debug_prefix_default()) : fn->fn_debug_prefix; - fn->fn_debug_suffix = (fn->fn_debug_suffix == NULL) ? - strdup(get_debug_suffix_default()) : fn->fn_debug_suffix; - fn->fn_trace_prefix = (fn->fn_trace_prefix == NULL) ? - strdup(get_trace_prefix_default()) : fn->fn_trace_prefix; - fn->fn_trace_suffix = (fn->fn_trace_suffix == NULL) ? - strdup(get_trace_suffix_default()) : fn->fn_trace_suffix; - fn->fn_msg_prefix = (fn->fn_msg_prefix == NULL) ? - strdup(get_msg_prefix_default()) : fn->fn_msg_prefix; - fn->fn_msg_suffix = (fn->fn_msg_suffix == NULL) ? - strdup(get_msg_suffix_default()) : fn->fn_msg_suffix; fn->fn_err_prefix = (fn->fn_err_prefix == NULL) ? strdup(get_err_prefix_default()) : fn->fn_err_prefix; fn->fn_err_suffix = (fn->fn_err_suffix == NULL) ? @@ -1908,60 +1832,16 @@ return_conf_init: } -static char* fname_conf_get_prefix(fnames_conf_t* fn, logfile_id_t id) +static char* fname_conf_get_prefix(fnames_conf_t* fn) { CHK_FNAMES_CONF(fn); - ss_dassert(id >= LOGFILE_FIRST && id <= LOGFILE_LAST); - - switch (id) - { - case LOGFILE_DEBUG: - return strdup(fn->fn_debug_prefix); - break; - - case LOGFILE_TRACE: - return strdup(fn->fn_trace_prefix); - break; - - case LOGFILE_MESSAGE: - return strdup(fn->fn_msg_prefix); - break; - - case LOGFILE_ERROR: - return strdup(fn->fn_err_prefix); - break; - - default: - return NULL; - } + return strdup(fn->fn_err_prefix); } -static char* fname_conf_get_suffix(fnames_conf_t* fn, logfile_id_t id) +static char* fname_conf_get_suffix(fnames_conf_t* fn) { CHK_FNAMES_CONF(fn); - ss_dassert(id >= LOGFILE_FIRST && id <= LOGFILE_LAST); - - switch (id) - { - case LOGFILE_DEBUG: - return strdup(fn->fn_debug_suffix); - break; - - case LOGFILE_TRACE: - return strdup(fn->fn_trace_suffix); - break; - - case LOGFILE_MESSAGE: - return strdup(fn->fn_msg_suffix); - break; - - case LOGFILE_ERROR: - return strdup(fn->fn_err_suffix); - break; - - default: - return NULL; - } + return strdup(fn->fn_err_suffix); } @@ -2523,8 +2403,8 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_chk_tail = CHK_NUM_LOGFILE; #endif logfile->lf_logmes = logmanager->lm_logmes; - logfile->lf_name_prefix = fname_conf_get_prefix(fn, LOGFILE_ERROR); - logfile->lf_name_suffix = fname_conf_get_suffix(fn, LOGFILE_ERROR); + logfile->lf_name_prefix = fname_conf_get_prefix(fn); + logfile->lf_name_suffix = fname_conf_get_suffix(fn); logfile->lf_npending_writes = 0; logfile->lf_name_seqno = 1; logfile->lf_lmgr = logmanager; @@ -3038,15 +2918,9 @@ static void fnames_conf_done(fnames_conf_t* fn) static void fnames_conf_free_memory(fnames_conf_t* fn) { - if (fn->fn_debug_prefix != NULL) free(fn->fn_debug_prefix); - if (fn->fn_debug_suffix!= NULL) free(fn->fn_debug_suffix); - if (fn->fn_trace_prefix != NULL) free(fn->fn_trace_prefix); - if (fn->fn_trace_suffix!= NULL) free(fn->fn_trace_suffix); - if (fn->fn_msg_prefix != NULL) free(fn->fn_msg_prefix); - if (fn->fn_msg_suffix != NULL) free(fn->fn_msg_suffix); - if (fn->fn_err_prefix != NULL) free(fn->fn_err_prefix); - if (fn->fn_err_suffix != NULL) free(fn->fn_err_suffix); - if (fn->fn_logpath != NULL) free(fn->fn_logpath); + free(fn->fn_err_prefix); + free(fn->fn_err_suffix); + free(fn->fn_logpath); } /** diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index cba349695..89a05d5bc 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -174,10 +174,6 @@ int skygw_log_get_augmentation(); EXTERN_C_BLOCK_END -const char* get_trace_prefix_default(void); -const char* get_trace_suffix_default(void); -const char* get_msg_prefix_default(void); -const char* get_msg_suffix_default(void); const char* get_err_prefix_default(void); const char* get_err_suffix_default(void); const char* get_logpath_default(void); From 865162dc549fa60d4793eb30ebd68ce640445c27 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 4 Nov 2015 10:20:59 +0200 Subject: [PATCH 101/179] Removed getopt options. --- log_manager/log_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 65b9d7674..f409f4b09 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1727,7 +1727,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, fn->fn_chk_tail = CHK_NUM_FNAMES; #endif optind = 1; /** Date: Wed, 4 Nov 2015 11:00:38 +0200 Subject: [PATCH 102/179] More obsolete functionality removed. The log manager possibility for explicitly specifying the names of the log files has never been used. In the name of simplicity that functionality is removed. --- log_manager/log_manager.cc | 91 +++++++------------------------------- log_manager/log_manager.h | 2 - 2 files changed, 15 insertions(+), 78 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index f409f4b09..7444cb393 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -43,6 +43,9 @@ # define _GNU_SOURCE #endif +static const char LOGFILE_NAME_PREFIX[] = "error"; +static const char LOGFILE_NAME_SUFFIX[] = ".log"; + extern char *program_invocation_name; extern char *program_invocation_short_name; @@ -180,8 +183,8 @@ struct logfile skygw_message_t* lf_logmes; char* lf_filepath; /**< path to file used for logging */ char* lf_linkpath; /**< path to symlink file. */ - char* lf_name_prefix; - char* lf_name_suffix; + const char* lf_name_prefix; + const char* lf_name_suffix; int lf_name_seqno; char* lf_full_file_name; /**< complete log file name */ char* lf_full_link_name; /**< complete symlink name */ @@ -206,8 +209,6 @@ struct fnames_conf skygw_chk_t fn_chk_top; #endif flat_obj_state_t fn_state; - char* fn_err_prefix; - char* fn_err_suffix; char* fn_logpath; #if defined(SS_DEBUG) skygw_chk_t fn_chk_tail; @@ -242,7 +243,7 @@ struct logmanager typedef struct strpart { - char* sp_string; + const char* sp_string; struct strpart* sp_next; } strpart_t; @@ -269,8 +270,6 @@ static void filewriter_done(filewriter_t* filewriter); static bool fnames_conf_init(fnames_conf_t* fn, int argc, char* argv[]); static void fnames_conf_done(fnames_conf_t* fn); static void fnames_conf_free_memory(fnames_conf_t* fn); -static char* fname_conf_get_prefix(fnames_conf_t* fn); -static char* fname_conf_get_suffix(fnames_conf_t* fn); static void* thr_filewriter_fun(void* data); static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); @@ -306,21 +305,6 @@ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); void flushall_logfiles(bool flush); bool thr_flushall_check(); -const char* get_suffix_default(void) -{ - return ".log"; -} - -const char* get_err_prefix_default(void) -{ - return "error"; -} - -const char* get_err_suffix_default(void) -{ - return get_suffix_default(); -} - const char* get_logpath_default(void) { return "/var/log/maxscale"; @@ -1710,8 +1694,6 @@ static bool fnames_conf_init(fnames_conf_t* fn, bool succp = false; const char* argstr = "-h - help\n" - "-g ............(\"skygw_err\")\n" - "-i ............(\".log\")\n" "-j ............(\"/tmp\")\n" "-l .......(no default)\n" "-m ............(argv[0])\n" @@ -1727,7 +1709,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, fn->fn_chk_tail = CHK_NUM_FNAMES; #endif optind = 1; /**fn_err_prefix = strndup(optarg, MAX_PREFIXLEN); - break; - - case 'i': - fn->fn_err_suffix = strndup(optarg, MAX_SUFFIXLEN); - break; - case 'j': fn->fn_logpath = strndup(optarg, MAX_PATHLEN); break; @@ -1778,12 +1752,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, } /** switch (opt) */ } /** If log file name is not specified in call arguments, use default. */ - fn->fn_err_prefix = (fn->fn_err_prefix == NULL) ? - strdup(get_err_prefix_default()) : fn->fn_err_prefix; - fn->fn_err_suffix = (fn->fn_err_suffix == NULL) ? - strdup(get_err_suffix_default()) : fn->fn_err_suffix; - fn->fn_logpath = (fn->fn_logpath == NULL) ? - strdup(get_logpath_default()) : fn->fn_logpath; + fn->fn_logpath = (fn->fn_logpath == NULL) ? strdup(get_logpath_default()) : fn->fn_logpath; /** Set identity string for syslog if it is not set in config.*/ if (do_syslog) @@ -1801,22 +1770,10 @@ static bool fnames_conf_init(fnames_conf_t* fn, ss_dfprintf(stderr, "\n");*/ #if defined(NOT_USED) fprintf(stderr, - "Error log :\t%s/%s1%s\n" - "Message log :\t%s/%s1%s\n" - "Trace log :\t%s/%s1%s\n" - "Debug log :\t%s/%s1%s\n\n", + "Log :\t%s/%s1%s\n\n", fn->fn_logpath, - fn->fn_err_prefix, - fn->fn_err_suffix, - fn->fn_logpath, - fn->fn_msg_prefix, - fn->fn_msg_suffix, - fn->fn_logpath, - fn->fn_trace_prefix, - fn->fn_trace_suffix, - fn->fn_logpath, - fn->fn_debug_prefix, - fn->fn_debug_suffix); + LOGFILE_NAME_PREFIX, + LOGFILE_NAME_SUFFIX); #endif succp = true; fn->fn_state = RUN; @@ -1832,19 +1789,6 @@ return_conf_init: } -static char* fname_conf_get_prefix(fnames_conf_t* fn) -{ - CHK_FNAMES_CONF(fn); - return strdup(fn->fn_err_prefix); -} - -static char* fname_conf_get_suffix(fnames_conf_t* fn) -{ - CHK_FNAMES_CONF(fn); - return strdup(fn->fn_err_suffix); -} - - /** * @node Calls logfile initializer for each logfile. * @@ -2152,7 +2096,7 @@ static char* form_full_file_name(strpart_t* parts, logfile_t* lf, int seqnoidx) { int file_sn; int link_sn = 0; - char* tmp = parts[0].sp_string; + const char* tmp = parts[0].sp_string; file_sn = find_last_seqno(parts, lf->lf_name_seqno, seqnoidx); @@ -2403,8 +2347,8 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_chk_tail = CHK_NUM_LOGFILE; #endif logfile->lf_logmes = logmanager->lm_logmes; - logfile->lf_name_prefix = fname_conf_get_prefix(fn); - logfile->lf_name_suffix = fname_conf_get_suffix(fn); + logfile->lf_name_prefix = LOGFILE_NAME_PREFIX; + logfile->lf_name_suffix = LOGFILE_NAME_SUFFIX; logfile->lf_npending_writes = 0; logfile->lf_name_seqno = 1; logfile->lf_lmgr = logmanager; @@ -2544,13 +2488,10 @@ static void logfile_done(logfile_t* lf) } } -static void logfile_free_memory( - logfile_t* lf) +static void logfile_free_memory(logfile_t* lf) { if (lf->lf_filepath != NULL) free(lf->lf_filepath); if (lf->lf_linkpath != NULL) free(lf->lf_linkpath); - if (lf->lf_name_prefix != NULL) free(lf->lf_name_prefix); - if (lf->lf_name_suffix != NULL) free(lf->lf_name_suffix); if (lf->lf_full_link_name != NULL) free(lf->lf_full_link_name); if (lf->lf_full_file_name != NULL) free(lf->lf_full_file_name); } @@ -2918,8 +2859,6 @@ static void fnames_conf_done(fnames_conf_t* fn) static void fnames_conf_free_memory(fnames_conf_t* fn) { - free(fn->fn_err_prefix); - free(fn->fn_err_suffix); free(fn->fn_logpath); } diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 89a05d5bc..1abfbeb1b 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -174,8 +174,6 @@ int skygw_log_get_augmentation(); EXTERN_C_BLOCK_END -const char* get_err_prefix_default(void); -const char* get_err_suffix_default(void); const char* get_logpath_default(void); /** From 126b4c1d79a9ef5af81801b4927300bfe6d7bc71 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 4 Nov 2015 12:14:43 +0200 Subject: [PATCH 103/179] Whitespace-fixes of maxkeys and maxpasswd. Whitespace and indentation fixes of maxkeys.c and maxpasswd.c. No other changes. --- server/core/maxkeys.c | 67 +++++++++++++------------- server/core/maxpasswd.c | 101 +++++++++++++++++++++------------------- 2 files changed, 86 insertions(+), 82 deletions(-) diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 27b5c8382..00f5d626d 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -22,13 +22,13 @@ * @verbatim * Revision History * - * Date Who Description - * 24/07/13 Mark Riddoch Initial implementation + * Date Who Description + * 24/07/13 Mark Riddoch Initial implementation * * @endverbatim */ -#include -#include +#include +#include #include #include #include @@ -41,40 +41,39 @@ int main(int argc, char **argv) char** arg_vector; int rval = 0; - if (argc < 2) - { - keyfile = "/var/lib/maxscale/"; - fprintf(stderr, "Generating .secrets file in /var/lib/maxscale/ ...\n"); - } - else - { - keyfile = argv[1]; - } - arg_vector = malloc(sizeof(char*)*(arg_count + 1)); + if (argc < 2) + { + keyfile = "/var/lib/maxscale/"; + fprintf(stderr, "Generating .secrets file in /var/lib/maxscale/ ...\n"); + } + else + { + keyfile = argv[1]; + } + arg_vector = malloc(sizeof(char*) * (arg_count + 1)); - if(arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation failed.\n"); - return 1; - } + if (arg_vector == NULL) + { + fprintf(stderr,"Error: Memory allocation failed.\n"); + return 1; + } - arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - arg_vector[2] = "/var/log/maxscale/maxkeys"; - arg_vector[3] = "-o"; - arg_vector[4] = NULL; - skygw_logmanager_init(arg_count,arg_vector); - free(arg_vector); - + arg_vector[0] = "logmanager"; + arg_vector[1] = "-j"; + arg_vector[2] = "/var/log/maxscale/maxkeys"; + arg_vector[3] = "-o"; + arg_vector[4] = NULL; + skygw_logmanager_init(arg_count, arg_vector); + free(arg_vector); - if (secrets_writeKeys(keyfile)) - { - fprintf(stderr, "Failed to encode the password\n"); - rval = 1; - } + if (secrets_writeKeys(keyfile)) + { + fprintf(stderr, "Failed to encode the password\n"); + rval = 1; + } - skygw_log_sync_all(); - skygw_logmanager_done(); + skygw_log_sync_all(); + skygw_logmanager_done(); return rval; } diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 0a3d5ddea..b88109ddf 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -22,74 +22,79 @@ * @verbatim * Revision History * - * Date Who Description - * 24/07/13 Mark Riddoch Initial implementation + * Date Who Description + * 24/07/13 Mark Riddoch Initial implementation * * @endverbatim */ -#include -#include +#include +#include #include #include /** * Encrypt a password for storing in the MaxScale.cnf file * - * @param argc Argument count - * @param argv Argument vector + * @param argc Argument count + * @param argv Argument vector */ int main(int argc, char **argv) { - char *enc, *pw; - int arg_count = 6; - char *home; + char *enc; + char *pw; + int arg_count = 6; + char *home; char** arg_vector; - int rval = 0; + int rval = 0; - if (argc != 3) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } + if (argc != 3) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } - arg_vector = malloc(sizeof(char*)*(arg_count + 1)); + arg_vector = malloc(sizeof(char*) * (arg_count + 1)); - if(arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation failed.\n"); - return 1; - } + if (arg_vector == NULL) + { + fprintf(stderr,"Error: Memory allocation failed.\n"); + return 1; + } - arg_vector[0] = strdup("logmanager"); - arg_vector[1] = strdup("-j"); - arg_vector[2] = strdup("/var/log/maxscale"); + arg_vector[0] = strdup("logmanager"); + arg_vector[1] = strdup("-j"); + arg_vector[2] = strdup("/var/log/maxscale"); - arg_vector[3] = "-o"; - arg_vector[4] = "-l"; - arg_vector[5] = "LOGFILE_ERROR"; - arg_vector[6] = NULL; - skygw_logmanager_init(arg_count,arg_vector); - free(arg_vector[2]); - free(arg_vector); - - pw = calloc(81,sizeof(char)); + arg_vector[3] = "-o"; + arg_vector[4] = "-l"; + arg_vector[5] = "LOGFILE_ERROR"; + arg_vector[6] = NULL; + skygw_logmanager_init(arg_count, arg_vector); + free(arg_vector[2]); + free(arg_vector); - if(pw == NULL){ - fprintf(stderr, "Error: cannot allocate enough memory."); - return 1; - } + pw = calloc(81, sizeof(char)); - strncpy(pw,argv[2],80); + if (pw == NULL) + { + fprintf(stderr, "Error: cannot allocate enough memory."); + return 1; + } - if ((enc = encryptPassword(argv[1],pw)) != NULL){ - printf("%s\n", enc); - }else{ - fprintf(stderr, "Failed to encode the password\n"); - rval = 1; - } + strncpy(pw, argv[2], 80); - free(pw); - skygw_log_sync_all(); - skygw_logmanager_done(); - return rval; + if ((enc = encryptPassword(argv[1], pw)) != NULL) + { + printf("%s\n", enc); + } + else + { + fprintf(stderr, "Failed to encode the password\n"); + rval = 1; + } + + free(pw); + skygw_log_sync_all(); + skygw_logmanager_done(); + return rval; } From 0accf869de36ecb15fb7b7159c5cd0925a96b5d9 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 3 Nov 2015 23:34:12 +0200 Subject: [PATCH 104/179] Fix to MXS-365: https://mariadb.atlassian.net/browse/MXS-365 Added tracking of LOAD DATA LOCAL INFILE While a LOAD DATA LOCAL INFILE query is being executed, all queries will be sent to the master and they will not be processed as normal packets. --- query_classifier/query_classifier.cc | 8 ++ query_classifier/query_classifier.h | 3 +- server/modules/include/readwritesplit.h | 3 + .../routing/readwritesplit/readwritesplit.c | 94 +++++++++++++------ 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index ab41845b4..10ced0a5e 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -1647,6 +1647,11 @@ retblock: skygw_query_op_t query_classifier_get_operation(GWBUF* querybuf) { + if (!query_is_parsed(querybuf)) + { + parse_query(querybuf); + } + LEX* lex = get_lex(querybuf); skygw_query_op_t operation = QUERY_OP_UNDEFINED; if(lex){ @@ -1687,6 +1692,9 @@ skygw_query_op_t query_classifier_get_operation(GWBUF* querybuf) case SQLCOM_CHANGE_DB: operation = QUERY_OP_CHANGE_DB; break; + case SQLCOM_LOAD: + operation = QUERY_OP_LOAD; + break; default: operation = QUERY_OP_UNDEFINED; diff --git a/query_classifier/query_classifier.h b/query_classifier/query_classifier.h index d59f82fad..e49022647 100644 --- a/query_classifier/query_classifier.h +++ b/query_classifier/query_classifier.h @@ -75,7 +75,8 @@ typedef enum { QUERY_OP_CREATE_INDEX = (1 << 8), QUERY_OP_DROP_TABLE = (1 << 9), QUERY_OP_DROP_INDEX = (1 << 10), - QUERY_OP_CHANGE_DB = (1 << 11) + QUERY_OP_CHANGE_DB = (1 << 11), + QUERY_OP_LOAD = (1 << 12) }skygw_query_op_t; typedef struct parsing_info_st { diff --git a/server/modules/include/readwritesplit.h b/server/modules/include/readwritesplit.h index 9f9866e5d..58eb48996 100644 --- a/server/modules/include/readwritesplit.h +++ b/server/modules/include/readwritesplit.h @@ -293,6 +293,9 @@ struct router_client_session { int rses_capabilities; /*< input type, for example */ bool rses_autocommit_enabled; bool rses_transaction_active; + bool rses_load_active; /*< If LOAD DATA LOCAL INFILE is + * being currently executed */ + uint64_t rses_load_data_sent; /*< How much data has been sent */ DCB* client_dcb; int pos_generator; #if defined(PREP_STMT_CACHING) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index dfbc6a01d..304bdd78c 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -106,6 +106,7 @@ static DCB* rses_get_client_dcb(ROUTER_CLIENT_SES* rses); static route_target_t get_route_target ( skygw_query_type_t qtype, bool trx_active, + bool load_active, target_t use_sql_variables_in, HINT* hint); @@ -1370,6 +1371,7 @@ static backend_ref_t* check_candidate_bref( static route_target_t get_route_target ( skygw_query_type_t qtype, bool trx_active, + bool load_active, target_t use_sql_variables_in, HINT* hint) { @@ -1377,7 +1379,7 @@ static route_target_t get_route_target ( /** * These queries are not affected by hints */ - if (QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE) || + if (!load_active && (QUERY_IS_TYPE(qtype, QUERY_TYPE_SESSION_WRITE) || QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_STMT) || QUERY_IS_TYPE(qtype, QUERY_TYPE_PREPARE_NAMED_STMT) || /** Configured to allow writing variables to all nodes */ @@ -1385,7 +1387,7 @@ static route_target_t get_route_target ( QUERY_IS_TYPE(qtype, QUERY_TYPE_GSYSVAR_WRITE)) || /** enable or disable autocommit are always routed to all */ QUERY_IS_TYPE(qtype, QUERY_TYPE_ENABLE_AUTOCOMMIT) || - QUERY_IS_TYPE(qtype, QUERY_TYPE_DISABLE_AUTOCOMMIT)) + QUERY_IS_TYPE(qtype, QUERY_TYPE_DISABLE_AUTOCOMMIT))) { /** * This is problematic query because it would be routed to all @@ -1423,7 +1425,7 @@ static route_target_t get_route_target ( /** * Hints may affect on routing of the following queries */ - else if (!trx_active && + else if (!trx_active && !load_active && (QUERY_IS_TYPE(qtype, QUERY_TYPE_READ) || /*< any SELECT */ QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_TABLES) || /*< 'SHOW TABLES' */ QUERY_IS_TYPE(qtype, QUERY_TYPE_USERVAR_READ)|| /*< read user var */ @@ -2143,8 +2145,13 @@ static bool route_single_stmt( if(packet_len == 0) { + /** Empty packet signals end of LOAD DATA LOCAL INFILE, send it to master*/ route_target = TARGET_MASTER; packet_type = MYSQL_COM_UNDEFINED; + rses->rses_load_active = false; + route_target = TARGET_MASTER; + skygw_log_write_flush(LT, "> LOAD DATA LOCAL INFILE finished: " + "%lu bytes sent.", rses->rses_load_data_sent + gwbuf_length(querybuf)); } else { @@ -2194,17 +2201,36 @@ static bool route_single_stmt( break; } /**< switch by packet type */ - /** - * Check if the query has anything to do with temporary tables. - */ if (!rses_begin_locked_router_action(rses)) { succp = false; goto retblock; - } + } + /** + * Check if the query has anything to do with temporary tables. + */ qtype = is_read_tmp_table(rses, querybuf, qtype); check_create_tmp_table(rses, querybuf, qtype); check_drop_tmp_table(rses, querybuf,qtype); + + /** + * Check if this is a LOAD DATA LOCAL INFILE query. If so, send all queries + * to the master until the last, empty packet arrives. + */ + if (!rses->rses_load_active) + { + skygw_query_op_t queryop = query_classifier_get_operation(querybuf); + if (queryop == QUERY_OP_LOAD) + { + rses->rses_load_active = true; + rses->rses_load_data_sent = 0; + } + } + else + { + rses->rses_load_data_sent += gwbuf_length(querybuf); + } + rses_end_locked_router_action(rses); /** * If autocommit is disabled or transaction is explicitly started @@ -2245,28 +2271,35 @@ static bool route_single_stmt( if (LOG_IS_ENABLED(LOGFILE_TRACE)) { - uint8_t* packet = GWBUF_DATA(querybuf); - unsigned char ptype = packet[4]; - size_t len = MIN(GWBUF_LENGTH(querybuf), - MYSQL_GET_PACKET_LEN((unsigned char *)querybuf->start)-1); - char* data = (char*)&packet[5]; - char* contentstr = strndup(data, MIN(len, RWSPLIT_TRACE_MSG_LEN)); - char* qtypestr = skygw_get_qtype_str(qtype); - - skygw_log_write( - LOGFILE_TRACE, - "> Autocommit: %s, trx is %s, cmd: %s, type: %s, " - "stmt: %s%s %s", - (rses->rses_autocommit_enabled ? "[enabled]" : "[disabled]"), - (rses->rses_transaction_active ? "[open]" : "[not open]"), - STRPACKETTYPE(ptype), - (qtypestr==NULL ? "N/A" : qtypestr), - contentstr, - (querybuf->hint == NULL ? "" : ", Hint:"), - (querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type))); - - free(contentstr); - free(qtypestr); + if (!rses->rses_load_active) + { + uint8_t* packet = GWBUF_DATA(querybuf); + unsigned char ptype = packet[4]; + size_t len = MIN(GWBUF_LENGTH(querybuf), + MYSQL_GET_PACKET_LEN((unsigned char *)querybuf->start) - 1); + char* data = (char*) &packet[5]; + char* contentstr = strndup(data, MIN(len, RWSPLIT_TRACE_MSG_LEN)); + char* qtypestr = skygw_get_qtype_str(qtype); + + skygw_log_write(LOGFILE_TRACE, + "> Autocommit: %s, trx is %s, cmd: %s, type: %s, " + "stmt: %s%s %s", + (rses->rses_autocommit_enabled ? "[enabled]" : "[disabled]"), + (rses->rses_transaction_active ? "[open]" : "[not open]"), + STRPACKETTYPE(ptype), + (qtypestr == NULL ? "N/A" : qtypestr), + contentstr, + (querybuf->hint == NULL ? "" : ", Hint:"), + (querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type))); + + free(contentstr); + free(qtypestr); + } + else + { + skygw_log_write(LT, "> Processing LOAD DATA LOCAL INFILE: " + "%lu bytes sent.", rses->rses_load_data_sent); + } } /** * Find out where to route the query. Result may not be clear; it is @@ -2287,9 +2320,10 @@ static bool route_single_stmt( */ route_target = get_route_target(qtype, rses->rses_transaction_active, + rses->rses_load_active, rses->rses_config.rw_use_sql_variables_in, querybuf->hint); - + if (TARGET_IS_ALL(route_target)) { /** Multiple, conflicting routing target. Return error */ From 834a88aeda1ff148cdd0c504217c2637cf3933c1 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 4 Nov 2015 14:26:53 +0200 Subject: [PATCH 105/179] Log variables moved to log_manager.h The log manager variables lm_enabled_log_files_bitmask, log_ses_count and tls_log_info that earlier were declared separately in every c-file are now declared in the log_manager.h header. --- log_manager/log_manager.h | 4 ++++ query_classifier/query_classifier.cc | 4 ---- server/core/adminusers.c | 4 ---- server/core/buffer.c | 5 ----- server/core/config.c | 5 ----- server/core/dbusers.c | 4 ---- server/core/dcb.c | 5 ----- server/core/externcmd.c | 5 ----- server/core/filter.c | 5 ----- server/core/gateway.c | 10 ---------- server/core/gw_utils.c | 7 +------ server/core/load_utils.c | 5 ----- server/core/modutil.c | 5 ----- server/core/monitor.c | 7 +------ server/core/poll.c | 5 ----- server/core/secrets.c | 4 ---- server/core/server.c | 5 ----- server/core/service.c | 5 ----- server/core/session.c | 5 ----- server/core/utils.c | 5 ----- server/modules/filter/hint/hintparser.c | 5 ----- server/modules/filter/namedserverfilter.c | 5 ----- server/modules/filter/qlafilter.c | 5 ----- server/modules/filter/regexfilter.c | 5 ----- server/modules/filter/slavelag.c | 5 ----- server/modules/filter/tee.c | 7 +------ server/modules/filter/topfilter.c | 5 ----- server/modules/monitor/galeramon.c | 7 +------ server/modules/monitor/mmmon.c | 7 +------ server/modules/monitor/mysql_mon.c | 5 ----- server/modules/monitor/ndbclustermon.c | 7 +------ server/modules/protocol/httpd.c | 5 ----- server/modules/protocol/maxscaled.c | 5 ----- server/modules/protocol/mysql_backend.c | 5 ----- server/modules/protocol/mysql_client.c | 5 ----- server/modules/protocol/mysql_common.c | 5 ----- server/modules/protocol/telnetd.c | 5 ----- server/modules/routing/GaleraHACRoute.c | 2 -- server/modules/routing/binlog/blr.c | 4 ---- server/modules/routing/binlog/blr_cache.c | 5 ----- server/modules/routing/binlog/blr_file.c | 4 ---- server/modules/routing/binlog/blr_master.c | 4 ---- server/modules/routing/binlog/blr_slave.c | 4 ---- server/modules/routing/binlog/maxbinlogcheck.c | 3 --- server/modules/routing/binlog/test/testbinlog.c | 3 --- server/modules/routing/cli.c | 5 ----- server/modules/routing/debugcli.c | 5 ----- server/modules/routing/maxinfo/maxinfo.c | 5 ----- server/modules/routing/maxinfo/maxinfo_error.c | 5 ----- server/modules/routing/maxinfo/maxinfo_exec.c | 4 ---- server/modules/routing/readconnroute.c | 5 ----- server/modules/routing/readwritesplit/readwritesplit.c | 4 ---- server/modules/routing/schemarouter/schemarouter.c | 4 ---- server/modules/routing/schemarouter/sharding_common.c | 5 ----- server/modules/routing/schemarouter/shardrouter.c | 4 ---- 55 files changed, 10 insertions(+), 262 deletions(-) diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 1abfbeb1b..2b838dc13 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -136,6 +136,10 @@ enum log_flush EXTERN_C_BLOCK_BEGIN +extern int lm_enabled_logfiles_bitmask; +extern ssize_t log_ses_count[]; +extern __thread log_info_t tls_log_info; + bool skygw_logmanager_init(int argc, char* argv[]); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 10ced0a5e..25220cb61 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -61,10 +61,6 @@ #include #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - #define QTYPE_LESS_RESTRICTIVE_THAN_WRITE(t) (t #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; /** * @file adminusers.c - Administration user account management diff --git a/server/core/buffer.c b/server/core/buffer.c index 8de0f6851..dca4ffb69 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -47,11 +47,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static buffer_object_t* gwbuf_remove_buffer_object( GWBUF* buf, buffer_object_t* bufobj); diff --git a/server/core/config.c b/server/core/config.c index eb5ed0109..8e152cd41 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -82,11 +82,6 @@ /** According to the PCRE manual, this should be a multiple of 3 */ #define MAXSCALE_PCRE_BUFSZ 24 -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - extern int setipaddress(struct in_addr *, char *); static int process_config_context(CONFIG_CONTEXT *); static int process_config_update(CONFIG_CONTEXT *); diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 721f9c4ab..2dc434329 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -105,10 +105,6 @@ #define ERROR_NO_SHOW_DATABASES "%s: Unable to load database grant information, \ MaxScale authentication will proceed without including database permissions. \ To correct this GRANT SHOW DATABASES ON *.* privilege to the user %s." -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; static int getUsers(SERVICE *service, USERS *users); static int uh_cmpfun( void* v1, void* v2); diff --git a/server/core/dcb.c b/server/core/dcb.c index 19d95a177..f45f682f1 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -82,11 +82,6 @@ #define SSL_ERRBUF_LEN 140 -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static DCB *allDCBs = NULL; /* Diagnostics need a list of DCBs */ static DCB *zombies = NULL; static SPINLOCK dcbspin = SPINLOCK_INIT; diff --git a/server/core/externcmd.c b/server/core/externcmd.c index d58b06351..8e8735ac3 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -1,10 +1,5 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * Tokenize a string into arguments suitable for a execvp call. * @param args Argument string diff --git a/server/core/filter.c b/server/core/filter.c index b8b1d3902..0afeda131 100644 --- a/server/core/filter.c +++ b/server/core/filter.c @@ -38,11 +38,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static SPINLOCK filter_spin = SPINLOCK_INIT; /**< Protects the list of all filters */ static FILTER_DEF *allFilters = NULL; /**< The list of all filters */ diff --git a/server/core/gateway.c b/server/core/gateway.c index 62f5afabc..4cd3aa869 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -101,16 +101,6 @@ time_t MaxScaleStarted; extern char *program_invocation_name; extern char *program_invocation_short_name; -/** - * Variable holding the enabled logfiles information. - * Used from log users to check enabled logs prior calling - * actual library calls such as skygw_log_write. - */ -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /* * Server options are passed to the mysql_server_init. Each gateway must have a unique * data directory that is passed to the mysql_server_init, therefore the data directory diff --git a/server/core/gw_utils.c b/server/core/gw_utils.c index 043a4d645..2950cdc15 100644 --- a/server/core/gw_utils.c +++ b/server/core/gw_utils.c @@ -48,11 +48,6 @@ SPINLOCK tmplock = SPINLOCK_INIT; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /* * Set IP address in socket structure in_addr * @@ -245,4 +240,4 @@ long get_processor_count() #error _SC_NPROCESSORS_ONLN not available. #endif return processors; -} \ No newline at end of file +} diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 7ff97bfa7..50d543261 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -51,11 +51,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static MODULES *registered = NULL; static MODULES *find_module(const char *module); diff --git a/server/core/modutil.c b/server/core/modutil.c index fdf4d4f73..b7c8c467d 100644 --- a/server/core/modutil.c +++ b/server/core/modutil.c @@ -33,11 +33,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** These are used when converting MySQL wildcards to regular expressions */ static SPINLOCK re_lock = SPINLOCK_INIT; static bool pattern_init = false; diff --git a/server/core/monitor.c b/server/core/monitor.c index ef782ed47..f55b78e0c 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -43,11 +43,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static MONITOR *allMonitors = NULL; static SPINLOCK monLock = SPINLOCK_INIT; @@ -526,4 +521,4 @@ bool check_monitor_permissions(MONITOR* monitor) mysql_close(mysql); free(dpasswd); return rval; -} \ No newline at end of file +} diff --git a/server/core/poll.c b/server/core/poll.c index 906682d22..8b6e455ff 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -46,11 +46,6 @@ extern unsigned long hkheartbeat; MEMLOG *plog; #endif -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - int number_poll_spins; int max_poll_sleep; diff --git a/server/core/secrets.c b/server/core/secrets.c index fd4f42ac5..b92398acf 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -24,10 +24,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; /** * Generate a random printable character * diff --git a/server/core/server.c b/server/core/server.c index 34875fe91..919b5bcbe 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -48,11 +48,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static SPINLOCK server_spin = SPINLOCK_INIT; static SERVER *allServers = NULL; diff --git a/server/core/service.c b/server/core/service.c index 4ee1394eb..b77043888 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -66,11 +66,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static RSA *rsa_512 = NULL; static RSA *rsa_1024 = NULL; diff --git a/server/core/session.c b/server/core/session.c index 32c7148e5..f3a7375f6 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -45,11 +45,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** Global session id; updated safely by holding session_spin */ static size_t session_id; diff --git a/server/core/utils.c b/server/core/utils.c index 8b8f4d55f..c5c60a773 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -44,11 +44,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /* used in the hex2bin function */ #define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\ X >= 'A' && X <= 'Z' ? X-'A'+10 :\ diff --git a/server/modules/filter/hint/hintparser.c b/server/modules/filter/hint/hintparser.c index abf2fb141..6556b2a99 100644 --- a/server/modules/filter/hint/hintparser.c +++ b/server/modules/filter/hint/hintparser.c @@ -25,11 +25,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * hintparser.c - Find any comment in the SQL packet and look for MAXSCALE * hints in that comment. diff --git a/server/modules/filter/namedserverfilter.c b/server/modules/filter/namedserverfilter.c index 822b5eaf2..f478e05d2 100644 --- a/server/modules/filter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter.c @@ -25,11 +25,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * @file namedserverfilter.c - a very simple regular expression based filter * that routes to a named server if a regular expression match is found. diff --git a/server/modules/filter/qlafilter.c b/server/modules/filter/qlafilter.c index e03dabf98..94ccdefca 100644 --- a/server/modules/filter/qlafilter.c +++ b/server/modules/filter/qlafilter.c @@ -52,11 +52,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - MODULE_INFO info = { MODULE_API_FILTER, MODULE_GA, diff --git a/server/modules/filter/regexfilter.c b/server/modules/filter/regexfilter.c index c424ec666..732675336 100644 --- a/server/modules/filter/regexfilter.c +++ b/server/modules/filter/regexfilter.c @@ -27,11 +27,6 @@ #include #include "maxconfig.h" -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * @file regexfilter.c - a very simple regular expression rewrite filter. * @verbatim diff --git a/server/modules/filter/slavelag.c b/server/modules/filter/slavelag.c index eb6b9536d..1e9bbaaa2 100644 --- a/server/modules/filter/slavelag.c +++ b/server/modules/filter/slavelag.c @@ -26,11 +26,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * @file slavelag.c - a very simple filter designed to send queries to the * master server after data modification has occurred. This is done to prevent diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 1557166f9..3906367a9 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -96,11 +96,6 @@ static unsigned char required_packets[] = { MYSQL_COM_CONNECT, 0 }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - MODULE_INFO info = { MODULE_API_FILTER, MODULE_GA, @@ -1400,4 +1395,4 @@ int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer) my_session->command = command; return 1; -} \ No newline at end of file +} diff --git a/server/modules/filter/topfilter.c b/server/modules/filter/topfilter.c index 38eab05c6..a8089b830 100644 --- a/server/modules/filter/topfilter.c +++ b/server/modules/filter/topfilter.c @@ -49,11 +49,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - MODULE_INFO info = { MODULE_API_FILTER, MODULE_GA, diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 8e7e7e24b..4b78f30e2 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -42,11 +42,6 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static void monitorMain(void *); static char *version_str = "V2.0.0"; @@ -770,4 +765,4 @@ bool isGaleraEvent(monitor_event_t event) return true; } return false; -} \ No newline at end of file +} diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 3bbb3c588..9abccf153 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -32,11 +32,6 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static void monitorMain(void *); static char *version_str = "V1.1.1"; @@ -753,4 +748,4 @@ bool isMySQLEvent(monitor_event_t event) return true; } return false; -} \ No newline at end of file +} diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index fccd8b767..6a817c505 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -54,11 +54,6 @@ #include #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static void monitorMain(void *); static char *version_str = "V1.4.0"; diff --git a/server/modules/monitor/ndbclustermon.c b/server/modules/monitor/ndbclustermon.c index d3cb40db3..02883c925 100644 --- a/server/modules/monitor/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon.c @@ -33,11 +33,6 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static void monitorMain(void *); static char *version_str = "V2.1.0"; @@ -476,4 +471,4 @@ bool isNdbEvent(monitor_event_t event) return true; } return false; -} \ No newline at end of file +} diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index a9c9c3ded..ef1754040 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -50,11 +50,6 @@ MODULE_INFO info = { "An experimental HTTPD implementation for use in admnistration" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - #define ISspace(x) isspace((int)(x)) #define HTTP_SERVER_STRING "MaxScale(c) v.1.0.0" static char *version_str = "V1.0.1"; diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index 874aa8bbd..e1051c3f2 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -45,11 +45,6 @@ MODULE_INFO info = { "A maxscale protocol for the administration interface" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * @file maxscaled.c - MaxScale administration protocol * diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 391ec0cc7..d4c616a66 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -55,11 +55,6 @@ MODULE_INFO info = { "The MySQL to backend server protocol" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static char *version_str = "V2.0.0"; static int gw_create_backend_connection(DCB *backend, SERVER *server, SESSION *in_session); static int gw_read_backend_event(DCB* dcb); diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 025a519d3..51ca80e89 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -56,11 +56,6 @@ MODULE_INFO info = { "The client to MaxScale MySQL protocol implementation" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static char *version_str = "V1.0.0"; static int gw_MySQLAccept(DCB *listener); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 553af4090..0c6c45179 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -50,11 +50,6 @@ /* The following can be compared using memcmp to detect a null password */ uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN]=""; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - extern int gw_read_backend_event(DCB* dcb); extern int gw_write_backend_event(DCB *dcb); extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue); diff --git a/server/modules/protocol/telnetd.c b/server/modules/protocol/telnetd.c index f70f8c038..ea236dbe2 100644 --- a/server/modules/protocol/telnetd.c +++ b/server/modules/protocol/telnetd.c @@ -45,11 +45,6 @@ MODULE_INFO info = { "A telnet deamon protocol for simple administration interface" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * @file telnetd.c - telnet daemon protocol module * diff --git a/server/modules/routing/GaleraHACRoute.c b/server/modules/routing/GaleraHACRoute.c index 27394c5c8..a14979a31 100644 --- a/server/modules/routing/GaleraHACRoute.c +++ b/server/modules/routing/GaleraHACRoute.c @@ -47,8 +47,6 @@ #include -extern int lm_enabled_logfiles_bitmask; - static char *version_str = "V1.0.0"; /* The router entry points */ diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index c2b5e5c1c..ee55505ad 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -75,10 +75,6 @@ #include #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static char *version_str = "V2.0.0"; /* The router entry points */ diff --git a/server/modules/routing/binlog/blr_cache.c b/server/modules/routing/binlog/blr_cache.c index 400114b9b..63b1e8f9e 100644 --- a/server/modules/routing/binlog/blr_cache.c +++ b/server/modules/routing/binlog/blr_cache.c @@ -53,11 +53,6 @@ #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - - /** * Initialise the cache for this instanceof the binlog router. As a side * effect also determine the binlog file to read and the position to read diff --git a/server/modules/routing/binlog/blr_file.c b/server/modules/routing/binlog/blr_file.c index efb9dc88c..29a15687e 100644 --- a/server/modules/routing/binlog/blr_file.c +++ b/server/modules/routing/binlog/blr_file.c @@ -63,10 +63,6 @@ #include #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static int blr_file_create(ROUTER_INSTANCE *router, char *file); static void blr_file_append(ROUTER_INSTANCE *router, char *file); static void blr_log_header(logfile_id_t file, char *msg, uint8_t *ptr); diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 3ac8086d5..5e8fd7ee1 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -78,10 +78,6 @@ #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static GWBUF *blr_make_query(char *statement); static GWBUF *blr_make_registration(ROUTER_INSTANCE *router); static GWBUF *blr_make_binlog_dump(ROUTER_INSTANCE *router); diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index 5b4aa8962..fcce69ea0 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -154,10 +154,6 @@ static int blr_slave_send_heartbeat(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave void poll_fake_write_event(DCB *dcb); -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * Process a request packet from the slave server. * diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index ece9058ff..12ae8b6ed 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -63,9 +63,6 @@ #include #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; extern int blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug); extern uint32_t extract_field(uint8_t *src, int bits); static void printVersion(const char *progname); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index 3741130be..4143cd517 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -51,9 +51,6 @@ #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; static void printVersion(const char *progname); static void printUsage(const char *progname); extern int blr_test_parse_change_master_command(char *input, char *error_string, CHANGE_MASTER_OPTIONS *config); diff --git a/server/modules/routing/cli.c b/server/modules/routing/cli.c index 5f927cd3c..311c15c3f 100644 --- a/server/modules/routing/cli.c +++ b/server/modules/routing/cli.c @@ -53,11 +53,6 @@ MODULE_INFO info = { "The admin user interface" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static char *version_str = "V1.0.0"; /* The router entry points */ diff --git a/server/modules/routing/debugcli.c b/server/modules/routing/debugcli.c index 635847b42..3467136e6 100644 --- a/server/modules/routing/debugcli.c +++ b/server/modules/routing/debugcli.c @@ -52,11 +52,6 @@ MODULE_INFO info = { "The debug user interface" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static char *version_str = "V1.1.1"; /* The router entry points */ diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 386a4c850..0efe22b63 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -63,11 +63,6 @@ MODULE_INFO info = { "The MaxScale Information Schema" }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - extern char *create_hex_sha1_sha1_passwd(char *passwd); static char *version_str = "V1.0.0"; diff --git a/server/modules/routing/maxinfo/maxinfo_error.c b/server/modules/routing/maxinfo/maxinfo_error.c index dd5a8f233..afb4a6270 100644 --- a/server/modules/routing/maxinfo/maxinfo_error.c +++ b/server/modules/routing/maxinfo/maxinfo_error.c @@ -45,11 +45,6 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * Process a parse error and send error report to client * diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index 6257228f6..d51f81d0d 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -49,10 +49,6 @@ #include #include -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static void exec_show(DCB *dcb, MAXINFO_TREE *tree); static void exec_select(DCB *dcb, MAXINFO_TREE *tree); static void exec_show_variables(DCB *dcb, MAXINFO_TREE *filter); diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index ccb071e1a..8cc75e17a 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -92,11 +92,6 @@ #include "modutil.h" -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - MODULE_INFO info = { MODULE_API_ROUTER, MODULE_GA, diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 304bdd78c..dc52f026a 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -47,10 +47,6 @@ MODULE_INFO info = { #define RWSPLIT_TRACE_MSG_LEN 1000 -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; /** * @file readwritesplit.c The entry points for the read/write query splitting * router module. diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 9bbf6b357..544fa80df 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -52,10 +52,6 @@ MODULE_INFO info = { }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; /** * @file schemarouter.c The entry points for the simple sharding * router module. diff --git a/server/modules/routing/schemarouter/sharding_common.c b/server/modules/routing/schemarouter/sharding_common.c index 813e9f826..201b7ec44 100644 --- a/server/modules/routing/schemarouter/sharding_common.c +++ b/server/modules/routing/schemarouter/sharding_common.c @@ -18,11 +18,6 @@ #include -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - /** * Extract the database name from a COM_INIT_DB or literal USE ... query. * @param buf Buffer with the database change query diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index a9b033962..272f48664 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -46,10 +46,6 @@ MODULE_INFO info = { }; -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; /** * @file shardrouter.c * From 603e73776974785afe7771395ba53813f2ba8bb6 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 5 Nov 2015 09:29:36 +0200 Subject: [PATCH 106/179] Cleaned up testbuffer.c and added a test for gwbuf_clone_all --- server/core/test/testbuffer.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/server/core/test/testbuffer.c b/server/core/test/testbuffer.c index 179300be3..ac768fcbe 100644 --- a/server/core/test/testbuffer.c +++ b/server/core/test/testbuffer.c @@ -68,9 +68,7 @@ int buflen; ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty"); ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined"); ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer"); - char* name = strdup("name"); - hint = hint_create_parameter(NULL, name, "value"); - free(name); + hint = hint_create_parameter(NULL, "name", "value"); gwbuf_add_hint(buffer, hint); ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint"); ss_dfprintf(stderr, "\t..done\nSet a property for the buffer"); @@ -157,7 +155,24 @@ int buflen; ss_info_dassert(100000 == buflen, "Incorrect buffer size"); ss_info_dassert(buffer == extra, "The buffer pointer should now point to the extra buffer"); ss_dfprintf(stderr, "\t..done\n"); - + + /** gwbuf_clone_all test */ + size_t headsize = 10; + GWBUF* head = gwbuf_alloc(headsize); + size_t tailsize = 20; + GWBUF* tail = gwbuf_alloc(tailsize); + + ss_info_dassert(head && tail, "Head and tail buffers should both be non-NULL"); + GWBUF* append = gwbuf_append(head, tail); + ss_info_dassert(append == head, "gwbuf_append should return head"); + ss_info_dassert(append->next == tail, "After append tail should be in the next pointer of head"); + ss_info_dassert(append->tail == tail, "After append tail should be in the tail pointer of head"); + GWBUF* all_clones = gwbuf_clone_all(head); + ss_info_dassert(all_clones && all_clones->next, "Cloning all should work"); + ss_info_dassert(GWBUF_LENGTH(all_clones) == headsize, "First buffer should be 10 bytes"); + ss_info_dassert(GWBUF_LENGTH(all_clones->next) == tailsize, "Second buffer should be 20 bytes"); + ss_info_dassert(gwbuf_length(all_clones) == headsize + tailsize, "Total buffer length should be 30 bytes"); + return 0; } From 548d03005b8389eecc861d180b9f3bd62033e31f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 5 Nov 2015 10:19:24 +0200 Subject: [PATCH 107/179] Added test for maxscale_pcre2.c --- server/core/test/CMakeLists.txt | 3 + server/core/test/testmaxscalepcre2.c | 111 +++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 server/core/test/testmaxscalepcre2.c diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 2d32d55b1..3bd6aee10 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(test_users testusers.c) add_executable(test_adminusers testadminusers.c) add_executable(testmemlog testmemlog.c) add_executable(testfeedback testfeedback.c) +add_executable(testmaxscalepcre2 testmaxscalepcre2.c) target_link_libraries(test_mysql_users MySQLClient fullcore) target_link_libraries(test_hash fullcore log_manager) target_link_libraries(test_hint fullcore log_manager) @@ -29,6 +30,7 @@ target_link_libraries(test_users fullcore) target_link_libraries(test_adminusers fullcore) target_link_libraries(testmemlog fullcore log_manager) target_link_libraries(testfeedback fullcore) +target_link_libraries(testmaxscalepcre2 fullcore log_manager) add_test(Internal-TestMySQLUsers test_mysql_users) add_test(Internal-TestHash test_hash) add_test(Internal-TestHint test_hint) @@ -43,5 +45,6 @@ add_test(Internal-TestServer test_server) add_test(Internal-TestUsers test_users) add_test(Internal-TestAdminUsers test_adminusers) add_test(Internal-TestMemlog testmemlog) +add_test(Internal-TestMaxScalePCRE2 testmaxscalepcre2) add_test(TestFeedback testfeedback) set_tests_properties(TestFeedback PROPERTIES TIMEOUT 30) diff --git a/server/core/test/testmaxscalepcre2.c b/server/core/test/testmaxscalepcre2.c new file mode 100644 index 000000000..c05b070e0 --- /dev/null +++ b/server/core/test/testmaxscalepcre2.c @@ -0,0 +1,111 @@ +/* + * This file is distributed as part of MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright MariaDB Corporation Ab 2015 + */ + +/** + * + * @verbatim + * Revision History + * + * Date Who Description + * 05-11-2015 Markus Makela Initial implementation + * + * @endverbatim + */ + +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#ifndef SS_DEBUG +#define SS_DEBUG +#endif +#ifdef NDEBUG +#undef NDEBUG +#endif + +#include +#include +#include +#include +#include + +#define test_assert(a, b) if(!(a)){fprintf(stderr, b);return 1;} + +/** + * Test PCRE2 regular expression simple matching function test + */ +static int test1() +{ + int error = 0; + mxs_pcre2_result_t result = mxs_pcre2_simple_match("brown.*dog", "The quick brown fox jumps over the lazy dog", 0, &error); + test_assert(result == MXS_PCRE2_MATCH, "Pattern should match"); + error = 0; + result = mxs_pcre2_simple_match("BROWN.*DOG", "The quick brown fox jumps over the lazy dog", PCRE2_CASELESS, &error); + test_assert(result == MXS_PCRE2_MATCH, "Pattern should match with PCRE2_CASELESS option"); + error = 0; + result = mxs_pcre2_simple_match("black.*dog", "The quick brown fox jumps over the lazy dog", 0, &error); + test_assert(result == MXS_PCRE2_NOMATCH && error == 0, "Pattern should not match"); + error = 0; + result = mxs_pcre2_simple_match("black.*[dog", "The quick brown fox jumps over the lazy dog", 0, &error); + test_assert(result == MXS_PCRE2_ERROR, "Pattern should not match and a failure should be retured"); + test_assert(error != 0, "Error number should be non-zero"); + return 0; +} + +/** + * Test PCRE2 string substitution + */ +static int test2() +{ + int err; + size_t erroff; + const char* pattern = "(.*)dog"; + const char* pattern2 = "(.*)duck"; + const char* good_replace = "$1cat"; + const char* bad_replace = "$6cat"; + const char* subject = "The quick brown fox jumps over the lazy dog"; + const char* expected = "The quick brown fox jumps over the lazy cat"; + + /** We'll assume malloc and the PCRE2 library works */ + pcre2_code *re = pcre2_compile((PCRE2_SPTR) pattern, PCRE2_ZERO_TERMINATED, + 0, &err, &erroff, NULL); + pcre2_code *re2 = pcre2_compile((PCRE2_SPTR) pattern2, PCRE2_ZERO_TERMINATED, + 0, &err, &erroff, NULL); + size_t size = 1000; + char* dest = malloc(size); + mxs_pcre2_result_t result = mxs_pcre2_substitute(re, subject, good_replace, &dest, &size); + + test_assert(result == MXS_PCRE2_MATCH, "Substitution should substitute"); + test_assert(strcmp(dest, expected) == 0, "Replaced text should match expected text"); + + result = mxs_pcre2_substitute(re2, subject, good_replace, &dest, &size); + test_assert(result == MXS_PCRE2_NOMATCH, "Non-matching substitution should not substitute"); + + result = mxs_pcre2_substitute(re, subject, bad_replace, &dest, &size); + test_assert(result == MXS_PCRE2_ERROR, "Bad substitution should return an error"); + return 0; +} + +int main(int argc, char **argv) +{ + int result = 0; + + result += test1(); + result += test2(); + + return result; +} + + From 33294e4c9556f5132c107c5d7acc02babf84a720 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 4 Nov 2015 15:19:41 +0200 Subject: [PATCH 108/179] Whitespace and indentation changes. - Tabs replaced with spaces. - Indentation level 4 spaces. - Allman braces (except for part of commands) - Space after , - Spaces around binary operators. No other changes. --- server/modules/routing/debugcmd.c | 1974 +++++++++++++++-------------- 1 file changed, 1037 insertions(+), 937 deletions(-) diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index b88a67a19..0da1082f8 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -33,17 +33,17 @@ * @verbatim * Revision History * - * Date Who Description - * 20/06/13 Mark Riddoch Initial implementation - * 17/07/13 Mark Riddoch Additional commands - * 09/08/13 Massimiliano Pinto Added enable/disable commands (now only for log) - * 20/05/14 Mark Riddoch Added ability to give server and service names rather - * than simply addresses - * 23/05/14 Mark Riddoch Added support for developer and user modes - * 29/05/14 Mark Riddoch Add Filter support - * 16/10/14 Mark Riddoch Add show eventq - * 05/03/15 Massimiliano Pinto Added enable/disable feedback - * 27/05/15 Martin Brampton Add show persistent [server] + * Date Who Description + * 20/06/13 Mark Riddoch Initial implementation + * 17/07/13 Mark Riddoch Additional commands + * 09/08/13 Massimiliano Pinto Added enable/disable commands (now only for log) + * 20/05/14 Mark Riddoch Added ability to give server and service names rather + * than simply addresses + * 23/05/14 Mark Riddoch Added support for developer and user modes + * 29/05/14 Mark Riddoch Add Filter support + * 16/10/14 Mark Riddoch Add show eventq + * 05/03/15 Massimiliano Pinto Added enable/disable feedback + * 27/05/15 Martin Brampton Add show persistent [server] * * @endverbatim */ @@ -75,18 +75,18 @@ #include #include -#define MAXARGS 5 +#define MAXARGS 5 -#define ARG_TYPE_ADDRESS 1 -#define ARG_TYPE_STRING 2 -#define ARG_TYPE_SERVICE 3 -#define ARG_TYPE_SERVER 4 -#define ARG_TYPE_DBUSERS 5 -#define ARG_TYPE_SESSION 6 -#define ARG_TYPE_DCB 7 -#define ARG_TYPE_MONITOR 8 -#define ARG_TYPE_FILTER 9 -#define ARG_TYPE_NUMERIC 10 +#define ARG_TYPE_ADDRESS 1 +#define ARG_TYPE_STRING 2 +#define ARG_TYPE_SERVICE 3 +#define ARG_TYPE_SERVER 4 +#define ARG_TYPE_DBUSERS 5 +#define ARG_TYPE_SESSION 6 +#define ARG_TYPE_DCB 7 +#define ARG_TYPE_MONITOR 8 +#define ARG_TYPE_FILTER 9 +#define ARG_TYPE_NUMERIC 10 /** * The subcommand structure @@ -94,161 +94,165 @@ * These are the options that may be passed to a command */ struct subcommand { - char *arg1; - int n_args; - void (*fn)(); - char *help; - char *devhelp; - int arg_types[3]; + char *arg1; + int n_args; + void (*fn)(); + char *help; + char *devhelp; + int arg_types[3]; }; -static void telnetdShowUsers(DCB *); +static void telnetdShowUsers(DCB *); /** * The subcommands of the show command */ struct subcommand showoptions[] = { - { "dcbs", 0, dprintAllDCBs, - "Show all descriptor control blocks (network connections)", - "Show all descriptor control blocks (network connections)", - {0, 0, 0} }, - { "dcb", 1, dprintDCB, - "Show a single descriptor control block e.g. show dcb 0x493340", - "Show a single descriptor control block e.g. show dcb 0x493340", - {ARG_TYPE_DCB, 0, 0} }, - { "dbusers", 1, dcb_usersPrint, - "Show statistics and user names for a service's user table.\n\t\tExample : show dbusers ", - "Show statistics and user names for a service's user table.\n\t\tExample : show dbusers |", - {ARG_TYPE_DBUSERS, 0, 0} }, - { "epoll", 0, dprintPollStats, - "Show the poll statistics", - "Show the poll statistics", - {0, 0, 0} }, - { "eventq", 0, dShowEventQ, - "Show the queue of events waiting to be processed", - "Show the queue of events waiting to be processed", - {0, 0, 0} }, - { "eventstats", 0, dShowEventStats, - "Show the event statistics", - "Show the event statistics", - {0, 0, 0} }, - { "feedbackreport", 0, moduleShowFeedbackReport, - "Show the report of MaxScale loaded modules, suitable for Notification Service", - "Show the report of MaxScale loaded modules, suitable for Notification Service", - {0, 0, 0} }, - { "filter", 1, dprintFilter, - "Show details of a filter, called with a filter name", - "Show details of a filter, called with the address of a filter", - {ARG_TYPE_FILTER, 0, 0} }, - { "filters", 0, dprintAllFilters, - "Show all filters", - "Show all filters", - {0, 0, 0} }, - { "modules", 0, dprintAllModules, - "Show all currently loaded modules", - "Show all currently loaded modules", - {0, 0, 0} }, - { "monitor", 1, monitorShow, - "Show the monitor details", - "Show the monitor details", - {ARG_TYPE_MONITOR, 0, 0} }, - { "monitors", 0, monitorShowAll, - "Show the monitors that are configured", - "Show the monitors that are configured", - {0, 0, 0} }, - { "persistent", 1, dprintPersistentDCBs, - "Show persistent pool for a named server, e.g. show persistent dbnode1", - "Show persistent pool for a server, e.g. show persistent 0x485390. The address may also be replaced with the server name from the configuration file", - {ARG_TYPE_SERVER, 0, 0} }, - { "server", 1, dprintServer, - "Show details for a named server, e.g. show server dbnode1", - "Show details for a server, e.g. show server 0x485390. The address may also be repalced with the server name from the configuration file", - {ARG_TYPE_SERVER, 0, 0} }, - { "servers", 0, dprintAllServers, - "Show all configured servers", - "Show all configured servers", - {0, 0, 0} }, - { "serversjson", 0, dprintAllServersJson, - "Show all configured servers in JSON format", - "Show all configured servers in JSON format", - {0, 0, 0} }, - { "services", 0, dprintAllServices, - "Show all configured services in MaxScale", - "Show all configured services in MaxScale", - {0, 0, 0} }, - { "service", 1, dprintService, - "Show a single service in MaxScale, may be passed a service name", - "Show a single service in MaxScale, may be passed a service name or address of a service object", - {ARG_TYPE_SERVICE, 0, 0} }, - { "session", 1, dprintSession, - "Show a single session in MaxScale, e.g. show session 0x284830", - "Show a single session in MaxScale, e.g. show session 0x284830", - {ARG_TYPE_SESSION, 0, 0} }, - { "sessions", 0, dprintAllSessions, - "Show all active sessions in MaxScale", - "Show all active sessions in MaxScale", - {0, 0, 0} }, - { "tasks", 0, hkshow_tasks, - "Show all active housekeeper tasks in MaxScale", - "Show all active housekeeper tasks in MaxScale", - {0, 0, 0} }, - { "threads", 0, dShowThreads, - "Show the status of the polling threads in MaxScale", - "Show the status of the polling threads in MaxScale", - {0, 0, 0} }, - { "users", 0, telnetdShowUsers, - "Show statistics and user names for the debug interface", - "Show statistics and user names for the debug interface", - {0, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "dcbs", 0, dprintAllDCBs, + "Show all descriptor control blocks (network connections)", + "Show all descriptor control blocks (network connections)", + {0, 0, 0} }, + { "dcb", 1, dprintDCB, + "Show a single descriptor control block e.g. show dcb 0x493340", + "Show a single descriptor control block e.g. show dcb 0x493340", + {ARG_TYPE_DCB, 0, 0} }, + { "dbusers", 1, dcb_usersPrint, + "Show statistics and user names for a service's user table.\n" + "\t\tExample : show dbusers ", + "Show statistics and user names for a service's user table.\n" + "\t\tExample : show dbusers |", + {ARG_TYPE_DBUSERS, 0, 0} }, + { "epoll", 0, dprintPollStats, + "Show the poll statistics", + "Show the poll statistics", + {0, 0, 0} }, + { "eventq", 0, dShowEventQ, + "Show the queue of events waiting to be processed", + "Show the queue of events waiting to be processed", + {0, 0, 0} }, + { "eventstats", 0, dShowEventStats, + "Show the event statistics", + "Show the event statistics", + {0, 0, 0} }, + { "feedbackreport", 0, moduleShowFeedbackReport, + "Show the report of MaxScale loaded modules, suitable for Notification Service", + "Show the report of MaxScale loaded modules, suitable for Notification Service", + {0, 0, 0} }, + { "filter", 1, dprintFilter, + "Show details of a filter, called with a filter name", + "Show details of a filter, called with the address of a filter", + {ARG_TYPE_FILTER, 0, 0} }, + { "filters", 0, dprintAllFilters, + "Show all filters", + "Show all filters", + {0, 0, 0} }, + { "modules", 0, dprintAllModules, + "Show all currently loaded modules", + "Show all currently loaded modules", + {0, 0, 0} }, + { "monitor", 1, monitorShow, + "Show the monitor details", + "Show the monitor details", + {ARG_TYPE_MONITOR, 0, 0} }, + { "monitors", 0, monitorShowAll, + "Show the monitors that are configured", + "Show the monitors that are configured", + {0, 0, 0} }, + { "persistent", 1, dprintPersistentDCBs, + "Show persistent pool for a named server, e.g. show persistent dbnode1", + "Show persistent pool for a server, e.g. show persistent 0x485390. " + "The address may also be replaced with the server name from the configuration file", + {ARG_TYPE_SERVER, 0, 0} }, + { "server", 1, dprintServer, + "Show details for a named server, e.g. show server dbnode1", + "Show details for a server, e.g. show server 0x485390. The address may also be " + "repalced with the server name from the configuration file", + {ARG_TYPE_SERVER, 0, 0} }, + { "servers", 0, dprintAllServers, + "Show all configured servers", + "Show all configured servers", + {0, 0, 0} }, + { "serversjson", 0, dprintAllServersJson, + "Show all configured servers in JSON format", + "Show all configured servers in JSON format", + {0, 0, 0} }, + { "services", 0, dprintAllServices, + "Show all configured services in MaxScale", + "Show all configured services in MaxScale", + {0, 0, 0} }, + { "service", 1, dprintService, + "Show a single service in MaxScale, may be passed a service name", + "Show a single service in MaxScale, may be passed a service name or address of a service object", + {ARG_TYPE_SERVICE, 0, 0} }, + { "session", 1, dprintSession, + "Show a single session in MaxScale, e.g. show session 0x284830", + "Show a single session in MaxScale, e.g. show session 0x284830", + {ARG_TYPE_SESSION, 0, 0} }, + { "sessions", 0, dprintAllSessions, + "Show all active sessions in MaxScale", + "Show all active sessions in MaxScale", + {0, 0, 0} }, + { "tasks", 0, hkshow_tasks, + "Show all active housekeeper tasks in MaxScale", + "Show all active housekeeper tasks in MaxScale", + {0, 0, 0} }, + { "threads", 0, dShowThreads, + "Show the status of the polling threads in MaxScale", + "Show the status of the polling threads in MaxScale", + {0, 0, 0} }, + { "users", 0, telnetdShowUsers, + "Show statistics and user names for the debug interface", + "Show statistics and user names for the debug interface", + {0, 0, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; /** * The subcommands of the list command */ struct subcommand listoptions[] = { - { "clients", 0, dListClients, - "List all the client connections to MaxScale", - "List all the client connections to MaxScale", - {0, 0, 0} }, - { "dcbs", 0, dListDCBs, - "List all the DCBs active within MaxScale", - "List all the DCBs active within MaxScale", - {0, 0, 0} }, - { "filters", 0, dListFilters, - "List all the filters defined within MaxScale", - "List all the filters defined within MaxScale", - {0, 0, 0} }, - { "listeners", 0, dListListeners, - "List all the listeners defined within MaxScale", - "List all the listeners defined within MaxScale", - {0, 0, 0} }, - { "modules", 0, dprintAllModules, - "List all currently loaded modules", - "List all currently loaded modules", - {0, 0, 0} }, - { "monitors", 0, monitorList, - "List all monitors", - "List all monitors", - {0, 0, 0} }, - { "services", 0, dListServices, - "List all the services defined within MaxScale", - "List all the services defined within MaxScale", - {0, 0, 0} }, - { "servers", 0, dListServers, - "List all the servers defined within MaxScale", - "List all the servers defined within MaxScale", - {0, 0, 0} }, - { "sessions", 0, dListSessions, - "List all the active sessions within MaxScale", - "List all the active sessions within MaxScale", - {0, 0, 0} }, - { "threads", 0, dShowThreads, - "List the status of the polling threads in MaxScale", - "List the status of the polling threads in MaxScale", - {0, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "clients", 0, dListClients, + "List all the client connections to MaxScale", + "List all the client connections to MaxScale", + {0, 0, 0} }, + { "dcbs", 0, dListDCBs, + "List all the DCBs active within MaxScale", + "List all the DCBs active within MaxScale", + {0, 0, 0} }, + { "filters", 0, dListFilters, + "List all the filters defined within MaxScale", + "List all the filters defined within MaxScale", + {0, 0, 0} }, + { "listeners", 0, dListListeners, + "List all the listeners defined within MaxScale", + "List all the listeners defined within MaxScale", + {0, 0, 0} }, + { "modules", 0, dprintAllModules, + "List all currently loaded modules", + "List all currently loaded modules", + {0, 0, 0} }, + { "monitors", 0, monitorList, + "List all monitors", + "List all monitors", + {0, 0, 0} }, + { "services", 0, dListServices, + "List all the services defined within MaxScale", + "List all the services defined within MaxScale", + {0, 0, 0} }, + { "servers", 0, dListServers, + "List all the servers defined within MaxScale", + "List all the servers defined within MaxScale", + {0, 0, 0} }, + { "sessions", 0, dListSessions, + "List all the active sessions within MaxScale", + "List all the active sessions within MaxScale", + {0, 0, 0} }, + { "threads", 0, dShowThreads, + "List the status of the polling threads in MaxScale", + "List the status of the polling threads in MaxScale", + {0, 0, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; extern void shutdown_server(); @@ -259,37 +263,38 @@ static void shutdown_monitor(DCB *dcb, MONITOR *monitor); * The subcommands of the shutdown command */ struct subcommand shutdownoptions[] = { - { "maxscale", - 0, - shutdown_server, - "Shutdown MaxScale", - "Shutdown MaxScale", - {0, 0, 0} - }, - { - "monitor", - 1, - shutdown_monitor, - "Shutdown a monitor, e.g. shutdown monitor 0x48381e0", - "Shutdown a monitor, e.g. shutdown monitor 0x48381e0", - {ARG_TYPE_MONITOR, 0, 0} - }, - { - "service", - 1, - shutdown_service, - "Shutdown a service, e.g. shutdown service \"Sales Database\"", - "Shutdown a service, e.g. shutdown service 0x4838320 or shutdown service \"Sales Database\"", - {ARG_TYPE_SERVICE, 0, 0} - }, - { - NULL, - 0, - NULL, - NULL, - NULL, - {0, 0, 0} - } + { + "maxscale", + 0, + shutdown_server, + "Shutdown MaxScale", + "Shutdown MaxScale", + {0, 0, 0} + }, + { + "monitor", + 1, + shutdown_monitor, + "Shutdown a monitor, e.g. shutdown monitor 0x48381e0", + "Shutdown a monitor, e.g. shutdown monitor 0x48381e0", + {ARG_TYPE_MONITOR, 0, 0} + }, + { + "service", + 1, + shutdown_service, + "Shutdown a service, e.g. shutdown service \"Sales Database\"", + "Shutdown a service, e.g. shutdown service 0x4838320 or shutdown service \"Sales Database\"", + {ARG_TYPE_SERVICE, 0, 0} + }, + { + NULL, + 0, + NULL, + NULL, + NULL, + {0, 0, 0} + } }; @@ -299,16 +304,16 @@ static void restart_monitor(DCB *dcb, MONITOR *monitor); * The subcommands of the restart command */ struct subcommand restartoptions[] = { - { "monitor", 1, restart_monitor, - "Restart a monitor, e.g. restart monitor 0x48181e0", - "Restart a monitor, e.g. restart monitor 0x48181e0", - {ARG_TYPE_MONITOR, 0, 0} }, - { "service", 1, restart_service, - "Restart a service, e.g. restart service \"Test Service\"", - "Restart a service, e.g. restart service 0x4838320", - {ARG_TYPE_SERVICE, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "monitor", 1, restart_monitor, + "Restart a monitor, e.g. restart monitor 0x48181e0", + "Restart a monitor, e.g. restart monitor 0x48181e0", + {ARG_TYPE_MONITOR, 0, 0} }, + { "service", 1, restart_service, + "Restart a service, e.g. restart service \"Test Service\"", + "Restart a service, e.g. restart service 0x4838320", + {ARG_TYPE_SERVICE, 0, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; static void set_server(DCB *dcb, SERVER *server, char *bit); @@ -318,21 +323,21 @@ static void set_nbpoll(DCB *dcb, int); * The subcommands of the set command */ struct subcommand setoptions[] = { - { "server", 2, set_server, - "Set the status of a server. E.g. set server dbnode4 master", - "Set the status of a server. E.g. set server 0x4838320 master", - {ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} }, - { "pollsleep", 1, set_pollsleep, - "Set the maximum poll sleep period in milliseconds", - "Set the maximum poll sleep period in milliseconds", - {ARG_TYPE_NUMERIC, 0, 0} }, - { "nbpolls", 1, set_nbpoll, - "Set the number of non-blocking polls", - "Set the number of non-blocking polls", - {ARG_TYPE_NUMERIC, 0, 0} }, + { "server", 2, set_server, + "Set the status of a server. E.g. set server dbnode4 master", + "Set the status of a server. E.g. set server 0x4838320 master", + {ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} }, + { "pollsleep", 1, set_pollsleep, + "Set the maximum poll sleep period in milliseconds", + "Set the maximum poll sleep period in milliseconds", + {ARG_TYPE_NUMERIC, 0, 0} }, + { "nbpolls", 1, set_nbpoll, + "Set the number of non-blocking polls", + "Set the number of non-blocking polls", + {ARG_TYPE_NUMERIC, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; static void clear_server(DCB *dcb, SERVER *server, char *bit); @@ -340,12 +345,12 @@ static void clear_server(DCB *dcb, SERVER *server, char *bit); * The subcommands of the clear command */ struct subcommand clearoptions[] = { - { "server", 2, clear_server, - "Clear the status of a server. E.g. clear server dbnode2 master", - "Clear the status of a server. E.g. clear server 0x4838320 master", - {ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "server", 2, clear_server, + "Clear the status of a server. E.g. clear server dbnode2 master", + "Clear the status of a server. E.g. clear server 0x4838320 master", + {ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; static void reload_dbusers(DCB *dcb, SERVICE *service); @@ -355,16 +360,16 @@ static void reload_config(DCB *dcb); * The subcommands of the reload command */ struct subcommand reloadoptions[] = { - { "config", 0, reload_config, - "Reload the configuration data for MaxScale.", - "Reload the configuration data for MaxScale.", - {0, 0, 0} }, - { "dbusers", 1, reload_dbusers, - "Reload the dbuser data for a service. E.g. reload dbusers \"splitter service\"", - "Reload the dbuser data for a service. E.g. reload dbusers 0x849420", - {ARG_TYPE_SERVICE, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "config", 0, reload_config, + "Reload the configuration data for MaxScale.", + "Reload the configuration data for MaxScale.", + {0, 0, 0} }, + { "dbusers", 1, reload_dbusers, + "Reload the dbuser data for a service. E.g. reload dbusers \"splitter service\"", + "Reload the dbuser data for a service. E.g. reload dbusers 0x849420", + {ARG_TYPE_SERVICE, 0, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; static void enable_log_action(DCB *, char *); @@ -382,58 +387,58 @@ static void disable_feedback_action(); * * The subcommands of the enable command * */ struct subcommand enableoptions[] = { - { - "heartbeat", - 1, - enable_monitor_replication_heartbeat, - "Enable the monitor replication heartbeat, pass a monitor name as argument", - "Enable the monitor replication heartbeat, pass a monitor name as argument", - {ARG_TYPE_MONITOR, 0, 0} - }, - { - "log", - 1, - enable_log_action, - "Enable Log options for MaxScale, options trace | error | " - "message E.g. enable log message.", - "Enable Log options for MaxScale, options trace | error | " - "message E.g. enable log message.", - {ARG_TYPE_STRING, 0, 0} - }, - { - "sessionlog", - 2, - enable_sess_log_action, - "Enable Log options for a single session. Usage: enable sessionlog [trace | error | " - "message | debug] \t E.g. enable sessionlog message 123.", - "Enable Log options for a single session. Usage: enable sessionlog [trace | error | " - "message | debug] \t E.g. enable sessionlog message 123.", - {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} - }, - { - "root", - 1, - enable_service_root, - "Enable root access to a service, pass a service name to enable root access", - "Enable root access to a service, pass a service name to enable root access", - {ARG_TYPE_SERVICE, 0, 0} - }, - { - "feedback", - 0, - enable_feedback_action, - "Enable MaxScale modules list sending via http to notification service", - "Enable MaxScale modules list sending via http to notification service", - {0, 0, 0} - }, - { - NULL, - 0, - NULL, - NULL, - NULL, - {0, 0, 0} - } + { + "heartbeat", + 1, + enable_monitor_replication_heartbeat, + "Enable the monitor replication heartbeat, pass a monitor name as argument", + "Enable the monitor replication heartbeat, pass a monitor name as argument", + {ARG_TYPE_MONITOR, 0, 0} + }, + { + "log", + 1, + enable_log_action, + "Enable Log options for MaxScale, options trace | error | " + "message E.g. enable log message.", + "Enable Log options for MaxScale, options trace | error | " + "message E.g. enable log message.", + {ARG_TYPE_STRING, 0, 0} + }, + { + "sessionlog", + 2, + enable_sess_log_action, + "Enable Log options for a single session. Usage: enable sessionlog [trace | error | " + "message | debug] \t E.g. enable sessionlog message 123.", + "Enable Log options for a single session. Usage: enable sessionlog [trace | error | " + "message | debug] \t E.g. enable sessionlog message 123.", + {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} + }, + { + "root", + 1, + enable_service_root, + "Enable root access to a service, pass a service name to enable root access", + "Enable root access to a service, pass a service name to enable root access", + {ARG_TYPE_SERVICE, 0, 0} + }, + { + "feedback", + 0, + enable_feedback_action, + "Enable MaxScale modules list sending via http to notification service", + "Enable MaxScale modules list sending via http to notification service", + {0, 0, 0} + }, + { + NULL, + 0, + NULL, + NULL, + NULL, + {0, 0, 0} + } }; @@ -442,58 +447,58 @@ struct subcommand enableoptions[] = { * * The subcommands of the disable command * */ struct subcommand disableoptions[] = { - { - "heartbeat", - 1, - disable_monitor_replication_heartbeat, - "Disable the monitor replication heartbeat", - "Disable the monitor replication heartbeat", - {ARG_TYPE_MONITOR, 0, 0} - }, - { - "log", - 1, - disable_log_action, - "Disable Log for MaxScale, Options: debug | trace | error | message " - "E.g. disable log debug", - "Disable Log for MaxScale, Options: debug | trace | error | message " - "E.g. disable log debug", - {ARG_TYPE_STRING, 0, 0} - }, - { - "sessionlog", - 2, - disable_sess_log_action, - "Disable Log options for a single session. Usage: disable sessionlog [trace | error | " - "message | debug] \t E.g. disable sessionlog message 123.", - "Disable Log options for a single session. Usage: disable sessionlog [trace | error | " - "message | debug] \t E.g. disable sessionlog message 123.", - {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} - }, - { - "root", - 1, - disable_service_root, - "Disable root access to a service", - "Disable root access to a service", - {ARG_TYPE_SERVICE, 0, 0} - }, - { - "feedback", - 0, - disable_feedback_action, - "Disable MaxScale modules list sending via http to notification service", - "Disable MaxScale modules list sending via http to notification service", - {0, 0, 0} - }, - { - NULL, - 0, - NULL, - NULL, - NULL, - {0, 0, 0} - } + { + "heartbeat", + 1, + disable_monitor_replication_heartbeat, + "Disable the monitor replication heartbeat", + "Disable the monitor replication heartbeat", + {ARG_TYPE_MONITOR, 0, 0} + }, + { + "log", + 1, + disable_log_action, + "Disable Log for MaxScale, Options: debug | trace | error | message " + "E.g. disable log debug", + "Disable Log for MaxScale, Options: debug | trace | error | message " + "E.g. disable log debug", + {ARG_TYPE_STRING, 0, 0} + }, + { + "sessionlog", + 2, + disable_sess_log_action, + "Disable Log options for a single session. Usage: disable sessionlog [trace | error | " + "message | debug] \t E.g. disable sessionlog message 123.", + "Disable Log options for a single session. Usage: disable sessionlog [trace | error | " + "message | debug] \t E.g. disable sessionlog message 123.", + {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} + }, + { + "root", + 1, + disable_service_root, + "Disable root access to a service", + "Disable root access to a service", + {ARG_TYPE_SERVICE, 0, 0} + }, + { + "feedback", + 0, + disable_feedback_action, + "Disable MaxScale modules list sending via http to notification service", + "Disable MaxScale modules list sending via http to notification service", + {0, 0, 0} + }, + { + NULL, + 0, + NULL, + NULL, + NULL, + {0, 0, 0} + } }; #if defined(FAKE_CODE) @@ -545,12 +550,12 @@ static void telnetdAddUser(DCB *, char *, char *); * The subcommands of the add command */ struct subcommand addoptions[] = { - { "user", 2, telnetdAddUser, - "Add a new user for the debug interface. E.g. add user john today", - "Add a new user for the debug interface. E.g. add user john today", - {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "user", 2, telnetdAddUser, + "Add a new user for the debug interface. E.g. add user john today", + "Add a new user for the debug interface. E.g. add user john today", + {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; @@ -559,66 +564,66 @@ static void telnetdRemoveUser(DCB *, char *, char *); * The subcommands of the remove command */ struct subcommand removeoptions[] = { - { - "user", - 2, - telnetdRemoveUser, - "Remove existing maxscale user. Example : remove user john johnpwd", - "Remove existing maxscale user. Example : remove user john johnpwd", - {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} - }, - { - NULL, 0, NULL, NULL, NULL, {0, 0, 0} - } + { + "user", + 2, + telnetdRemoveUser, + "Remove existing maxscale user. Example : remove user john johnpwd", + "Remove existing maxscale user. Example : remove user john johnpwd", + {ARG_TYPE_STRING, ARG_TYPE_STRING, 0} + }, + { + NULL, 0, NULL, NULL, NULL, {0, 0, 0} + } }; /** * User command to flush a single logfile * - * @param pdcb The stream to write output to - * @param logname The name of the log + * @param pdcb The stream to write output to + * @param logname The name of the log */ static void flushlog(DCB *pdcb, char *logname) { - if (logname == NULL) - { - } - else if (!strcasecmp(logname, "error")) - { - skygw_log_rotate(LOGFILE_ERROR); - } - else if (!strcasecmp(logname, "message")) - { - skygw_log_rotate(LOGFILE_MESSAGE); - } - else if (!strcasecmp(logname, "trace")) - { - skygw_log_rotate(LOGFILE_TRACE); - } - else if (!strcasecmp(logname, "debug")) - { - skygw_log_rotate(LOGFILE_DEBUG); - } - else - { - dcb_printf(pdcb, "Unexpected logfile name, expected " - "error, message, trace or debug.\n"); - } + if (logname == NULL) + { + } + else if (!strcasecmp(logname, "error")) + { + skygw_log_rotate(LOGFILE_ERROR); + } + else if (!strcasecmp(logname, "message")) + { + skygw_log_rotate(LOGFILE_MESSAGE); + } + else if (!strcasecmp(logname, "trace")) + { + skygw_log_rotate(LOGFILE_TRACE); + } + else if (!strcasecmp(logname, "debug")) + { + skygw_log_rotate(LOGFILE_DEBUG); + } + else + { + dcb_printf(pdcb, "Unexpected logfile name, expected " + "error, message, trace or debug.\n"); + } } /** * User command to flush all logfiles * - * @param pdcb The stream to write output to + * @param pdcb The stream to write output to */ static void flushlogs(DCB *pdcb) { - skygw_log_rotate(LOGFILE_ERROR); - skygw_log_rotate(LOGFILE_MESSAGE); - skygw_log_rotate(LOGFILE_TRACE); - skygw_log_rotate(LOGFILE_DEBUG); + skygw_log_rotate(LOGFILE_ERROR); + skygw_log_rotate(LOGFILE_MESSAGE); + skygw_log_rotate(LOGFILE_TRACE); + skygw_log_rotate(LOGFILE_DEBUG); } @@ -626,25 +631,25 @@ flushlogs(DCB *pdcb) * The subcommands of the flush command */ struct subcommand flushoptions[] = { - { - "log", - 1, - flushlog, - "Flush the content of a log file, close that log, rename it and open a new log file", - "Flush the content of a log file, close that log, rename it and open a new log file", - {ARG_TYPE_STRING, 0, 0} - }, - { - "logs", - 0, - flushlogs, - "Flush the content of all log files, close that logs, rename them and open a new log files", - "Flush the content of all log files, close that logs, rename them and open a new log files", - {0, 0, 0} - }, - { - NULL, 0, NULL, NULL, NULL, {0, 0, 0} - } + { + "log", + 1, + flushlog, + "Flush the content of a log file, close that log, rename it and open a new log file", + "Flush the content of a log file, close that log, rename it and open a new log file", + {ARG_TYPE_STRING, 0, 0} + }, + { + "logs", + 0, + flushlogs, + "Flush the content of all log files, close that logs, rename them and open a new log files", + "Flush the content of all log files, close that logs, rename them and open a new log files", + {0, 0, 0} + }, + { + NULL, 0, NULL, NULL, NULL, {0, 0, 0} + } }; @@ -652,25 +657,25 @@ struct subcommand flushoptions[] = { * The debug command table */ static struct { - char *cmd; - struct subcommand *options; + char *cmd; + struct subcommand *options; } cmds[] = { - { "add", addoptions }, - { "clear", clearoptions }, - { "disable", disableoptions }, - { "enable", enableoptions }, + { "add", addoptions }, + { "clear", clearoptions }, + { "disable", disableoptions }, + { "enable", enableoptions }, #if defined(FAKE_CODE) - { "fail", failoptions }, + { "fail", failoptions }, #endif /* FAKE_CODE */ - { "flush", flushoptions }, - { "list", listoptions }, - { "reload", reloadoptions }, - { "remove", removeoptions }, - { "restart", restartoptions }, - { "set", setoptions }, - { "show", showoptions }, - { "shutdown", shutdownoptions }, - { NULL, NULL } + { "flush", flushoptions }, + { "list", listoptions }, + { "reload", reloadoptions }, + { "remove", removeoptions }, + { "restart", restartoptions }, + { "set", setoptions }, + { "show", showoptions }, + { "shutdown", shutdownoptions }, + { NULL, NULL } }; @@ -678,76 +683,89 @@ static struct { * Convert a string argument to a numeric, observing prefixes * for number bases, e.g. 0x for hex, 0 for octal * - * @param mode The CLI mode - * @param arg The string representation of the argument - * @param arg_type The target type for the argument + * @param mode The CLI mode + * @param arg The string representation of the argument + * @param arg_type The target type for the argument * @return The argument as a long integer */ static unsigned long convert_arg(int mode, char *arg, int arg_type) { -unsigned long rval; -SERVICE *service; + unsigned long rval; + SERVICE *service; - switch (arg_type) - { - case ARG_TYPE_ADDRESS: - return (unsigned long)strtol(arg, NULL, 0); - case ARG_TYPE_STRING: - return (unsigned long)arg; - case ARG_TYPE_SERVICE: - if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) - rval = (unsigned long)service_find(arg); - - return rval; - case ARG_TYPE_SERVER: - if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) - rval = (unsigned long)server_find_by_unique_name(arg); - - return rval; - case ARG_TYPE_DBUSERS: - if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) - { - service = service_find(arg); - if (service) - return (unsigned long)(service->users); - else - return 0; - } - return rval; - case ARG_TYPE_DCB: - rval = (unsigned long)strtol(arg, NULL, 0); - if (mode == CLIM_USER && dcb_isvalid((DCB *)rval) == 0) - rval = 0; - return rval; - case ARG_TYPE_SESSION: - rval = (unsigned long)strtol(arg, NULL, 0); - if (mode == CLIM_USER && session_isvalid((SESSION *)rval) == 0) - rval = 0; - - return rval; - case ARG_TYPE_MONITOR: - if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) - rval = (unsigned long)monitor_find(arg); - - return rval; - case ARG_TYPE_FILTER: - if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) - rval = (unsigned long)filter_find(arg); - - return rval; - case ARG_TYPE_NUMERIC: - { - int i; - for (i = 0; arg[i]; i++) - { - if (arg[i] < '0' || arg[i] > '9') - return 0; - } - return atoi(arg); - } - } - return 0; + switch (arg_type) + { + case ARG_TYPE_ADDRESS: + return (unsigned long)strtol(arg, NULL, 0); + case ARG_TYPE_STRING: + return (unsigned long)arg; + case ARG_TYPE_SERVICE: + if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) + { + rval = (unsigned long)service_find(arg); + } + return rval; + case ARG_TYPE_SERVER: + if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) + { + rval = (unsigned long)server_find_by_unique_name(arg); + } + return rval; + case ARG_TYPE_DBUSERS: + if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) + { + service = service_find(arg); + if (service) + { + return (unsigned long)(service->users); + } + else + { + return 0; + } + } + return rval; + case ARG_TYPE_DCB: + rval = (unsigned long)strtol(arg, NULL, 0); + if (mode == CLIM_USER && dcb_isvalid((DCB *)rval) == 0) + { + rval = 0; + } + return rval; + case ARG_TYPE_SESSION: + rval = (unsigned long)strtol(arg, NULL, 0); + if (mode == CLIM_USER && session_isvalid((SESSION *)rval) == 0) + { + rval = 0; + } + return rval; + case ARG_TYPE_MONITOR: + if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) + { + rval = (unsigned long)monitor_find(arg); + } + return rval; + case ARG_TYPE_FILTER: + if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0) + { + rval = (unsigned long)filter_find(arg); + } + return rval; + case ARG_TYPE_NUMERIC: + { + int i; + for (i = 0; arg[i]; i++) + { + if (arg[i] < '0' || arg[i] > '9') + { + return 0; + } + } + return atoi(arg); + } + } + return 0; } /** @@ -761,408 +779,453 @@ SERVICE *service; * assumed to the numeric values and will be converted before being passed * to the handler function for the command. * - * @param cli The CLI_SESSION - * @return Returns 0 if the interpreter should exit + * @param cli The CLI_SESSION + * @return Returns 0 if the interpreter should exit */ int execute_cmd(CLI_SESSION *cli) { -DCB *dcb = cli->session->client; -int argc, i, j, found = 0; -char *args[MAXARGS + 1]; -unsigned long arg1, arg2, arg3; -int in_quotes = 0, escape_next = 0; -char *ptr, *lptr; -bool in_space = false; -int nskip = 0; + DCB *dcb = cli->session->client; + int argc, i, j, found = 0; + char *args[MAXARGS + 1]; + unsigned long arg1, arg2, arg3; + int in_quotes = 0, escape_next = 0; + char *ptr, *lptr; + bool in_space = false; + int nskip = 0; - args[0] = cli->cmdbuf; - ptr = args[0]; - lptr = ptr; - i = 0; - /* - * Break the command line into a number of words. Whitespace is used - * to delimit words and may be escaped by use of the \ character or - * the use of double quotes. - * The array args contains the broken down words, one per index. - */ + args[0] = cli->cmdbuf; + ptr = args[0]; + lptr = ptr; + i = 0; + /* + * Break the command line into a number of words. Whitespace is used + * to delimit words and may be escaped by use of the \ character or + * the use of double quotes. + * The array args contains the broken down words, one per index. + */ - while (*ptr) - { - if (escape_next) - { - *lptr++ = *ptr++; - escape_next = 0; - } - else if (*ptr == '\\') - { - escape_next = 1; - ptr++; - } - else if (in_quotes == 0 && ((in_space = *ptr == ' ') || *ptr == '\t' || *ptr == '\r' || *ptr == '\n')) - { + while (*ptr) + { + if (escape_next) + { + *lptr++ = *ptr++; + escape_next = 0; + } + else if (*ptr == '\\') + { + escape_next = 1; + ptr++; + } + else if (in_quotes == 0 && ((in_space = *ptr == ' ') || *ptr == '\t' || *ptr == '\r' || *ptr == '\n')) + { - *lptr = 0; - lptr += nskip; - nskip = 0; + *lptr = 0; + lptr += nskip; + nskip = 0; - if(!in_space){ - break; - } + if (!in_space) + { + break; + } - if (args[i] == ptr) - args[i] = ptr + 1; - else - { - i++; - if (i >= MAXARGS-1) - break; - args[i] = ptr + 1; - } - ptr++; - lptr++; - } - else if (*ptr == '\"' && in_quotes == 0) - { - in_quotes = 1; - ptr++; - nskip++; - } - else if (*ptr == '\"' && in_quotes == 1) - { - in_quotes = 0; - ptr++; - nskip++; - } - else - { - *lptr++ = *ptr++; - } - } - *lptr = 0; - args[MIN(MAXARGS-1,i+1)] = NULL; + if (args[i] == ptr) + { + args[i] = ptr + 1; + } + else + { + i++; + if (i >= MAXARGS - 1) + { + break; + } + args[i] = ptr + 1; + } + ptr++; + lptr++; + } + else if (*ptr == '\"' && in_quotes == 0) + { + in_quotes = 1; + ptr++; + nskip++; + } + else if (*ptr == '\"' && in_quotes == 1) + { + in_quotes = 0; + ptr++; + nskip++; + } + else + { + *lptr++ = *ptr++; + } + } + *lptr = 0; + args[MIN(MAXARGS - 1, i + 1)] = NULL; - if (args[0] == NULL || *args[0] == 0) - return 1; - for (i = 0; args[i] && *args[i]; i++) - ; - argc = i - 2; /* The number of extra arguments to commands */ - + if (args[0] == NULL || *args[0] == 0) + { + return 1; + } + for (i = 0; args[i] && *args[i]; i++) + ; + argc = i - 2; /* The number of extra arguments to commands */ - if (!strcasecmp(args[0], "help")) - { - if (args[1] == NULL || *args[1] == 0) - { - found = 1; - dcb_printf(dcb, "Available commands:\n"); - for (i = 0; cmds[i].cmd; i++) - { - if (cmds[i].options[1].arg1 == NULL) - dcb_printf(dcb, " %s %s\n", cmds[i].cmd, cmds[i].options[0].arg1); - else - { - dcb_printf(dcb, " %s [", cmds[i].cmd); - for (j = 0; cmds[i].options[j].arg1; j++) - { - dcb_printf(dcb, "%s%s", cmds[i].options[j].arg1, - cmds[i].options[j+1].arg1 ? "|" : ""); - } - dcb_printf(dcb, "]\n"); - } - } - dcb_printf(dcb, "\nType help command to see details of each command.\n"); - dcb_printf(dcb, "Where commands require names as arguments and these names contain\n"); - dcb_printf(dcb, "whitespace either the \\ character may be used to escape the whitespace\n"); - dcb_printf(dcb, "or the name may be enclosed in double quotes \".\n\n"); - } - else - { - for (i = 0; cmds[i].cmd; i++) - { - if (!strcasecmp(args[1], cmds[i].cmd)) - { - found = 1; - dcb_printf(dcb, "Available options to the %s command:\n", args[1]); - for (j = 0; cmds[i].options[j].arg1; j++) - { - dcb_printf(dcb, " %-10s %s\n", cmds[i].options[j].arg1, - cmds[i].options[j].help); - } - } - } - if (found == 0) - { - dcb_printf(dcb, "No command %s to offer help with\n", args[1]); - } - } - found = 1; - } - else if (!strcasecmp(args[0], "quit")) - { - return 0; - } - else if (argc >= 0) - { - for (i = 0; cmds[i].cmd; i++) - { - if (strcasecmp(args[0], cmds[i].cmd) == 0) - { - for (j = 0; cmds[i].options[j].arg1; j++) - { - if (strcasecmp(args[1], cmds[i].options[j].arg1) == 0) - { - found = 1; /**< command and sub-command match */ - if (argc != cmds[i].options[j].n_args) - { - dcb_printf(dcb, "Incorrect number of arguments: %s %s expects %d arguments\n", - cmds[i].cmd, cmds[i].options[j].arg1, - cmds[i].options[j].n_args); - - } - else - { - switch (cmds[i].options[j].n_args) - { - case 0: - cmds[i].options[j].fn(dcb); - break; - case 1: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); + if (!strcasecmp(args[0], "help")) + { + if (args[1] == NULL || *args[1] == 0) + { + found = 1; + dcb_printf(dcb, "Available commands:\n"); + for (i = 0; cmds[i].cmd; i++) + { + if (cmds[i].options[1].arg1 == NULL) + { + dcb_printf(dcb, " %s %s\n", cmds[i].cmd, cmds[i].options[0].arg1); + } + else + { + dcb_printf(dcb, " %s [", cmds[i].cmd); + for (j = 0; cmds[i].options[j].arg1; j++) + { + dcb_printf(dcb, "%s%s", cmds[i].options[j].arg1, + cmds[i].options[j + 1].arg1 ? "|" : ""); + } + dcb_printf(dcb, "]\n"); + } + } + dcb_printf(dcb, "\nType help command to see details of each command.\n"); + dcb_printf(dcb, "Where commands require names as arguments and these names contain\n"); + dcb_printf(dcb, "whitespace either the \\ character may be used to escape the whitespace\n"); + dcb_printf(dcb, "or the name may be enclosed in double quotes \".\n\n"); + } + else + { + for (i = 0; cmds[i].cmd; i++) + { + if (!strcasecmp(args[1], cmds[i].cmd)) + { + found = 1; + dcb_printf(dcb, "Available options to the %s command:\n", args[1]); + for (j = 0; cmds[i].options[j].arg1; j++) + { + dcb_printf(dcb, " %-10s %s\n", cmds[i].options[j].arg1, + cmds[i].options[j].help); + } + } + } + if (found == 0) + { + dcb_printf(dcb, "No command %s to offer help with\n", args[1]); + } + } + found = 1; + } + else if (!strcasecmp(args[0], "quit")) + { + return 0; + } + else if (argc >= 0) + { + for (i = 0; cmds[i].cmd; i++) + { + if (strcasecmp(args[0], cmds[i].cmd) == 0) + { + for (j = 0; cmds[i].options[j].arg1; j++) + { + if (strcasecmp(args[1], cmds[i].options[j].arg1) == 0) + { + found = 1; /**< command and sub-command match */ + if (argc != cmds[i].options[j].n_args) + { + dcb_printf(dcb, "Incorrect number of arguments: %s %s expects %d arguments\n", + cmds[i].cmd, cmds[i].options[j].arg1, + cmds[i].options[j].n_args); + } + else + { + switch (cmds[i].options[j].n_args) + { + case 0: + cmds[i].options[j].fn(dcb); + break; + case 1: + arg1 = convert_arg(cli->mode, args[2], cmds[i].options[j].arg_types[0]); - if (arg1) - cmds[i].options[j].fn(dcb, arg1); - else - dcb_printf(dcb, "Invalid argument: %s\n", - args[2]); - break; - case 2: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); - arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]); - if (arg1 && arg2) - cmds[i].options[j].fn(dcb, arg1, arg2); - else if (arg1 == 0) - dcb_printf(dcb, "Invalid argument: %s\n", - args[2]); - else - dcb_printf(dcb, "Invalid argument: %s\n", - args[3]); - break; - case 3: - arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]); - arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]); - arg3 = convert_arg(cli->mode, args[4],cmds[i].options[j].arg_types[2]); - if (arg1 && arg2 && arg3) - cmds[i].options[j].fn(dcb, arg1, arg2, arg3); - else if (arg1 == 0) - dcb_printf(dcb, "Invalid argument: %s\n", - args[2]); - else if (arg2 == 0) - dcb_printf(dcb, "Invalid argument: %s\n", - args[3]); - else if (arg3 == 0) - dcb_printf(dcb, "Invalid argument: %s\n", - args[4]); - } - } - } - } - if (!found) - { - dcb_printf(dcb, - "Unknown or missing option for the %s command. Valid sub-commands are:\n", - cmds[i].cmd); - for (j = 0; cmds[i].options[j].arg1; j++) - { - dcb_printf(dcb, " %-10s %s\n", cmds[i].options[j].arg1, - cmds[i].options[j].help); - } - found = 1; - } - } - } - } - else if (argc == -1) - { - dcb_printf(dcb, - "Commands must consist of at least two words. Type help for a list of commands\n"); - found = 1; - } - if (!found) - dcb_printf(dcb, - "Command '%s' not known, type help for a list of available commands\n", args[0]); - memset(cli->cmdbuf, 0, cmdbuflen); + if (arg1) + { + cmds[i].options[j].fn(dcb, arg1); + } + else + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[2]); + } + break; + case 2: + arg1 = convert_arg(cli->mode, args[2], cmds[i].options[j].arg_types[0]); + arg2 = convert_arg(cli->mode, args[3], cmds[i].options[j].arg_types[1]); + if (arg1 && arg2) + { + cmds[i].options[j].fn(dcb, arg1, arg2); + } + else if (arg1 == 0) + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[2]); + } + else + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[3]); + } + break; + case 3: + arg1 = convert_arg(cli->mode, args[2], cmds[i].options[j].arg_types[0]); + arg2 = convert_arg(cli->mode, args[3], cmds[i].options[j].arg_types[1]); + arg3 = convert_arg(cli->mode, args[4], cmds[i].options[j].arg_types[2]); + if (arg1 && arg2 && arg3) + { + cmds[i].options[j].fn(dcb, arg1, arg2, arg3); + } + else if (arg1 == 0) + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[2]); + } + else if (arg2 == 0) + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[3]); + } + else if (arg3 == 0) + { + dcb_printf(dcb, "Invalid argument: %s\n", + args[4]); + } + } + } + } + } + if (!found) + { + dcb_printf(dcb, + "Unknown or missing option for the %s command. Valid sub-commands are:\n", + cmds[i].cmd); + for (j = 0; cmds[i].options[j].arg1; j++) + { + dcb_printf(dcb, " %-10s %s\n", cmds[i].options[j].arg1, + cmds[i].options[j].help); + } + found = 1; + } + } + } + } + else if (argc == -1) + { + dcb_printf(dcb, + "Commands must consist of at least two words. Type help for a list of commands\n"); + found = 1; + } + if (!found) + { + dcb_printf(dcb, + "Command '%s' not known, type help for a list of available commands\n", args[0]); + } - return 1; + memset(cli->cmdbuf, 0, cmdbuflen); + + return 1; } /** * Debug command to stop a service * - * @param dcb The DCB to print any output to - * @param service The service to shutdown + * @param dcb The DCB to print any output to + * @param service The service to shutdown */ static void shutdown_service(DCB *dcb, SERVICE *service) { - serviceStop(service); + serviceStop(service); } /** * Debug command to restart a stopped service * - * @param dcb The DCB to print any output to - * @param service The service to restart + * @param dcb The DCB to print any output to + * @param service The service to restart */ static void restart_service(DCB *dcb, SERVICE *service) { - serviceRestart(service); + serviceRestart(service); } static struct { - char *str; - unsigned int bit; + char *str; + unsigned int bit; } ServerBits[] = { - { "running", SERVER_RUNNING }, - { "master", SERVER_MASTER }, - { "slave", SERVER_SLAVE }, - { "synced", SERVER_JOINED }, - { "ndb", SERVER_NDB }, - { "maintenance", SERVER_MAINT }, - { "maint", SERVER_MAINT }, - { NULL, 0 } + { "running", SERVER_RUNNING }, + { "master", SERVER_MASTER }, + { "slave", SERVER_SLAVE }, + { "synced", SERVER_JOINED }, + { "ndb", SERVER_NDB }, + { "maintenance", SERVER_MAINT }, + { "maint", SERVER_MAINT }, + { NULL, 0 } }; /** * Map the server status bit * - * @param str String representation + * @param str String representation * @return bit value or 0 on error */ static unsigned int server_map_status(char *str) { -int i; + int i; - for (i = 0; ServerBits[i].str; i++) - if (!strcasecmp(str, ServerBits[i].str)) - return ServerBits[i].bit; - return 0; + for (i = 0; ServerBits[i].str; i++) + { + if (!strcasecmp(str, ServerBits[i].str)) + { + return ServerBits[i].bit; + } + } + return 0; } /** * Set the status bit of a server * - * @param dcb DCB to send output to - * @param server The server to set the status of - * @param bit String representation of the status bit + * @param dcb DCB to send output to + * @param server The server to set the status of + * @param bit String representation of the status bit */ static void set_server(DCB *dcb, SERVER *server, char *bit) { -unsigned int bitvalue; + unsigned int bitvalue; - if ((bitvalue = server_map_status(bit)) != 0) - server_set_status(server, bitvalue); - else - dcb_printf(dcb, "Unknown status bit %s\n", bit); + if ((bitvalue = server_map_status(bit)) != 0) + { + server_set_status(server, bitvalue); + } + else + { + dcb_printf(dcb, "Unknown status bit %s\n", bit); + } } /** * Clear the status bit of a server * - * @param dcb DCB to send output to - * @param server The server to set the status of - * @param bit String representation of the status bit + * @param dcb DCB to send output to + * @param server The server to set the status of + * @param bit String representation of the status bit */ static void clear_server(DCB *dcb, SERVER *server, char *bit) { -unsigned int bitvalue; + unsigned int bitvalue; - if ((bitvalue = server_map_status(bit)) != 0) - server_clear_status(server, bitvalue); - else - dcb_printf(dcb, "Unknown status bit %s\n", bit); + if ((bitvalue = server_map_status(bit)) != 0) + { + server_clear_status(server, bitvalue); + } + else + { + dcb_printf(dcb, "Unknown status bit %s\n", bit); + } } /** * Reload the authenticaton data from the backend database of a service. * - * @param dcb DCB to send output - * @param service The service to update + * @param dcb DCB to send output + * @param service The service to update */ static void reload_dbusers(DCB *dcb, SERVICE *service) { - dcb_printf(dcb, "Loaded %d database users for service %s.\n", - reload_mysql_users(service), service->name); + dcb_printf(dcb, "Loaded %d database users for service %s.\n", + reload_mysql_users(service), service->name); } /** * Relaod the configuration data from the config file * - * @param dcb DCB to use to send output + * @param dcb DCB to use to send output */ static void reload_config(DCB *dcb) { - dcb_printf(dcb, "Reloading configuration from file.\n"); - config_reload(); + dcb_printf(dcb, "Reloading configuration from file.\n"); + config_reload(); } /** * Add a new maxscale admin user * - * @param dcb The DCB for messages - * @param user The user name - * @param passwd The Password of the user + * @param dcb The DCB for messages + * @param user The user name + * @param passwd The Password of the user */ static void telnetdAddUser(DCB *dcb, char *user, char *passwd) { -char *err; + char *err; - if (admin_search_user(user)) - { - dcb_printf(dcb, "User %s already exists.\n", user); - return; - } - if ((err = admin_add_user(user, passwd)) == NULL) - dcb_printf(dcb, "User %s has been successfully added.\n", user); - else - dcb_printf(dcb, "Failed to add new user. %s\n", err); + if (admin_search_user(user)) + { + dcb_printf(dcb, "User %s already exists.\n", user); + return; + } + + if ((err = admin_add_user(user, passwd)) == NULL) + { + dcb_printf(dcb, "User %s has been successfully added.\n", user); + } + else + { + dcb_printf(dcb, "Failed to add new user. %s\n", err); + } } /** * Remove a maxscale admin user * - * @param dcb The DCB for messages - * @param user The user name - * @param passwd The Password of the user + * @param dcb The DCB for messages + * @param user The user name + * @param passwd The Password of the user */ static void telnetdRemoveUser( - DCB* dcb, - char* user, - char* passwd) + DCB* dcb, + char* user, + char* passwd) { - char* err; + char* err; - if (!admin_search_user(user)) - { - dcb_printf(dcb, "User %s doesn't exist.\n", user); - return; - } - - if ((err = admin_remove_user(user, passwd)) == NULL) - { - dcb_printf(dcb, "User %s has been successfully removed.\n", user); - } - else - { - dcb_printf(dcb, "Failed to remove user %s. %s\n", user, err); - } + if (!admin_search_user(user)) + { + dcb_printf(dcb, "User %s doesn't exist.\n", user); + return; + } + + if ((err = admin_remove_user(user, passwd)) == NULL) + { + dcb_printf(dcb, "User %s has been successfully removed.\n", user); + } + else + { + dcb_printf(dcb, "Failed to remove user %s. %s\n", user, err); + } } @@ -1170,44 +1233,44 @@ static void telnetdRemoveUser( /** * Print the adminsitration users * - * @param dcb The DCB to print the user data to + * @param dcb The DCB to print the user data to */ static void telnetdShowUsers(DCB *dcb) { - dcb_printf(dcb, "Administration interface users:\n"); - dcb_PrintAdminUsers(dcb); + dcb_printf(dcb, "Administration interface users:\n"); + dcb_PrintAdminUsers(dcb); } /** * Command to shutdown a running monitor * - * @param dcb The DCB to use to print messages - * @param monitor The monitor to shutdown + * @param dcb The DCB to use to print messages + * @param monitor The monitor to shutdown */ static void shutdown_monitor(DCB *dcb, MONITOR *monitor) { - monitorStop(monitor); + monitorStop(monitor); } /** * Command to restart a stopped monitor * - * @param dcb The DCB to use to print messages - * @param monitor The monitor to restart + * @param dcb The DCB to use to print messages + * @param monitor The monitor to restart */ static void restart_monitor(DCB *dcb, MONITOR *monitor) { - monitorStart(monitor, NULL); + monitorStart(monitor, NULL); } /** * Enable replication heartbeat for a monitor * - * @param dcb Connection to user interface - * @param monitor The monitor + * @param dcb Connection to user interface + * @param monitor The monitor */ static void enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor) @@ -1219,14 +1282,14 @@ enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor) param.value = (char*)value; param.next = NULL; monitorStop(monitor); - monitorStart(monitor,¶m); + monitorStart(monitor, ¶m); } /** * Disable replication heartbeat for a monitor * - * @param dcb Connection to user interface - * @param monitor The monitor + * @param dcb Connection to user interface + * @param monitor The monitor */ static void disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor) @@ -1238,31 +1301,31 @@ disable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor) param.value = (char*)value; param.next = NULL; monitorStop(monitor); - monitorStart(monitor,¶m); + monitorStart(monitor, ¶m); } /** * Enable root access to a service * - * @param dcb Connection to user interface - * @param service The service + * @param dcb Connection to user interface + * @param service The service */ static void enable_service_root(DCB *dcb, SERVICE *service) { - serviceEnableRootUser(service, 1); + serviceEnableRootUser(service, 1); } /** * Disable root access to a service * - * @param dcb Connection to user interface - * @param service The service + * @param dcb Connection to user interface + * @param service The service */ static void disable_service_root(DCB *dcb, SERVICE *service) { - serviceEnableRootUser(service, 0); + serviceEnableRootUser(service, 0); } /** @@ -1273,39 +1336,48 @@ disable_service_root(DCB *dcb, SERVICE *service) */ static void enable_sess_log_action(DCB *dcb, char *arg1, char *arg2) { - logfile_id_t type; - size_t id = 0; - int max_len = strlen("message"); - SESSION* session = get_all_sessions(); + logfile_id_t type; + size_t id = 0; + int max_len = strlen("message"); + SESSION* session = get_all_sessions(); - ss_dassert(arg1 != NULL && arg2 != NULL && session != NULL); + ss_dassert(arg1 != NULL && arg2 != NULL && session != NULL); - if (strncmp(arg1, "debug", max_len) == 0) { - type = LOGFILE_DEBUG; - } else if (strncmp(arg1, "trace", max_len) == 0) { - type = LOGFILE_TRACE; - } else if (strncmp(arg1, "error", max_len) == 0) { - type = LOGFILE_ERROR; - } else if (strncmp(arg1, "message", max_len) == 0) { - type = LOGFILE_MESSAGE; - } else { - dcb_printf(dcb, "%s is not supported for enable log\n", arg1); - return ; - } - - id = (size_t)strtol(arg2,0,0); + if (strncmp(arg1, "debug", max_len) == 0) + { + type = LOGFILE_DEBUG; + } + else if (strncmp(arg1, "trace", max_len) == 0) + { + type = LOGFILE_TRACE; + } + else if (strncmp(arg1, "error", max_len) == 0) + { + type = LOGFILE_ERROR; + } + else if (strncmp(arg1, "message", max_len) == 0) + { + type = LOGFILE_MESSAGE; + } + else + { + dcb_printf(dcb, "%s is not supported for enable log\n", arg1); + return ; + } - while(session) - { - if(session->ses_id == id) - { - session_enable_log(session,type); - return; - } - session = session->next; - } + id = (size_t)strtol(arg2, 0, 0); - dcb_printf(dcb, "Session not found: %s\n", arg2); + while(session) + { + if (session->ses_id == id) + { + session_enable_log(session, type); + return; + } + session = session->next; + } + + dcb_printf(dcb, "Session not found: %s\n", arg2); } /** @@ -1316,39 +1388,48 @@ static void enable_sess_log_action(DCB *dcb, char *arg1, char *arg2) */ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2) { - logfile_id_t type; - int id = 0; - int max_len = strlen("message"); - SESSION* session = get_all_sessions(); + logfile_id_t type; + int id = 0; + int max_len = strlen("message"); + SESSION* session = get_all_sessions(); - ss_dassert(arg1 != NULL && arg2 != NULL && session != NULL); + ss_dassert(arg1 != NULL && arg2 != NULL && session != NULL); - if (strncmp(arg1, "debug", max_len) == 0) { - type = LOGFILE_DEBUG; - } else if (strncmp(arg1, "trace", max_len) == 0) { - type = LOGFILE_TRACE; - } else if (strncmp(arg1, "error", max_len) == 0) { - type = LOGFILE_ERROR; - } else if (strncmp(arg1, "message", max_len) == 0) { - type = LOGFILE_MESSAGE; - } else { - dcb_printf(dcb, "%s is not supported for disable log\n", arg1); - return ; + if (strncmp(arg1, "debug", max_len) == 0) + { + type = LOGFILE_DEBUG; + } + else if (strncmp(arg1, "trace", max_len) == 0) + { + type = LOGFILE_TRACE; + } + else if (strncmp(arg1, "error", max_len) == 0) + { + type = LOGFILE_ERROR; + } + else if (strncmp(arg1, "message", max_len) == 0) + { + type = LOGFILE_MESSAGE; + } + else + { + dcb_printf(dcb, "%s is not supported for disable log\n", arg1); + return ; + } + + id = (size_t)strtol(arg2, 0, 0); + + while(session) + { + if (session->ses_id == id) + { + session_disable_log(session, type); + return; } - - id = (size_t)strtol(arg2,0,0); + session = session->next; + } - while(session) - { - if(session->ses_id == id) - { - session_disable_log(session,type); - return; - } - session = session->next; - } - - dcb_printf(dcb, "Session not found: %s\n", arg2); + dcb_printf(dcb, "Session not found: %s\n", arg2); } /** @@ -1356,71 +1437,90 @@ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2) */ static void enable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type; - int max_len = strlen("message"); + logfile_id_t type; + int max_len = strlen("message"); - if (strncmp(arg1, "debug", max_len) == 0) { - type = LOGFILE_DEBUG; - } else if (strncmp(arg1, "trace", max_len) == 0) { - type = LOGFILE_TRACE; - } else if (strncmp(arg1, "error", max_len) == 0) { - type = LOGFILE_ERROR; - } else if (strncmp(arg1, "message", max_len) == 0) { - type = LOGFILE_MESSAGE; - } else { - dcb_printf(dcb, "%s is not supported for enable log\n", arg1); - return ; - } - - skygw_log_enable(type); + if (strncmp(arg1, "debug", max_len) == 0) + { + type = LOGFILE_DEBUG; + } + else if (strncmp(arg1, "trace", max_len) == 0) + { + type = LOGFILE_TRACE; + } + else if (strncmp(arg1, "error", max_len) == 0) + { + type = LOGFILE_ERROR; + } + else if (strncmp(arg1, "message", max_len) == 0) + { + type = LOGFILE_MESSAGE; + } + else + { + dcb_printf(dcb, "%s is not supported for enable log\n", arg1); + return ; + } + + skygw_log_enable(type); } /** * The log disable action */ -static void disable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type; - int max_len = strlen("message"); +static void disable_log_action(DCB *dcb, char *arg1) +{ + logfile_id_t type; + int max_len = strlen("message"); - if (strncmp(arg1, "debug", max_len) == 0) { - type = LOGFILE_DEBUG; - } else if (strncmp(arg1, "trace", max_len) == 0) { - type = LOGFILE_TRACE; - } else if (strncmp(arg1, "error", max_len) == 0) { - type = LOGFILE_ERROR; - } else if (strncmp(arg1, "message", max_len) == 0) { - type = LOGFILE_MESSAGE; - } else { - dcb_printf(dcb, "%s is not supported for disable log\n", arg1); - return ; - } + if (strncmp(arg1, "debug", max_len) == 0) + { + type = LOGFILE_DEBUG; + } + else if (strncmp(arg1, "trace", max_len) == 0) + { + type = LOGFILE_TRACE; + } + else if (strncmp(arg1, "error", max_len) == 0) + { + type = LOGFILE_ERROR; + } + else if (strncmp(arg1, "message", max_len) == 0) + { + type = LOGFILE_MESSAGE; + } + else + { + dcb_printf(dcb, "%s is not supported for disable log\n", arg1); + return ; + } - skygw_log_disable(type); + skygw_log_disable(type); } /** * Set the duration of the sleep passed to the poll wait * - * @param dcb DCB for output - * @param sleeptime Sleep time in milliseconds + * @param dcb DCB for output + * @param sleeptime Sleep time in milliseconds */ static void set_pollsleep(DCB *dcb, int sleeptime) { - poll_set_maxwait(sleeptime); + poll_set_maxwait(sleeptime); } /** * Set the number of non-blockign spins to make * - * @param dcb DCB for output - * @param nb Number of spins + * @param dcb DCB for output + * @param nb Number of spins */ static void set_nbpoll(DCB *dcb, int nb) { - poll_set_nonblocking_polls(nb); + poll_set_nonblocking_polls(nb); } /** @@ -1431,8 +1531,8 @@ set_nbpoll(DCB *dcb, int nb) static void enable_feedback_action(void) { - config_enable_feedback_task(); - return; + config_enable_feedback_task(); + return; } /** @@ -1442,52 +1542,52 @@ enable_feedback_action(void) static void disable_feedback_action(void) { - config_disable_feedback_task(); - return; + config_disable_feedback_task(); + return; } #if defined(FAKE_CODE) static void fail_backendfd(void) -{ - fail_next_backend_fd = true; +{ + fail_next_backend_fd = true; } static void fail_clientfd(void) -{ - fail_next_client_fd = true; +{ + fail_next_client_fd = true; } static void fail_accept( - DCB* dcb, - char* arg1, - char* arg2) + DCB* dcb, + char* arg1, + char* arg2) { - int failcount = MIN(atoi(arg2), 100); - fail_accept_errno = atoi(arg1); - char errbuf[STRERROR_BUFLEN]; + int failcount = MIN(atoi(arg2), 100); + fail_accept_errno = atoi(arg1); + char errbuf[STRERROR_BUFLEN]; - switch(fail_accept_errno) { - case EAGAIN: -// case EWOULDBLOCK: - case EBADF: - case EINTR: - case EINVAL: - case EMFILE: - case ENFILE: - case ENOTSOCK: - case EOPNOTSUPP: - case ENOBUFS: - case ENOMEM: - case EPROTO: - fail_next_accept = failcount; + switch(fail_accept_errno) { + case EAGAIN: +// case EWOULDBLOCK: + case EBADF: + case EINTR: + case EINVAL: + case EMFILE: + case ENFILE: + case ENOTSOCK: + case EOPNOTSUPP: + case ENOBUFS: + case ENOMEM: + case EPROTO: + fail_next_accept = failcount; break; - default: - dcb_printf(dcb, - "[%d, %s] is not valid errno for accept.\n", - fail_accept_errno, - strerror_r(fail_accept_errno, errbuf, sizeof(errbuf))); - return ; - } + default: + dcb_printf(dcb, + "[%d, %s] is not valid errno for accept.\n", + fail_accept_errno, + strerror_r(fail_accept_errno, errbuf, sizeof(errbuf))); + return ; + } } #endif /* FAKE_CODE */ From 80344babd7c669519df9ecfe106f5ceee35944f7 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 5 Nov 2015 16:14:36 +0200 Subject: [PATCH 109/179] Log manager additions. Changes related to the replacement of the notion of logfiles with the notion of syslog priorities. --- log_manager/log_manager.cc | 139 +++++++++++++++++++++++++++++++++++++ log_manager/log_manager.h | 5 ++ 2 files changed, 144 insertions(+) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 7444cb393..979a29815 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -2989,3 +2989,142 @@ void logmanager_enable_maxscalelog(int val) { do_maxscalelog = val; } + + +/** + * Explicitly ensure that all pending log messages are flushed. + * + * @return 0 if the flushing was successfully initiated, otherwise -1. + * + * Note that the return value only indicates whether the flushing was + * successfully initiated, not whether the actual flushing has been + * performed. + */ +int mxs_log_flush() +{ + return skygw_log_flush(LOGFILE_ERROR); +} + +/** + * Rotate the log-file. That is, close the current one and create a new one + * with a larger sequence number. + * + * @return 0 if the rotating was successfully initiated, otherwise -1. + * + * Note that the return value only indicates whether the rotating was + * successfully initiated, not whether the actual rotation has been + * performed. + */ +int mxs_log_rotate() +{ + return skygw_log_rotate(LOGFILE_ERROR); +} + +static bool convert_priority_to_file(int priority, logfile_id_t* idp, const char** textp) +{ + bool converted = true; + + *idp = (logfile_id_t) -1; + *textp = NULL; + + switch (priority) + { + case LOG_DEBUG: + *idp = LOGFILE_DEBUG; + break; + case LOG_INFO: + *idp = LOGFILE_TRACE; + break; + case LOG_NOTICE: + *idp = LOGFILE_MESSAGE; + break; + case LOG_ERR: + *idp = LOGFILE_ERROR; + break; + case LOG_WARNING: + *textp = "LOG_WARNING"; + break; + case LOG_CRIT: + *textp = "LOG_CRIT"; + break; + case LOG_ALERT: + *textp = "LOG_ALERT"; + break; + case LOG_EMERG: + *textp = "LOG_EMERG"; + break; + default: + converted = false; + } + + return converted; +} + +/** + * Enable a particular syslog priority. + * + * @param priority One of the LOG_ERR etc. constants from sys/syslog.h. + * @return 0 if the priority was valid, -1 otherwise. + */ +int mxs_log_enable_priority(int priority) +{ + int rv = -1; + logfile_id_t id; + const char* text; + + if (convert_priority_to_file(priority, &id, &text)) + { + if (!text) + { + rv = skygw_log_enable(id); + } + else + { + // TODO: Change to warning when available. + MXS_DEBUG("Attempt to enable syslog priority %s, which is not available yet.", text); + rv = 0; + } + } + else + { + MXS_ERROR("Attempt to enable unknown syslog priority: %d", priority); + } + + return rv; +} + +/** + * Disable a particular syslog priority. + * + * @param priority One of the LOG_ERR etc. constants from sys/syslog.h. + * + * Note that there is no hierarchy. That is, disabling a priority of + * high importance, such as LOG_ERR, does not automatically disable + * all lower prioritys. + */ +int mxs_log_disable_priority(int priority) +{ + int rv = -1; + logfile_id_t id; + const char* text; + + if (convert_priority_to_file(priority, &id, &text)) + { + if (!text) + { + rv = skygw_log_disable(id); + } + else + { + // TODO: Change to warning when available. + MXS_DEBUG("Attempt to enable syslog priority %s, which is not available.", text); + rv = 0; + } + } + else + { + MXS_ERROR("Attempt to enable unknown syslog priority: %d", priority); + } + + return rv; +} diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 2b838dc13..5e11045f7 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -140,6 +140,11 @@ extern int lm_enabled_logfiles_bitmask; extern ssize_t log_ses_count[]; extern __thread log_info_t tls_log_info; +int mxs_log_flush(); +int mxs_log_rotate(); +int mxs_log_enable_priority(int priority); +int mxs_log_disable_priority(int priority); + bool skygw_logmanager_init(int argc, char* argv[]); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); From b19a4b9f4a2639bd55d68740c6e037429f3f04ac Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 5 Nov 2015 16:20:16 +0200 Subject: [PATCH 110/179] Commands for enabling the log priority added to maxadmin. Enabling log files is accepted but deprecated. --- server/modules/routing/debugcmd.c | 138 ++++++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 8 deletions(-) diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 0da1082f8..73411dc83 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -74,6 +74,7 @@ #include #include +#include #define MAXARGS 5 @@ -374,6 +375,8 @@ struct subcommand reloadoptions[] = { static void enable_log_action(DCB *, char *); static void disable_log_action(DCB *, char *); +static void enable_log_priority(DCB *, char *); +static void disable_log_priority(DCB *, char *); static void enable_sess_log_action(DCB *dcb, char *arg1, char *arg2); static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2); static void enable_monitor_replication_heartbeat(DCB *dcb, MONITOR *monitor); @@ -405,6 +408,18 @@ struct subcommand enableoptions[] = { "message E.g. enable log message.", {ARG_TYPE_STRING, 0, 0} }, + { + "log-priority", + 1, + enable_log_priority, + "Enable log priority for MaxScale; options LOG_ERR | " + "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " + "E.g.: enable log-priority LOG_INFO.", + "Enable log priority for MaxScale; options LOG_ERR | " + "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " + "E.g.: enable log-priority LOG_INFO.", + {ARG_TYPE_STRING, 0, 0} + }, { "sessionlog", 2, @@ -465,6 +480,18 @@ struct subcommand disableoptions[] = { "E.g. disable log debug", {ARG_TYPE_STRING, 0, 0} }, + { + "log-priority", + 1, + disable_log_priority, + "Disable log priority for MaxScale; options LOG_ERR | " + "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " + "E.g.: enable log-priority LOG_INFO.", + "Disable log priority for MaxScale; options LOG_ERR | " + "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " + "E.g.: enable log-priority LOG_INFO.", + {ARG_TYPE_STRING, 0, 0} + }, { "sessionlog", 2, @@ -1436,33 +1463,44 @@ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2) * The log enable action */ -static void enable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type; +static void enable_log_action(DCB *dcb, char *arg1) +{ + logfile_id_t type = -1; int max_len = strlen("message"); + const char* priority; if (strncmp(arg1, "debug", max_len) == 0) { type = LOGFILE_DEBUG; + priority = "LOG_DEBUG"; } else if (strncmp(arg1, "trace", max_len) == 0) { type = LOGFILE_TRACE; + priority = "LOG_INFO"; } else if (strncmp(arg1, "error", max_len) == 0) { type = LOGFILE_ERROR; + priority = "LOG_ERR"; } else if (strncmp(arg1, "message", max_len) == 0) { type = LOGFILE_MESSAGE; + priority = "LOG_NOTICE"; + } + + if (type != -1) + { + skygw_log_enable(type); + dcb_printf(dcb, + "'enable log %s' is accepted but deprecated, use 'enable log-priority %s' instead.\n", + arg1, priority); } else { dcb_printf(dcb, "%s is not supported for enable log\n", arg1); - return ; } - - skygw_log_enable(type); } /** @@ -1471,32 +1509,116 @@ static void enable_log_action(DCB *dcb, char *arg1) { static void disable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type; + logfile_id_t type = -1; int max_len = strlen("message"); + const char* priority; if (strncmp(arg1, "debug", max_len) == 0) { type = LOGFILE_DEBUG; + priority = "LOG_DEBUG"; } else if (strncmp(arg1, "trace", max_len) == 0) { type = LOGFILE_TRACE; + priority = "LOG_INFO"; } else if (strncmp(arg1, "error", max_len) == 0) { type = LOGFILE_ERROR; + priority = "LOG_ERR"; } else if (strncmp(arg1, "message", max_len) == 0) { type = LOGFILE_MESSAGE; + priority = "LOG_NOTICE"; + } + + if (type != -1) + { + skygw_log_disable(type); + dcb_printf(dcb, + "'disable log %s' is accepted but deprecated, use 'disable log-priority %s' instead.\n", + arg1, priority); } else { dcb_printf(dcb, "%s is not supported for disable log\n", arg1); - return ; } +} - skygw_log_disable(type); +struct log_priority_entry +{ + int priority; + const char* name; +}; + +static int compare_log_priority_entries(const void* l, const void* r) +{ + const struct log_priority_entry* l_entry = (const struct log_priority_entry*) l; + const struct log_priority_entry* r_entry = (const struct log_priority_entry*) r; + + return strcmp(l_entry->name, r_entry->name); +} + +static int string_to_priority(const char* name) +{ + static const struct log_priority_entry LOG_PRIORITY_ENTRIES[] = + { + // NOTE: If you make changes to this array, ensure that it remains alphabetically ordered. + { LOG_DEBUG, "LOG_DEBUG" }, + { LOG_ERR, "LOG_ERR" }, + { LOG_INFO, "LOG_INFO" }, + { LOG_NOTICE, "LOG_NOTICE" }, + { LOG_WARNING, "LOG_WARNING" }, + }; + + const size_t N_LOG_PRIORITY_ENTRIES = sizeof(LOG_PRIORITY_ENTRIES) / sizeof(LOG_PRIORITY_ENTRIES[0]); + + struct log_priority_entry key = { -1, name }; + struct log_priority_entry* result = bsearch(&key, + LOG_PRIORITY_ENTRIES, + N_LOG_PRIORITY_ENTRIES, + sizeof(struct log_priority_entry), + compare_log_priority_entries); + + return result ? result->priority : -1; +} + +/** + * The log-priority enable action + */ + +static void enable_log_priority(DCB *dcb, char *arg1) +{ + int priority = string_to_priority(arg1); + + if (priority != -1) + { + mxs_log_enable_priority(priority); + } + else + { + dcb_printf(dcb, "%s is not a supported log priority\n", arg1); + } +} + +/** + * The log-priority disable action + */ + +static void disable_log_priority(DCB *dcb, char *arg1) +{ + int priority = string_to_priority(arg1); + + if (priority != -1) + { + mxs_log_enable_priority(priority); + } + else + { + dcb_printf(dcb, "%s is not a supported log priority\n", arg1); + } } /** From 450078fa923385c3a93c6a0bf9be8e89e8a5c057 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 6 Nov 2015 12:29:43 +0200 Subject: [PATCH 111/179] Interface of skygw_logmanager_init(int argc, char* argv[]) changed. The previous interface of skygw_logmanager_init was conceptually broken. With -o you could specify that logging should be done to stdout. However, even if you did that, the log manager still checked that the logging directory could be accessed. Unless it had been specified using -j the default was /var/log/maxscale. That is, unless the program calling skygw_logmanager_init was invoked by a user that had write access to /var/log/maxscale, there would be a complaint even if nothing was ever written to that directory. In practice this meant that even if -o was used you had to provide a -j with a path that surely is writeable (e.g. "/tmp"). This has now been changed so that you explicitly must provide the log directory and the flags -j and -o are removed. bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]); If /logdir/ is provided then logged messages are written to a log file in that directory. If /logdir/ is NULL then messages are logged to stdout and no checks for access to any directory is not made. --- log_manager/log_manager.cc | 72 ++++++++++--------- log_manager/log_manager.h | 2 +- log_manager/test/testlog.c | 38 +++++----- log_manager/test/testorder.c | 6 +- server/core/gateway.c | 22 +++--- server/core/maxkeys.c | 9 +-- server/core/maxpasswd.c | 15 ++-- server/include/test_utils.h | 10 +-- server/modules/filter/test/harness_common.c | 10 ++- .../modules/routing/binlog/maxbinlogcheck.c | 9 +-- .../modules/routing/binlog/test/testbinlog.c | 9 +-- 11 files changed, 92 insertions(+), 110 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 979a29815..3b01141b9 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -267,14 +267,14 @@ static bool filewriter_init(logmanager_t* logmanager, skygw_message_t* clientmes, skygw_message_t* logmes); static void filewriter_done(filewriter_t* filewriter); -static bool fnames_conf_init(fnames_conf_t* fn, int argc, char* argv[]); +static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir, int argc, char* argv[]); static void fnames_conf_done(fnames_conf_t* fn); static void fnames_conf_free_memory(fnames_conf_t* fn); static void* thr_filewriter_fun(void* data); static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); static void logmanager_unregister(void); -static bool logmanager_init_nomutex(int argc, char* argv[]); +static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]); static void logmanager_done_nomutex(void); static bool logmanager_is_valid_id(logfile_id_t id); @@ -310,7 +310,7 @@ const char* get_logpath_default(void) return "/var/log/maxscale"; } -static bool logmanager_init_nomutex(int argc, char* argv[]) +static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]) { fnames_conf_t* fn; filewriter_t* fw; @@ -356,7 +356,7 @@ static bool logmanager_init_nomutex(int argc, char* argv[]) } /** Initialize configuration including log file naming info */ - if (!fnames_conf_init(fn, argc, argv)) + if (!fnames_conf_init(fn, logdir, argc, argv)) { err = 1; goto return_succp; @@ -418,15 +418,14 @@ return_succp: /** * Initializes log managing routines in MariaDB Corporation MaxScale. * - * Parameters: + * @param logdir The directory for the log file. If NULL logging will be made to stdout. * @param argc number of arguments in argv array - * * @param argv arguments array * * @return true if succeed, otherwise false * */ -bool skygw_logmanager_init(int argc, char* argv[]) +bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]) { bool succp = false; @@ -438,7 +437,7 @@ bool skygw_logmanager_init(int argc, char* argv[]) goto return_succp; } - succp = logmanager_init_nomutex(argc, argv); + succp = logmanager_init_nomutex(logdir, argc, argv); return_succp: release_lock(&lmlock); @@ -1623,7 +1622,8 @@ static bool logmanager_register(bool writep) if (lm == NULL) { - succp = logmanager_init_nomutex(0, NULL); + // TODO: This looks fishy. + succp = logmanager_init_nomutex(get_logpath_default(), 0, NULL); } } /** if logmanager existed or was succesfully restarted, increase link */ @@ -1670,23 +1670,18 @@ static void logmanager_unregister(void) * @node Initialize log file naming parameters from call arguments * or from default functions in cases where arguments are not provided. * - * Parameters: - * @param fn - - * - * - * @param argc - - * - * - * @param argv - - * - * - * @return pointer to object which is either in RUN or DONE state. + * @param fn The fnames_conf_t structure to initialize. + * @param logdir The directory for the log file. If NULL logging will be made to stdout. + * @param argc number of arguments in argv array + * @param argv arguments array * + * @return True if the initialization was performed, false otherwise. * * @details Note that input parameter lenghts are checked here. * */ static bool fnames_conf_init(fnames_conf_t* fn, + const char* logdir, int argc, char* argv[]) { @@ -1694,11 +1689,9 @@ static bool fnames_conf_init(fnames_conf_t* fn, bool succp = false; const char* argstr = "-h - help\n" - "-j ............(\"/tmp\")\n" "-l .......(no default)\n" "-m ............(argv[0])\n" - "-s .......(no default)\n" - "-o .......(write logs to stdout)\n"; + "-s .......(no default)\n"; /** * When init_started is set, clean must be done for it. @@ -1709,18 +1702,11 @@ static bool fnames_conf_init(fnames_conf_t* fn, fn->fn_chk_tail = CHK_NUM_FNAMES; #endif optind = 1; /**fn_logpath = strndup(optarg, MAX_PATHLEN); - break; - case 'l': /** record list of log file ids for syslogged */ if (do_syslog) @@ -1751,8 +1737,18 @@ static bool fnames_conf_init(fnames_conf_t* fn, goto return_conf_init; } /** switch (opt) */ } - /** If log file name is not specified in call arguments, use default. */ - fn->fn_logpath = (fn->fn_logpath == NULL) ? strdup(get_logpath_default()) : fn->fn_logpath; + + if (logdir) + { + use_stdout = 0; + fn->fn_logpath = strdup(logdir); + } + else + { + use_stdout = 1; + // TODO: Re-arrange things so that fn->fn_logpath can be NULL. + fn->fn_logpath = strdup(get_logpath_default()); + } /** Set identity string for syslog if it is not set in config.*/ if (do_syslog) @@ -1907,6 +1903,14 @@ static bool logfile_create(logfile_t* lf) bool succp; strpart_t spart[3]; /*< string parts of which the file is composed of */ + if (use_stdout) + { + // TODO: Refactor so that lf_full_file_name can be NULL in this case. + lf->lf_full_file_name = strdup("stdout"); + succp = true; + // TODO: Refactor to get rid of the gotos. + goto return_succp; + } /** * sparts is an array but next pointers are used to walk through * the list of string parts. diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 5e11045f7..21023871b 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -145,7 +145,7 @@ int mxs_log_rotate(); int mxs_log_enable_priority(int priority); int mxs_log_disable_priority(int priority); -bool skygw_logmanager_init(int argc, char* argv[]); +bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index a0e70bedc..43b28c02c 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -105,7 +105,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Couldn't register exit function.\n"); } - succp = skygw_logmanager_init( log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); if(!succp) fprintf(stderr, "Log manager initialization failed.\n"); ss_dassert(succp); @@ -121,7 +121,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init( log_argc, log_argv); + skygw_logmanager_init("/tmp", log_argc, log_argv); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -169,7 +169,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init( log_argc, log_argv); + skygw_logmanager_init("/tmp", log_argc, log_argv); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -301,7 +301,7 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_ERROR, logstr); ss_dassert(err == 0); - succp = skygw_logmanager_init(log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); ss_dassert(succp); skygw_log_disable(LOGFILE_TRACE); @@ -362,7 +362,7 @@ int main(int argc, char* argv[]) #endif /* TEST 3 */ #if defined(TEST4) - succp = skygw_logmanager_init(log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -397,7 +397,7 @@ int main(int argc, char* argv[]) skygw_logmanager_done(); - succp = skygw_logmanager_init(log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -473,7 +473,7 @@ static void* thr_run( char* logstr; int err; - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); skygw_logmanager_done(); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); @@ -489,14 +489,14 @@ static void* thr_run( fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Testing. One, two, three\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); @@ -506,13 +506,13 @@ static void* thr_run( fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operatos & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a."); err = skygw_log_write(LOGFILE_ERROR, logstr); if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); skygw_logmanager_done(); skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); @@ -522,8 +522,8 @@ static void* thr_run( if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -532,13 +532,13 @@ static void* thr_run( if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operatos & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a."); err = skygw_log_write(LOGFILE_ERROR, logstr); if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("..... and you too?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if(err != 0) @@ -563,14 +563,14 @@ static void* thr_run( if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if(err != 0) fprintf(stderr,"Error, log write failed.\n"); ss_dassert(err == 0); - skygw_logmanager_init( 0, NULL); - skygw_logmanager_init( 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); skygw_logmanager_done(); simple_mutex_lock(td->mtx, true); *td->nactive -= 1; diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 7ca7696bb..d9bd0fc6e 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -63,14 +63,12 @@ int main(int argc, char** argv) sprintf(tmp,"%s",cwd); optstr[0] = strdup("log_manager"); - optstr[1] = strdup("-j"); - optstr[2] = strdup(tmp); - optstr[3] = NULL; + optstr[1] = NULL; iterations = atoi(argv[1]); interval = atoi(argv[2]); - succp = skygw_logmanager_init( 3, optstr); + succp = skygw_logmanager_init(tmp, 1, optstr); if(!succp) fprintf(stderr,"Error, log manager initialization failed.\n"); ss_dassert(succp); diff --git a/server/core/gateway.c b/server/core/gateway.c index 4cd3aa869..cd7e9f64f 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1716,8 +1716,6 @@ int main(int argc, char **argv) } argv[0] = "MaxScale"; - argv[1] = "-j"; - argv[2] = get_logdir(); if (!(*syslog_enabled)) { @@ -1733,21 +1731,21 @@ int main(int argc, char **argv) if (logtofile) { - argv[3] = "-l"; /*< write to syslog */ + argv[1] = "-l"; /*< write to syslog */ /** Logs that should be syslogged */ - argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR" + argv[2] = "LOGFILE_MESSAGE,LOGFILE_ERROR" "LOGFILE_DEBUG,LOGFILE_TRACE"; - argv[5] = NULL; - succp = skygw_logmanager_init(5, argv); + argv[3] = NULL; + succp = skygw_logmanager_init(get_logdir(), 3, argv); } else { - argv[3] = "-s"; /*< store to shared memory */ - argv[4] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< to shm */ - argv[5] = "-l"; /*< write to syslog */ - argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< to syslog */ - argv[7] = NULL; - succp = skygw_logmanager_init(7, argv); + argv[1] = "-s"; /*< store to shared memory */ + argv[2] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< to shm */ + argv[3] = "-l"; /*< write to syslog */ + argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< to syslog */ + argv[5] = NULL; + succp = skygw_logmanager_init(get_logdir(), 5, argv); } if (!succp) diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 00f5d626d..39651b54c 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -35,7 +35,7 @@ int main(int argc, char **argv) { - int arg_count = 4; + int arg_count = 1; char *home; char *keyfile; char** arg_vector; @@ -59,11 +59,8 @@ int main(int argc, char **argv) } arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - arg_vector[2] = "/var/log/maxscale/maxkeys"; - arg_vector[3] = "-o"; - arg_vector[4] = NULL; - skygw_logmanager_init(arg_count, arg_vector); + arg_vector[1] = NULL; + skygw_logmanager_init(NULL, arg_count, arg_vector); free(arg_vector); if (secrets_writeKeys(keyfile)) diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index b88109ddf..96e00dd18 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -42,7 +42,7 @@ main(int argc, char **argv) { char *enc; char *pw; - int arg_count = 6; + int arg_count = 1; char *home; char** arg_vector; int rval = 0; @@ -61,16 +61,9 @@ main(int argc, char **argv) return 1; } - arg_vector[0] = strdup("logmanager"); - arg_vector[1] = strdup("-j"); - arg_vector[2] = strdup("/var/log/maxscale"); - - arg_vector[3] = "-o"; - arg_vector[4] = "-l"; - arg_vector[5] = "LOGFILE_ERROR"; - arg_vector[6] = NULL; - skygw_logmanager_init(arg_count, arg_vector); - free(arg_vector[2]); + arg_vector[0] = "logmanager"; + arg_vector[1] = NULL; + skygw_logmanager_init(NULL, arg_count, arg_vector); free(arg_vector); pw = calloc(81, sizeof(char)); diff --git a/server/include/test_utils.h b/server/include/test_utils.h index 0ed271225..4b1d9bc6f 100644 --- a/server/include/test_utils.h +++ b/server/include/test_utils.h @@ -8,19 +8,19 @@ void init_test_env(char *path) { - int argc = 5; - + int argc = 3; + + const char* logdir = path ? path : TEST_LOG_DIR; + char* argv[] = { "log_manager", "-l", "LOGFILE_ERROR", - "-j", - path? path:TEST_LOG_DIR, NULL }; - skygw_logmanager_init(argc,argv); + skygw_logmanager_init(logdir, argc, argv); poll_init(); hkinit(); } diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index e0326d040..e657fbdd0 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -18,7 +18,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ char** optstr; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ - skygw_logmanager_init(0,NULL); + skygw_logmanager_init(NULL,0,NULL); } if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) @@ -52,12 +52,10 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ getcwd(cwd,sizeof(cwd)); sprintf(tmp,"%s",cwd); - optstr = (char**)malloc(sizeof(char*)*4); + optstr = (char**)malloc(sizeof(char*)*2); optstr[0] = strdup("log_manager"); - optstr[1] = strdup("-j"); - optstr[2] = strdup(tmp); - optstr[3] = NULL; - skygw_logmanager_init( 3, optstr); + optstr[1] = NULL; + skygw_logmanager_init(tmp, 1, optstr); free(optstr); rval = process_opts(argc,argv); diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 12ae8b6ed..50e7e489a 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -87,7 +87,7 @@ return 1; int main(int argc, char **argv) { char** arg_vector; - int arg_count = 4; + int arg_count = 1; ROUTER_INSTANCE *inst; int fd; int ret; @@ -135,11 +135,8 @@ int main(int argc, char **argv) { } arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - arg_vector[2] = "/tmp/maxbinlogcheck"; - arg_vector[3] = "-o"; - arg_vector[4] = NULL; - skygw_logmanager_init(arg_count,arg_vector); + arg_vector[1] = NULL; + skygw_logmanager_init(NULL, arg_count, arg_vector); skygw_log_set_augmentation(0); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index 4143cd517..da75005b4 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) { ROUTER_INSTANCE *inst; int ret; int rc; - int arg_count = 4; + int arg_count = 1; char error_string[BINLOG_ERROR_MSG_LEN + 1] = ""; CHANGE_MASTER_OPTIONS change_master; char query[255+1]=""; @@ -100,11 +100,8 @@ int main(int argc, char **argv) { } arg_vector[0] = "logmanager"; - arg_vector[1] = "-j"; - arg_vector[2] = "/tmp/maxbinlogcheck"; - arg_vector[3] = "-o"; - arg_vector[4] = NULL; - skygw_logmanager_init(arg_count,arg_vector); + arg_vector[1] = NULL; + skygw_logmanager_init(NULL, arg_count,arg_vector); free(arg_vector); skygw_log_disable(LOGFILE_DEBUG); From 43c7ccdd08bd573cabf3089ccf59dcdf0cac7163 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 6 Nov 2015 14:59:10 +0200 Subject: [PATCH 112/179] Whitespace and indentation changes. Whitespace and indentation changes of log manager test programs. --- log_manager/test/testlog.c | 1022 ++++++++++++++++++---------------- log_manager/test/testorder.c | 173 +++--- 2 files changed, 633 insertions(+), 562 deletions(-) diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 43b28c02c..886a66c09 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -17,8 +17,8 @@ */ -/** @file -@brief (brief description) +/** @file + @brief (brief description) */ #include @@ -27,11 +27,12 @@ #include #include -typedef struct thread_st { - skygw_message_t* mes; - simple_mutex_t* mtx; - size_t* nactive; - pthread_t tid; +typedef struct thread_st +{ + skygw_message_t* mes; + simple_mutex_t* mtx; + size_t* nactive; + pthread_t tid; } thread_t; static void* thr_run(void* data); @@ -53,582 +54,641 @@ static void* thr_run_morelog(void* data); int main(int argc, char* argv[]) { - int err = 0; - char* logstr; - - int i; - bool succp; - skygw_message_t* mes; - simple_mutex_t* mtx; - size_t nactive; - thread_t** thr = NULL; - time_t t; - struct tm tm; - char c; - int nthr = 0; - int log_argc = 0; - char** log_argv = NULL; + int err = 0; + char* logstr; - while ((c = getopt(argc, argv, "t:")) != -1) - { - switch (c) { - case 't': - nthr = atoi(optarg); - break; + int i; + bool succp; + skygw_message_t* mes; + simple_mutex_t* mtx; + size_t nactive; + thread_t** thr = NULL; + time_t t; + struct tm tm; + char c; + int nthr = 0; + int log_argc = 0; + char** log_argv = NULL; - default: - break; - } + while ((c = getopt(argc, argv, "t:")) != -1) + { + switch (c) { + case 't': + nthr = atoi(optarg); + break; + + default: + break; } + } - if (nthr <= 0) - { - fprintf(stderr, "Thread count argument is zero or " - "negative. Exiting.\n"); - err = 1; - goto return_err; - } + if (nthr <= 0) + { + fprintf(stderr, "Thread count argument is zero or " + "negative. Exiting.\n"); + err = 1; + goto return_err; + } - thr = (thread_t **)calloc(1, nthr*sizeof(thread_t*)); - - if (thr == NULL) - { - fprintf(stderr, "Failed to allocate memory for thread " - "structure. Exiting.\n"); - err = 1; - goto return_err; - - } - i = atexit(skygw_logmanager_exit); - - if (i != 0) { - fprintf(stderr, "Couldn't register exit function.\n"); - } - - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); - if(!succp) - fprintf(stderr, "Log manager initialization failed.\n"); - ss_dassert(succp); + thr = (thread_t **)calloc(1, nthr*sizeof(thread_t*)); - t = time(NULL); - tm = *(localtime(&t)); - err = skygw_log_write_flush(LOGFILE_ERROR, - "%04d %02d/%02d %02d.%02d.%02d", - tm.tm_year+1900, - tm.tm_mon+1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec); - - skygw_logmanager_init("/tmp", log_argc, log_argv); - logstr = ("First write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + if (thr == NULL) + { + fprintf(stderr, "Failed to allocate memory for thread " + "structure. Exiting.\n"); + err = 1; + goto return_err; + } + i = atexit(skygw_logmanager_exit); - logstr = ("Second write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + if (i != 0) + { + fprintf(stderr, "Couldn't register exit function.\n"); + } - logstr = ("Third write, no flush."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); - logstr = ("Fourth write, no flush. Next flush only."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + if (!succp) + { + fprintf(stderr, "Log manager initialization failed.\n"); + } + ss_dassert(succp); - err = skygw_log_flush(LOGFILE_ERROR); - - logstr = "My name is %s %d years and %d months."; + t = time(NULL); + tm = *(localtime(&t)); + err = skygw_log_write_flush(LOGFILE_ERROR, + "%04d %02d/%02d %02d.%02d.%02d", + tm.tm_year+1900, + tm.tm_mon+1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); + + skygw_logmanager_init("/tmp", log_argc, log_argv); + logstr = ("First write with flush."); + err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + + logstr = ("Second write with flush."); + err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + + logstr = ("Third write, no flush."); + err = skygw_log_write(LOGFILE_ERROR, logstr); + + logstr = ("Fourth write, no flush. Next flush only."); + err = skygw_log_write(LOGFILE_ERROR, logstr); + + err = skygw_log_flush(LOGFILE_ERROR); + + logstr = "My name is %s %d years and %d months."; #if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); + skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, logstr, "TraceyTracey", 3, 7); - skygw_log_flush(LOGFILE_TRACE); + err = skygw_log_write(LOGFILE_TRACE, logstr, "TraceyTracey", 3, 7); + skygw_log_flush(LOGFILE_TRACE); #if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); + skygw_log_enable(LOGFILE_TRACE); #endif - logstr = "My name is Tracey Tracey 47 years and 7 months."; - err = skygw_log_write(LOGFILE_TRACE, logstr); + logstr = "My name is Tracey Tracey 47 years and 7 months."; + err = skygw_log_write(LOGFILE_TRACE, logstr); #if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); -#endif - logstr = "My name is Stacey %s"; - err = skygw_log_write_flush(LOGFILE_TRACE, logstr, " "); - skygw_logmanager_done(); -#if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); + skygw_log_enable(LOGFILE_TRACE); #endif - logstr = "My name is Philip"; - err = skygw_log_write(LOGFILE_TRACE, logstr); + logstr = "My name is Stacey %s"; + err = skygw_log_write_flush(LOGFILE_TRACE, logstr, " "); + skygw_logmanager_done(); #if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); + skygw_log_enable(LOGFILE_TRACE); #endif - logstr = "Philip."; - err = skygw_log_write(LOGFILE_TRACE, logstr); + logstr = "My name is Philip"; + err = skygw_log_write(LOGFILE_TRACE, logstr); #if !defined(SS_DEBUG) - skygw_log_enable(LOGFILE_TRACE); + skygw_log_enable(LOGFILE_TRACE); #endif - logstr = "Ph%dlip."; - err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - - skygw_logmanager_init("/tmp", log_argc, log_argv); - logstr = ("A terrible error has occurred!"); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + logstr = "Philip."; + err = skygw_log_write(LOGFILE_TRACE, logstr); +#if !defined(SS_DEBUG) + skygw_log_enable(LOGFILE_TRACE); +#endif + logstr = "Ph%dlip."; + err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - logstr = ("Hi, how are you?"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + skygw_logmanager_init("/tmp", log_argc, log_argv); + logstr = ("A terrible error has occurred!"); + err = skygw_log_write_flush(LOGFILE_ERROR, logstr); - logstr = ("I'm doing fine!"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + logstr = ("Hi, how are you?"); + err = skygw_log_write(LOGFILE_MESSAGE, logstr); - logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operators & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + logstr = ("I'm doing fine!"); + err = skygw_log_write(LOGFILE_MESSAGE, logstr); - logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I thought that would you like to come to my place and have a little piece of cheese with us. Just me and my mom - and you, of course. Then, if you wish, we could listen to the radio and keep company for our little Steven, my mom's cat, you know."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_done(); + logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " + "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " + "immediately; the two forms are equivalent. Applying the operators & to both parts " + "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " + "address of the i-th element beyond a."); + err = skygw_log_write(LOGFILE_ERROR, logstr); + + logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I " + "thought that would you like to come to my place and have a little piece of cheese " + "with us. Just me and my mom - and you, of course. Then, if you wish, we could " + "listen to the radio and keep company for our little Steven, my mom's cat, you know."); + err = skygw_log_write(LOGFILE_MESSAGE, logstr); + skygw_logmanager_done(); #if defined(TEST1) - - mes = skygw_message_init(); - mtx = simple_mutex_init(NULL, "testmtx"); - /** Test starts */ + mes = skygw_message_init(); + mtx = simple_mutex_init(NULL, "testmtx"); + /** Test starts */ - fprintf(stderr, "\nStarting test #1 \n"); - - /** 1 */ - for (i=0; imes = mes; - thr[i]->mtx = mtx; - thr[i]->nactive = &nactive; - } - nactive = nthr; + fprintf(stderr, "\nStarting test #1 \n"); - for (i=0; itid = p; - } + /** 1 */ + for (i = 0; i < nthr; i++) + { + thr[i] = (thread_t*)calloc(1, sizeof(thread_t)); + thr[i]->mes = mes; + thr[i]->mtx = mtx; + thr[i]->nactive = &nactive; + } + nactive = nthr; - do { - skygw_message_wait(mes); - simple_mutex_lock(mtx, true); - if (nactive > 0) { - simple_mutex_unlock(mtx); - continue; - } - break; - } while(true); + for (i = 0; i < nthr; i++) + { + pthread_t p; + pthread_create(&p, NULL, thr_run, thr[i]); + thr[i]->tid = p; + } - for (i=0; itid, NULL); - } - /** This is to release memory */ - skygw_logmanager_done(); - - simple_mutex_unlock(mtx); - - for (i=0; i 0) + { + simple_mutex_unlock(mtx); + continue; } + break; + } while(true); + + for (i = 0; i < nthr; i++) + { + pthread_join(thr[i]->tid, NULL); + } + /** This is to release memory */ + skygw_logmanager_done(); + + simple_mutex_unlock(mtx); + + for (i = 0; i < nthr; i++) + { + free(thr[i]); + } #endif #if defined(TEST2) - fprintf(stderr, "\nStarting test #2 \n"); + fprintf(stderr, "\nStarting test #2 \n"); - /** 2 */ - for (i=0; imes = mes; - thr[i]->mtx = mtx; - thr[i]->nactive = &nactive; + /** 2 */ + for (i = 0; i < nthr; i++) + { + thr[i] = (thread_t*)calloc(1, sizeof(thread_t)); + thr[i]->mes = mes; + thr[i]->mtx = mtx; + thr[i]->nactive = &nactive; + } + nactive = nthr; + + fprintf(stderr, + "\nLaunching %d threads, each iterating %d times.", + nthr, + NITER); + + for (i = 0; i < nthr; i++) + { + pthread_t p; + pthread_create(&p, NULL, thr_run_morelog, thr[i]); + thr[i]->tid = p; + } + + fprintf(stderr, ".. done"); + + fprintf(stderr, "\nStarting to wait threads.\n"); + + do + { + skygw_message_wait(mes); + simple_mutex_lock(mtx, true); + if (nactive > 0) + { + simple_mutex_unlock(mtx); + continue; } - nactive = nthr; + break; + } while(true); - fprintf(stderr, - "\nLaunching %d threads, each iterating %d times.", - nthr, - NITER); - - for (i=0; itid = p; - } + for (i = 0; i < nthr; i++) + { + pthread_join(thr[i]->tid, NULL); + } + /** This is to release memory */ + skygw_logmanager_done(); - fprintf(stderr, ".. done"); + simple_mutex_unlock(mtx); - fprintf(stderr, "\nStarting to wait threads.\n"); - - do { - skygw_message_wait(mes); - simple_mutex_lock(mtx, true); - if (nactive > 0) { - simple_mutex_unlock(mtx); - continue; - } - break; - } while(true); + fprintf(stderr, "\nFreeing thread memory."); - for (i=0; itid, NULL); - } - /** This is to release memory */ - skygw_logmanager_done(); - - simple_mutex_unlock(mtx); + for (i = 0; i < nthr; i++) + { + free(thr[i]); + } - fprintf(stderr, "\nFreeing thread memory."); - - for (i=0; imtx, true); - *td->nactive -= 1; - simple_mutex_unlock(td->mtx); - skygw_message_send(td->mes); - return NULL; + err = skygw_log_write(LOGFILE_TRACE, logstr); + if (err != 0) + { + fprintf(stderr,"Error, log write failed.\n"); + } + ss_dassert(err == 0); + skygw_logmanager_done(); + logstr = ("Testing. One, two, three, four\n"); + err = skygw_log_write(LOGFILE_ERROR, logstr); + if (err != 0) + { + fprintf(stderr,"Error, log write failed.\n"); + } + ss_dassert(err == 0); + skygw_logmanager_init("/tmp", 0, NULL); + logstr = ("Testing. One, two, three, .. where was I?\n"); + err = skygw_log_write(LOGFILE_ERROR, logstr); + if (err != 0) + { + fprintf(stderr,"Error, log write failed.\n"); + } + ss_dassert(err == 0); + skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_done(); + simple_mutex_lock(td->mtx, true); + *td->nactive -= 1; + simple_mutex_unlock(td->mtx); + skygw_message_send(td->mes); + return NULL; } -static int nstr( - char** str_arr) +static int nstr(char** str_arr) { - int i; + int i; - for (i=0; str_arr[i] != NULL; i++) { - } - return i; + for (i = 0; str_arr[i] != NULL; i++) + { + } + return i; } char* logs[] = { - "foo", - "bar", - "done", - "critical test logging", - "longer test l o g g g i n g", - "reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line", - "shoorter one", - "two", - "scrap : 834nuft984pnw8ynup4598yp8wup8upwn48t5gpn45", - "more the same : f98uft5p8ut2p44449upnt5", - "asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd98987", - NULL + "foo", + "bar", + "done", + "critical test logging", + "longer test l o g g g i n g", + "reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally looooooooooooooooooooooooooooooooooooooo" + "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line", + "shoorter one", + "two", + "scrap : 834nuft984pnw8ynup4598yp8wup8upwn48t5gpn45", + "more the same : f98uft5p8ut2p44449upnt5", + "asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd987987asdasd98987", + NULL }; - -static void* thr_run_morelog( - void* data) +static void* thr_run_morelog(void* data) { - thread_t* td = (thread_t *)data; - int err; - int i; - int nmsg; + thread_t* td = (thread_t *)data; + int err; + int i; + int nmsg; - nmsg = nstr(logs); - - for (i=0; imtx, true); - *td->nactive -= 1; - simple_mutex_unlock(td->mtx); - skygw_message_send(td->mes); - return NULL; + } + + simple_mutex_lock(td->mtx, true); + *td->nactive -= 1; + simple_mutex_unlock(td->mtx); + skygw_message_send(td->mes); + return NULL; } diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index d9bd0fc6e..edb51fec3 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -25,88 +25,99 @@ int main(int argc, char** argv) { - int iterations = 0, i, interval = 10; - int block_size; - int succp, err = 0; - char cwd[1024]; - char tmp[2048]; - char *message; - char** optstr; - long msg_index = 1; - struct timespec ts1; - ts1.tv_sec = 0; - - memset(cwd,0,1024); - if( argc <4){ - fprintf(stderr, - "Log Manager Log Order Test\n" - "Writes an ascending number into the error log to determine if log writes are in order.\n" - "Usage:\t testorder \n"); - return 1; - } - - block_size = atoi(argv[3]); - if(block_size < 1 || block_size > 1024){ - fprintf(stderr,"Message size too small or large, must be at least 1 byte long and must not exceed 1024 bytes."); - return 1; - } + int iterations = 0, i, interval = 10; + int block_size; + int succp, err = 0; + char cwd[1024]; + char tmp[2048]; + char *message; + char** optstr; + long msg_index = 1; + struct timespec ts1; + ts1.tv_sec = 0; - - if(getcwd(cwd,sizeof(cwd)) == NULL || - (optstr = (char**)malloc(sizeof(char*)*4)) == NULL || - (message = (char*)malloc(sizeof(char)*block_size))== NULL){ - fprintf(stderr,"Fatal Error, exiting..."); - return 1; - } - - memset(tmp,0,1024); - - sprintf(tmp,"%s",cwd); - optstr[0] = strdup("log_manager"); - optstr[1] = NULL; - - iterations = atoi(argv[1]); - interval = atoi(argv[2]); - - succp = skygw_logmanager_init(tmp, 1, optstr); - if(!succp) - fprintf(stderr,"Error, log manager initialization failed.\n"); - ss_dassert(succp); - - skygw_log_disable(LOGFILE_TRACE); - skygw_log_disable(LOGFILE_MESSAGE); - skygw_log_disable(LOGFILE_DEBUG); - - for(i = 0;i 8192){ - fprintf(stderr,"Error: Message too long"); - break; - } - memset(message + strlen(message), ' ', msgsize); - memset(message + block_size - 1,'\0',1); - if(interval > 0 && i % interval == 0){ - err = skygw_log_write_flush(LOGFILE_ERROR, message); - }else{ - err = skygw_log_write(LOGFILE_ERROR, message); + memset(cwd, 0, 1024); + if (argc < 4) + { + fprintf(stderr, + "Log Manager Log Order Test\n" + "Writes an ascending number into the error log to determine if log writes are in order.\n" + "Usage:\t testorder \n"); + return 1; } - if(err){ - fprintf(stderr,"Error: log_manager returned %d",err); - break; - } - ts1.tv_nsec = 100*1000000; - nanosleep(&ts1, NULL); - } - skygw_log_flush(LOGFILE_ERROR); - skygw_logmanager_done(); - free(message); - free(optstr[0]); - free(optstr[1]); - free(optstr[2]); - free(optstr[3]); - free(optstr); - return 0; + block_size = atoi(argv[3]); + if (block_size < 1 || block_size > 1024) + { + fprintf(stderr,"Message size too small or large, must be at least 1 byte long and " + "must not exceed 1024 bytes."); + return 1; + } + + if (getcwd(cwd, sizeof(cwd)) == NULL || + (optstr = (char**)malloc(sizeof(char*) * 4)) == NULL || + (message = (char*)malloc(sizeof(char) * block_size)) == NULL) + { + fprintf(stderr,"Fatal Error, exiting..."); + return 1; + } + + memset(tmp, 0, 1024); + + sprintf(tmp, "%s", cwd); + optstr[0] = strdup("log_manager"); + optstr[1] = NULL; + + iterations = atoi(argv[1]); + interval = atoi(argv[2]); + + succp = skygw_logmanager_init(tmp, 1, optstr); + + if (!succp) + { + fprintf(stderr,"Error, log manager initialization failed.\n"); + } + ss_dassert(succp); + + skygw_log_disable(LOGFILE_TRACE); + skygw_log_disable(LOGFILE_MESSAGE); + skygw_log_disable(LOGFILE_DEBUG); + + for (i = 0; i < iterations; i++) + { + sprintf(message, "message|%ld", msg_index++); + int msgsize = block_size - strlen(message); + if (msgsize < 0 || msgsize > 8192) + { + fprintf(stderr,"Error: Message too long"); + break; + } + memset(message + strlen(message), ' ', msgsize); + memset(message + block_size - 1, '\0', 1); + if (interval > 0 && i % interval == 0) + { + err = skygw_log_write_flush(LOGFILE_ERROR, message); + } + else + { + err = skygw_log_write(LOGFILE_ERROR, message); + } + if (err) + { + fprintf(stderr,"Error: log_manager returned %d",err); + break; + } + ts1.tv_nsec = 100 * 1000000; + nanosleep(&ts1, NULL); + } + + skygw_log_flush(LOGFILE_ERROR); + skygw_logmanager_done(); + free(message); + free(optstr[0]); + free(optstr[1]); + free(optstr[2]); + free(optstr[3]); + free(optstr); + return 0; } From 49866b5959f3d0d6ba6f52fbb6aa6b82ff059479 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 21:19:50 +0200 Subject: [PATCH 113/179] ss_info_dassert now enabled also in release mode. --- server/core/test/testadminusers.c | 7 +++++++ server/core/test/testdcb.c | 7 +++++++ server/core/test/testfeedback.c | 7 +++++++ server/core/test/testfilter.c | 7 +++++++ server/core/test/testgwbitmask.c | 7 +++++++ server/core/test/testhash.c | 8 +++++++- server/core/test/testhint.c | 7 +++++++ server/core/test/testmemlog.c | 7 +++++++ server/core/test/testmodutil.c | 7 +++++++ server/core/test/testpoll.c | 7 +++++++ server/core/test/testserver.c | 7 +++++++ server/core/test/testsession.c | 7 +++++++ server/core/test/testspinlock.c | 7 +++++++ 13 files changed, 91 insertions(+), 1 deletion(-) diff --git a/server/core/test/testadminusers.c b/server/core/test/testadminusers.c index cfa9be6ba..cdc7687ef 100644 --- a/server/core/test/testadminusers.c +++ b/server/core/test/testadminusers.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testdcb.c b/server/core/test/testdcb.c index 9668d8a23..7e63ce134 100644 --- a/server/core/test/testdcb.c +++ b/server/core/test/testdcb.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testfeedback.c b/server/core/test/testfeedback.c index c1d53b9cc..17fb3cf99 100644 --- a/server/core/test/testfeedback.c +++ b/server/core/test/testfeedback.c @@ -28,6 +28,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #define FAILTEST(s) printf("TEST FAILED: " s "\n");return 1; #include #include diff --git a/server/core/test/testfilter.c b/server/core/test/testfilter.c index bf97d7897..1fee8557c 100644 --- a/server/core/test/testfilter.c +++ b/server/core/test/testfilter.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testgwbitmask.c b/server/core/test/testgwbitmask.c index 86bad1245..df446c600 100644 --- a/server/core/test/testgwbitmask.c +++ b/server/core/test/testgwbitmask.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testhash.c b/server/core/test/testhash.c index 60f759839..5af247989 100644 --- a/server/core/test/testhash.c +++ b/server/core/test/testhash.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include @@ -154,7 +161,6 @@ static bool do_hashtest( ss_dfprintf(stderr, "\t\t..done\n\nTest completed successfully.\n\n"); - CHK_HASHTABLE(h); hashtable_free(h); diff --git a/server/core/test/testhint.c b/server/core/test/testhint.c index 388d0f610..77c1aa4e8 100644 --- a/server/core/test/testhint.c +++ b/server/core/test/testhint.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testmemlog.c b/server/core/test/testmemlog.c index d1cad08ae..7d2f29e93 100644 --- a/server/core/test/testmemlog.c +++ b/server/core/test/testmemlog.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testmodutil.c b/server/core/test/testmodutil.c index 39632ab6d..a865560e3 100644 --- a/server/core/test/testmodutil.c +++ b/server/core/test/testmodutil.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testpoll.c b/server/core/test/testpoll.c index 61978b4f4..40ed00f0c 100644 --- a/server/core/test/testpoll.c +++ b/server/core/test/testpoll.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testserver.c b/server/core/test/testserver.c index 7e00b4f0b..b82c1f2c8 100644 --- a/server/core/test/testserver.c +++ b/server/core/test/testserver.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testsession.c b/server/core/test/testsession.c index 4d8d4cc04..8d2dd46af 100644 --- a/server/core/test/testsession.c +++ b/server/core/test/testsession.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include diff --git a/server/core/test/testspinlock.c b/server/core/test/testspinlock.c index ed8fa7214..3f2357d4a 100644 --- a/server/core/test/testspinlock.c +++ b/server/core/test/testspinlock.c @@ -27,6 +27,13 @@ * @endverbatim */ +// To ensure that ss_info_assert asserts also when builing in non-debug mode. +#if !defined(SS_DEBUG) +#define SS_DEBUG +#endif +#if defined(NDEBUG) +#undef NDEBUG +#endif #include #include #include From 72072778de08c607d32490a9b489d3895b9a0ba2 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 11 Nov 2015 08:39:47 +0000 Subject: [PATCH 114/179] Consume the given buffer in all cases, as caller has to assume that this will take place. --- server/modules/routing/readconnroute.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 79d0032dc..cd670285d 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -70,6 +70,7 @@ * 11/06/2015 Martin Brampton Remove decrement n_current (moved to dcb.c) * 09/09/2015 Martin Brampton Modify error handler * 25/09/2015 Martin Brampton Block callback processing when no router session in the DCB + * 09/11/2015 Martin Brampton Modified routeQuery - must free "queue" regardless of outcome * * @endverbatim */ @@ -731,6 +732,7 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue) "server.%s", mysql_command,rses_is_closed ? " Session is closed." : ""))); rc = 0; + while((queue = GWBUF_CONSUME_ALL(queue)) != NULL); goto return_rc; } From 1fc6b002118877f966e0b9840cc02779f3fcb1b6 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 11 Nov 2015 09:03:48 +0000 Subject: [PATCH 115/179] Add conditionally compiled mechanism to "show buffers" to give a list of the currently allocated buffers, with a trace for each one of the calls that led to its creation. --- server/core/buffer.c | 128 +++++++++++++++++++++++++++++- server/include/buffer.h | 5 +- server/modules/routing/debugcmd.c | 10 ++- 3 files changed, 140 insertions(+), 3 deletions(-) diff --git a/server/core/buffer.c b/server/core/buffer.c index 8de0f6851..0c1990c6c 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -35,7 +35,9 @@ * 15/07/2014 Mark Riddoch Addition of properties * 28/08/2014 Mark Riddoch Adition of tail pointer to speed * the gwbuf_append process - * + * 09/11/2015 Martin Brampton Add buffer tracing (conditional compilation), + * accessed by "show buffers" maxadmin command + * * @endverbatim */ #include @@ -47,6 +49,13 @@ #include #include +#if defined(BUFFER_TRACE) +#include +#include + +static HASHTABLE *buffer_hashtable = NULL; +#endif + /** Defined in log_manager.cc */ extern int lm_enabled_logfiles_bitmask; extern size_t log_ses_count[]; @@ -56,6 +65,12 @@ static buffer_object_t* gwbuf_remove_buffer_object( GWBUF* buf, buffer_object_t* bufobj); +#if defined(BUFFER_TRACE) +static void gwbuf_add_to_hashtable(GWBUF *buf); +static int bhashfn (void *key); +static int bcmpfn (void *key1, void *key2); +static void gwbuf_remove_from_hashtable(GWBUF *buf); +#endif /** * Allocate a new gateway buffer structure of size bytes. @@ -119,9 +134,111 @@ retblock: "Error : Memory allocation failed due to %s.", strerror_r(errno, errbuf, sizeof(errbuf))))); } +#if defined(BUFFER_TRACE) + else + { + gwbuf_add_to_hashtable(rval); + } +#endif return rval; } +#if defined(BUFFER_TRACE) +/** + * Store a trace of buffer creation + * + * @param buf The buffer to record + */ +static void +gwbuf_add_to_hashtable(GWBUF *buf) +{ + void *array[16]; + size_t size, i, total; + char **strings; + char *tracetext; + + size = backtrace (array, 16); + strings = backtrace_symbols (array, size); + total = (2 * size) + 1; + for (i = 0; i < size; i++) + { + total += strlen(strings[i]); + } + tracetext = (char *)malloc(total); + if (tracetext) + { + char *ptr = tracetext; + for (i = 0; i < size; i++) + { + sprintf(ptr, "\t%s\n", strings[i]); + ptr += (strlen(strings[i]) + 2); + } + free (strings); + + if (NULL == buffer_hashtable) + { + buffer_hashtable = hashtable_alloc(10000, bhashfn, bcmpfn); + hashtable_memory_fns(buffer_hashtable,NULL,NULL,NULL,(HASHMEMORYFN)free); + } + hashtable_add(buffer_hashtable, buf, (void *)tracetext); + } +} + +/** + * Hash a buffer (address) to an integer + * + * @param key The pointer to the buffer + */ +static int +bhashfn(void *key) +{ + return (int)((uintptr_t) key % INT_MAX); +} + +/** + * Compare two buffer keys (pointers) + * + * @param key1 The pointer to the first buffer + * @param key2 The pointer to the second buffer + */ +static int +bcmpfn(void *key1, void *key2) +{ + return key1 == key2 ? 0 : 1; +} + +/** + * Remove a buffer from the store of buffer traces + * + * @param buf The buffer to be removed + */ +static void +gwbuf_remove_from_hashtable(GWBUF *buf) +{ + hashtable_delete(buffer_hashtable, buf); +} + +/** + * Print all buffer traces via a given print DCB + * + * @param pdcb Print DCB for output + */ +void +dprintAllBuffers(void *pdcb) +{ + void *buf; + char *backtrace; + HASHITERATOR *buffers = hashtable_iterator(buffer_hashtable); + while (NULL != (buf = hashtable_next(buffers))) + { + dcb_printf((DCB *)pdcb, "Buffer: %p\n", (void *)buf); + backtrace = hashtable_fetch(buffer_hashtable, buf); + dcb_printf((DCB *)pdcb, "%s", backtrace); + } + hashtable_iterator_free(buffers); +} +#endif + /** * Free a gateway buffer * @@ -162,6 +279,9 @@ BUF_PROPERTY *prop; buf->hint = buf->hint->next; hint_free(h); } +#if defined(BUFFER_TRACE) + gwbuf_remove_from_hashtable(buf); +#endif free(buf); } @@ -201,6 +321,9 @@ GWBUF *rval; rval->tail = rval; rval->next = NULL; CHK_GWBUF(rval); +#if defined(BUFFER_TRACE) + gwbuf_add_to_hashtable(rval); +#endif return rval; } @@ -268,6 +391,9 @@ GWBUF *gwbuf_clone_portion( clonebuf->next = NULL; clonebuf->tail = clonebuf; CHK_GWBUF(clonebuf); +#if defined(BUFFER_TRACE) + gwbuf_add_to_hashtable(clonebuf); +#endif return clonebuf; } diff --git a/server/include/buffer.h b/server/include/buffer.h index 6be9fc7aa..0e1b34246 100644 --- a/server/include/buffer.h +++ b/server/include/buffer.h @@ -43,6 +43,7 @@ * 03/10/2014 Martin Brampton Pointer arithmetic standard conformity * Add more buffer handling macros * Add gwbuf_rtrim (handle chains) + * 09/11/2014 Martin Brampton Add dprintAllBuffers (conditional compilation) * * @endverbatim */ @@ -52,7 +53,6 @@ #include #include - EXTERN_C_BLOCK_BEGIN /** @@ -202,6 +202,9 @@ void gwbuf_add_buffer_object(GWBUF* buf, void* data, void (*donefun_fp)(void *)); void* gwbuf_get_buffer_object_data(GWBUF* buf, bufobj_id_t id); +#if defined(BUFFER_TRACE) +extern void dprintAllBuffers(void *pdcb); +#endif EXTERN_C_BLOCK_END diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index bd15b54ec..5b444d87c 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -43,7 +43,8 @@ * 29/05/14 Mark Riddoch Add Filter support * 16/10/14 Mark Riddoch Add show eventq * 05/03/15 Massimiliano Pinto Added enable/disable feedback - * 27/05/15 Martin Brampton Add show persistent [server] + * 27/05/15 Martin Brampton Add show persistent [server] + * 06/11/15 Martin Brampton Add show buffers (conditional compilation) * * @endverbatim */ @@ -60,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +109,12 @@ static void telnetdShowUsers(DCB *); * The subcommands of the show command */ struct subcommand showoptions[] = { +#if defined(BUFFER_TRACE) + { "buffers", 0, dprintAllBuffers, + "Show all buffers with backtrace", + "Show all buffers with backtrace", + {0, 0, 0} }, +#endif { "dcbs", 0, dprintAllDCBs, "Show all descriptor control blocks (network connections)", "Show all descriptor control blocks (network connections)", From abea233a2ea541fd119d7330c4eb8b4bd60eef64 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 9 Nov 2015 10:57:20 +0200 Subject: [PATCH 116/179] If log manager not inited messages are written to stdout. If the log manager has not been inited, then messages are written to stdout. In practice this can happen if something is directly or indirectly logged during the startup of maxscale, before skygw_logmanager_init() has been called. Some refactoring is needed to allow skygw_logmanager_init() to be called very early at program startup. --- log_manager/log_manager.cc | 13 +++++-------- log_manager/log_manager.h | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 3b01141b9..454a98800 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -305,11 +305,6 @@ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); void flushall_logfiles(bool flush); bool thr_flushall_check(); -const char* get_logpath_default(void) -{ - return "/var/log/maxscale"; -} - static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]) { fnames_conf_t* fn; @@ -1622,8 +1617,10 @@ static bool logmanager_register(bool writep) if (lm == NULL) { - // TODO: This looks fishy. - succp = logmanager_init_nomutex(get_logpath_default(), 0, NULL); + // If someone is logging before the log manager has been inited, + // or after the log manager has been finished, the messages are + // written to stdout. + succp = logmanager_init_nomutex(NULL, 0, NULL); } } /** if logmanager existed or was succesfully restarted, increase link */ @@ -1747,7 +1744,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, { use_stdout = 1; // TODO: Re-arrange things so that fn->fn_logpath can be NULL. - fn->fn_logpath = strdup(get_logpath_default()); + fn->fn_logpath = strdup("/tmp"); // Not used. } /** Set identity string for syslog if it is not set in config.*/ diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 21023871b..f17a32d02 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -183,8 +183,6 @@ int skygw_log_get_augmentation(); EXTERN_C_BLOCK_END -const char* get_logpath_default(void); - /** * Helper, not to be called directly. */ From 2183d5d3c5f582ea82b5279ad1a127b879972edb Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 11 Nov 2015 11:31:07 +0000 Subject: [PATCH 117/179] Fix mistakes in merging. --- server/core/buffer.c | 5 - server/modules/routing/debugcmd.c | 207 +++++++++++++++--------------- 2 files changed, 105 insertions(+), 107 deletions(-) diff --git a/server/core/buffer.c b/server/core/buffer.c index 0c1990c6c..e8a1d9100 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -56,11 +56,6 @@ static HASHTABLE *buffer_hashtable = NULL; #endif -/** Defined in log_manager.cc */ -extern int lm_enabled_logfiles_bitmask; -extern size_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - static buffer_object_t* gwbuf_remove_buffer_object( GWBUF* buf, buffer_object_t* bufobj); diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 6dd780e66..894eec39e 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -112,104 +112,108 @@ static void telnetdShowUsers(DCB *); struct subcommand showoptions[] = { #if defined(BUFFER_TRACE) { "buffers", 0, dprintAllBuffers, - "Show all buffers with backtrace", - "Show all buffers with backtrace", - {0, 0, 0} }, + "Show all buffers with backtrace", + "Show all buffers with backtrace", + {0, 0, 0} }, #endif - { "dcbs", 0, dprintAllDCBs, - "Show all descriptor control blocks (network connections)", - "Show all descriptor control blocks (network connections)", - {0, 0, 0} }, - { "dcb", 1, dprintDCB, - "Show a single descriptor control block e.g. show dcb 0x493340", - "Show a single descriptor control block e.g. show dcb 0x493340", - {ARG_TYPE_DCB, 0, 0} }, - { "dbusers", 1, dcb_usersPrint, - "Show statistics and user names for a service's user table.\n\t\tExample : show dbusers ", - "Show statistics and user names for a service's user table.\n\t\tExample : show dbusers |", - {ARG_TYPE_DBUSERS, 0, 0} }, - { "epoll", 0, dprintPollStats, - "Show the poll statistics", - "Show the poll statistics", - {0, 0, 0} }, - { "eventq", 0, dShowEventQ, - "Show the queue of events waiting to be processed", - "Show the queue of events waiting to be processed", - {0, 0, 0} }, - { "eventstats", 0, dShowEventStats, - "Show the event statistics", - "Show the event statistics", - {0, 0, 0} }, - { "feedbackreport", 0, moduleShowFeedbackReport, - "Show the report of MaxScale loaded modules, suitable for Notification Service", - "Show the report of MaxScale loaded modules, suitable for Notification Service", - {0, 0, 0} }, - { "filter", 1, dprintFilter, - "Show details of a filter, called with a filter name", - "Show details of a filter, called with the address of a filter", - {ARG_TYPE_FILTER, 0, 0} }, - { "filters", 0, dprintAllFilters, - "Show all filters", - "Show all filters", - {0, 0, 0} }, - { "modules", 0, dprintAllModules, - "Show all currently loaded modules", - "Show all currently loaded modules", - {0, 0, 0} }, - { "monitor", 1, monitorShow, - "Show the monitor details", - "Show the monitor details", - {ARG_TYPE_MONITOR, 0, 0} }, - { "monitors", 0, monitorShowAll, - "Show the monitors that are configured", - "Show the monitors that are configured", - {0, 0, 0} }, - { "persistent", 1, dprintPersistentDCBs, - "Show persistent pool for a named server, e.g. show persistent dbnode1", - "Show persistent pool for a server, e.g. show persistent 0x485390. The address may also be replaced with the server name from the configuration file", - {ARG_TYPE_SERVER, 0, 0} }, - { "server", 1, dprintServer, - "Show details for a named server, e.g. show server dbnode1", - "Show details for a server, e.g. show server 0x485390. The address may also be repalced with the server name from the configuration file", - {ARG_TYPE_SERVER, 0, 0} }, - { "servers", 0, dprintAllServers, - "Show all configured servers", - "Show all configured servers", - {0, 0, 0} }, - { "serversjson", 0, dprintAllServersJson, - "Show all configured servers in JSON format", - "Show all configured servers in JSON format", - {0, 0, 0} }, - { "services", 0, dprintAllServices, - "Show all configured services in MaxScale", - "Show all configured services in MaxScale", - {0, 0, 0} }, - { "service", 1, dprintService, - "Show a single service in MaxScale, may be passed a service name", - "Show a single service in MaxScale, may be passed a service name or address of a service object", - {ARG_TYPE_SERVICE, 0, 0} }, - { "session", 1, dprintSession, - "Show a single session in MaxScale, e.g. show session 0x284830", - "Show a single session in MaxScale, e.g. show session 0x284830", - {ARG_TYPE_SESSION, 0, 0} }, - { "sessions", 0, dprintAllSessions, - "Show all active sessions in MaxScale", - "Show all active sessions in MaxScale", - {0, 0, 0} }, - { "tasks", 0, hkshow_tasks, - "Show all active housekeeper tasks in MaxScale", - "Show all active housekeeper tasks in MaxScale", - {0, 0, 0} }, - { "threads", 0, dShowThreads, - "Show the status of the polling threads in MaxScale", - "Show the status of the polling threads in MaxScale", - {0, 0, 0} }, - { "users", 0, telnetdShowUsers, - "Show statistics and user names for the debug interface", - "Show statistics and user names for the debug interface", - {0, 0, 0} }, - { NULL, 0, NULL, NULL, NULL, - {0, 0, 0} } + { "dcbs", 0, dprintAllDCBs, + "Show all descriptor control blocks (network connections)", + "Show all descriptor control blocks (network connections)", + {0, 0, 0} }, + { "dcb", 1, dprintDCB, + "Show a single descriptor control block e.g. show dcb 0x493340", + "Show a single descriptor control block e.g. show dcb 0x493340", + {ARG_TYPE_DCB, 0, 0} }, + { "dbusers", 1, dcb_usersPrint, + "Show statistics and user names for a service's user table.\n" + "\t\tExample : show dbusers ", + "Show statistics and user names for a service's user table.\n" + "\t\tExample : show dbusers |", + {ARG_TYPE_DBUSERS, 0, 0} }, + { "epoll", 0, dprintPollStats, + "Show the poll statistics", + "Show the poll statistics", + {0, 0, 0} }, + { "eventq", 0, dShowEventQ, + "Show the queue of events waiting to be processed", + "Show the queue of events waiting to be processed", + {0, 0, 0} }, + { "eventstats", 0, dShowEventStats, + "Show the event statistics", + "Show the event statistics", + {0, 0, 0} }, + { "feedbackreport", 0, moduleShowFeedbackReport, + "Show the report of MaxScale loaded modules, suitable for Notification Service", + "Show the report of MaxScale loaded modules, suitable for Notification Service", + {0, 0, 0} }, + { "filter", 1, dprintFilter, + "Show details of a filter, called with a filter name", + "Show details of a filter, called with the address of a filter", + {ARG_TYPE_FILTER, 0, 0} }, + { "filters", 0, dprintAllFilters, + "Show all filters", + "Show all filters", + {0, 0, 0} }, + { "modules", 0, dprintAllModules, + "Show all currently loaded modules", + "Show all currently loaded modules", + {0, 0, 0} }, + { "monitor", 1, monitorShow, + "Show the monitor details", + "Show the monitor details", + {ARG_TYPE_MONITOR, 0, 0} }, + { "monitors", 0, monitorShowAll, + "Show the monitors that are configured", + "Show the monitors that are configured", + {0, 0, 0} }, + { "persistent", 1, dprintPersistentDCBs, + "Show persistent pool for a named server, e.g. show persistent dbnode1", + "Show persistent pool for a server, e.g. show persistent 0x485390. " + "The address may also be replaced with the server name from the configuration file", + {ARG_TYPE_SERVER, 0, 0} }, + { "server", 1, dprintServer, + "Show details for a named server, e.g. show server dbnode1", + "Show details for a server, e.g. show server 0x485390. The address may also be " + "repalced with the server name from the configuration file", + {ARG_TYPE_SERVER, 0, 0} }, + { "servers", 0, dprintAllServers, + "Show all configured servers", + "Show all configured servers", + {0, 0, 0} }, + { "serversjson", 0, dprintAllServersJson, + "Show all configured servers in JSON format", + "Show all configured servers in JSON format", + {0, 0, 0} }, + { "services", 0, dprintAllServices, + "Show all configured services in MaxScale", + "Show all configured services in MaxScale", + {0, 0, 0} }, + { "service", 1, dprintService, + "Show a single service in MaxScale, may be passed a service name", + "Show a single service in MaxScale, may be passed a service name or address of a service object", + {ARG_TYPE_SERVICE, 0, 0} }, + { "session", 1, dprintSession, + "Show a single session in MaxScale, e.g. show session 0x284830", + "Show a single session in MaxScale, e.g. show session 0x284830", + {ARG_TYPE_SESSION, 0, 0} }, + { "sessions", 0, dprintAllSessions, + "Show all active sessions in MaxScale", + "Show all active sessions in MaxScale", + {0, 0, 0} }, + { "tasks", 0, hkshow_tasks, + "Show all active housekeeper tasks in MaxScale", + "Show all active housekeeper tasks in MaxScale", + {0, 0, 0} }, + { "threads", 0, dShowThreads, + "Show the status of the polling threads in MaxScale", + "Show the status of the polling threads in MaxScale", + {0, 0, 0} }, + { "users", 0, telnetdShowUsers, + "Show statistics and user names for the debug interface", + "Show statistics and user names for the debug interface", + {0, 0, 0} }, + { NULL, 0, NULL, NULL, NULL, + {0, 0, 0} } }; /** @@ -714,14 +718,13 @@ static struct { * Convert a string argument to a numeric, observing prefixes * for number bases, e.g. 0x for hex, 0 for octal * - * @param dcb The client DCB - * @param mode The CLI mode - * @param arg The string representation of the argument - * @param arg_type The target type for the argument + * @param mode The CLI mode + * @param arg The string representation of the argument + * @param arg_type The target type for the argument * @return The argument as a long integer */ static unsigned long -convert_arg(DCB* dcb, int mode, char *arg, int arg_type) +convert_arg(int mode, char *arg, int arg_type) { unsigned long rval; SERVICE *service; From 14b8dbc4d8aa78be747b4de41b4c67845106f32a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 9 Nov 2015 12:45:50 +0200 Subject: [PATCH 118/179] Miniman changes to make testlog work. testlog.c can never have worked, or then it cannot have been kept up to date for a very long time. --- log_manager/test/CMakeLists.txt | 1 + log_manager/test/testlog.c | 83 +++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/log_manager/test/CMakeLists.txt b/log_manager/test/CMakeLists.txt index bbcfd5791..e510cf79a 100644 --- a/log_manager/test/CMakeLists.txt +++ b/log_manager/test/CMakeLists.txt @@ -3,3 +3,4 @@ add_executable(testorder testorder.c) target_link_libraries(testlog pthread log_manager utils) target_link_libraries(testorder pthread log_manager utils) add_test(NAME Internal-TestLogOrder COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/logorder.sh 200 0 1000 ${CMAKE_CURRENT_BINARY_DIR}/logorder.log) +add_test(Internal-TestLog testlog) diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 886a66c09..4f94b0cee 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,15 @@ static void* thr_run_morelog(void* data); #define TEST3 #define TEST4 +const char USAGE[]= + "usage: %s [-t <#threads>]\n" + "\n" + "-t: Number of threads. Default is %d.\n"; +const int N_THR = 4; + +#define TEST_ERROR(msg)\ + do { fprintf(stderr, "[%s:%d]: %s\n", basename(__FILE__), __LINE__, msg); } while (false) + int main(int argc, char* argv[]) { int err = 0; @@ -66,7 +76,7 @@ int main(int argc, char* argv[]) time_t t; struct tm tm; char c; - int nthr = 0; + int nthr = N_THR; int log_argc = 0; char** log_argv = NULL; @@ -75,21 +85,27 @@ int main(int argc, char* argv[]) switch (c) { case 't': nthr = atoi(optarg); + if (nthr <= 0) + { + err = 1; + } break; default: + err = 1; break; } } - if (nthr <= 0) + if (err != 0) { - fprintf(stderr, "Thread count argument is zero or " - "negative. Exiting.\n"); + fprintf(stderr, USAGE, argv[0], N_THR); err = 1; goto return_err; } + printf("Using %d threads.\n", nthr); + thr = (thread_t **)calloc(1, nthr*sizeof(thread_t*)); if (thr == NULL) @@ -319,20 +335,20 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif + succp = skygw_logmanager_init("/tmp", log_argc, log_argv); + ss_dassert(succp); + logstr = ("\tTEST 3 - test enabling and disabling logs."); err = skygw_log_write(LOGFILE_ERROR, logstr); ss_dassert(err == 0); - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); - ss_dassert(succp); - skygw_log_disable(LOGFILE_TRACE); logstr = ("1.\tWrite once to ERROR and twice to MESSAGE log."); err = skygw_log_write(LOGFILE_MESSAGE, logstr); ss_dassert(err == 0); err = skygw_log_write(LOGFILE_TRACE, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); err = skygw_log_write(LOGFILE_ERROR, logstr); ss_dassert(err == 0); @@ -355,18 +371,18 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_TRACE, logstr); ss_dassert(err == 0); err = skygw_log_write(LOGFILE_ERROR, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); skygw_log_disable(LOGFILE_TRACE); logstr = ("4.\tWrite to none."); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); err = skygw_log_write(LOGFILE_TRACE, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); err = skygw_log_write(LOGFILE_ERROR, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); skygw_log_enable(LOGFILE_ERROR); skygw_log_enable(LOGFILE_MESSAGE); @@ -375,7 +391,7 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_MESSAGE, logstr); ss_dassert(err == 0); err = skygw_log_write(LOGFILE_TRACE, logstr); - ss_dassert(err != 0); /**< Must fail */ + ss_dassert(err == 0); err = skygw_log_write(LOGFILE_ERROR, logstr); ss_dassert(err == 0); @@ -401,6 +417,7 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_MESSAGE, logstr); ss_dassert(err == 0); + skygw_log_enable(LOGFILE_TRACE); logstr = ("3.\tWrite to TRACE log only."); err = skygw_log_write(LOGFILE_TRACE, logstr); ss_dassert(err == 0); @@ -415,7 +432,7 @@ int main(int argc, char* argv[]) logstr = ("5.\tThis should not appear anywhere since MESSAGE " "is disabled."); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - ss_dassert(err != 0); + ss_dassert(err == 0); skygw_logmanager_done(); @@ -447,7 +464,7 @@ int main(int argc, char* argv[]) logstr = ("10.\tThis should not appear anywhere since MESSAGE is " "disabled."); err = skygw_log_write_flush(LOGFILE_MESSAGE, logstr); - ss_dassert(err != 0); + ss_dassert(err == 0); skygw_log_enable(LOGFILE_MESSAGE); @@ -493,14 +510,13 @@ static void* thr_run(void* data) int err; skygw_logmanager_init("/tmp", 0, NULL); - skygw_logmanager_done(); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_done(); @@ -513,7 +529,7 @@ static void* thr_run(void* data) "cat, you know."); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -522,7 +538,7 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_init("/tmp", 0, NULL); @@ -530,11 +546,13 @@ static void* thr_run(void* data) skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); +#if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); +#endif err = skygw_log_write(LOGFILE_TRACE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_done(); @@ -547,22 +565,22 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_init("/tmp", 0, NULL); skygw_logmanager_done(); skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); - skygw_logmanager_done(); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("..and you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_done(); skygw_logmanager_init("/tmp", 0, NULL); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) @@ -571,7 +589,7 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_TRACE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_init("/tmp", 0, NULL); @@ -583,7 +601,7 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_init("/tmp", 0, NULL); @@ -591,10 +609,11 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_done(); + skygw_logmanager_init("/tmp", 0, NULL); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -606,26 +625,28 @@ static void* thr_run(void* data) err = skygw_log_write(LOGFILE_TRACE, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); skygw_logmanager_done(); + skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Testing. One, two, three, four\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); + skygw_logmanager_done(); skygw_logmanager_init("/tmp", 0, NULL); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) { - fprintf(stderr,"Error, log write failed.\n"); + TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_done(); skygw_logmanager_init("/tmp", 0, NULL); skygw_logmanager_done(); simple_mutex_lock(td->mtx, true); From 90a8646ac2e88c3dd72b41503ee54eb5233936f8 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 9 Nov 2015 13:55:59 +0200 Subject: [PATCH 119/179] Whitespace and indentation changes. Also changed line-endings from DOS CRLF to only LF. In addition, made functions const correct. --- server/core/secrets.c | 841 ++++++++++++++++++++------------------- server/include/secrets.h | 21 +- 2 files changed, 437 insertions(+), 425 deletions(-) diff --git a/server/core/secrets.c b/server/core/secrets.c index b92398acf..98318dc99 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -1,415 +1,426 @@ -/* - * This file is distributed as part of the MariaDB Corporation MaxScale. It is free - * software: you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation, - * version 2. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright MariaDB Corporation Ab 2013-2014 - */ - -#include -#include -#include -#include -#include -#include -#include - -/** - * Generate a random printable character - * - * @return A random printable character - */ -static unsigned char -secrets_randomchar() -{ - return (char)((rand() % ('~' - ' ')) + ' '); -} - -static int -secrets_random_str(unsigned char *output, int len) -{ -int i; - srand((unsigned long )time(0L) ^ (unsigned long )output); - - for ( i = 0; i < len; ++i ) - { - output[i] = secrets_randomchar(); - } - return 0; -} - -/** - * This routine reads data from a binary file named ".secrets" and extracts the AES encryption key - * and the AES Init Vector. - * If the path parameter is not null the custom path is interpreted as a folder - * containing the .secrets file. Otherwise the default location is used. - * @return The keys structure or NULL on error - */ -static MAXKEYS * -secrets_readKeys(char* path) -{ -char secret_file[PATH_MAX+1]; -char *home; -MAXKEYS *keys; -struct stat secret_stats; -int fd; -int len; -static int reported = 0; - if(path != NULL) - snprintf(secret_file, PATH_MAX, "%s/.secrets", path); - else - snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir()); - /* Try to access secrets file */ - if (access(secret_file, R_OK) == -1) - { - int eno = errno; - errno = 0; - if (eno == ENOENT) - { - if (!reported) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Encrypted password file %s can't be accessed " - "(%s). Password encryption is not used.", - secret_file, - strerror_r(eno, errbuf, sizeof(errbuf))))); - reported = 1; - } - } - else - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : access for secrets file " - "[%s] failed. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - } - return NULL; - } - - /* open secret file */ - if ((fd = open(secret_file, O_RDONLY)) < 0) - { - int eno = errno; - errno = 0; - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed opening secret " - "file [%s]. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - return NULL; - - } - - /* accessing file details */ - if (fstat(fd, &secret_stats) < 0) { - int eno = errno; - errno = 0; - close(fd); - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : fstat for secret file %s " - "failed. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - return NULL; - } - - if (secret_stats.st_size != sizeof(MAXKEYS)) - { - int eno = errno; - errno = 0; - close(fd); - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Secrets file %s has " - "incorrect size. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - return NULL; - } - if (secret_stats.st_mode != (S_IRUSR|S_IFREG)) - { - close(fd); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Ignoring secrets file " - "%s, invalid permissions.", - secret_file))); - return NULL; - } - - if ((keys = (MAXKEYS *)malloc(sizeof(MAXKEYS))) == NULL) - { - close(fd); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed " - "for key structure."))); - return NULL; - } - - /** - * Read all data from file. - * MAXKEYS (secrets.h) is struct for key, _not_ length-related macro. - */ - len = read(fd, keys, sizeof(MAXKEYS)); - - if (len != sizeof(MAXKEYS)) - { - int eno = errno; - errno = 0; - close(fd); - free(keys); - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Read from secrets file " - "%s failed. Read %d, expected %d bytes. Error %d, %s.", - secret_file, - len, - sizeof(MAXKEYS), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - return NULL; - } - - /* Close the file */ - if (close(fd) < 0) { - int eno = errno; - errno = 0; - free(keys); - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed closing the " - "secrets file %s. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - return NULL; - } - ss_dassert(keys != NULL); - return keys; -} - -/** - * secrets_writeKeys - * - * This routine writes into a binary file the AES encryption key - * and the AES Init Vector - * - * @param secret_file The file with secret keys - * @return 0 on success and 1 on failure - */ -int secrets_writeKeys(char *path) -{ -int fd,randfd; -unsigned int randval; -MAXKEYS key; -char secret_file[PATH_MAX + 10]; - -if(strlen(path) > PATH_MAX) -{ - skygw_log_write(LOGFILE_ERROR,"Error: Pathname too long."); - return 1; -} - - snprintf(secret_file,PATH_MAX + 9,"%s/.secrets",path); - secret_file[PATH_MAX + 9] = '\0'; - - /* Open for writing | Create | Truncate the file for writing */ - if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed opening secret " - "file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - return 1; - } - - /* Open for writing | Create | Truncate the file for writing */ - if ((randfd = open("/dev/random", O_RDONLY)) < 0) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed opening /dev/random. Error %d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - close(fd); - return 1; - } - - if(read(randfd,(void*)&randval,sizeof(unsigned int)) < 1) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to read /dev/random."))); - close(fd); - close(randfd); - return 1; - } - - close(randfd); - srand(randval); - secrets_random_str(key.enckey, MAXSCALE_KEYLEN); - secrets_random_str(key.initvector, MAXSCALE_IV_LEN); - - /* Write data */ - if (write(fd, &key, sizeof(key)) < 0) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed writing into " - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - close(fd); - return 1; - } - - /* close file */ - if (close(fd) < 0) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed closing the " - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - } - - if( chmod(secret_file, S_IRUSR) < 0) - { - char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to change the permissions of the" - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - } - - return 0; -} - -/** - * Decrypt a password that is stored inthe MaxScale configuration file. - * If the password is not encrypted, ie is not a HEX string, then the - * original is returned, this allows for backward compatibility with - * unencrypted password. - * - * Note the return is always a malloc'd string that the caller must free - * - * @param crypt The encrypted password - * @return The decrypted password - */ -char * -decryptPassword(char *crypt) -{ -MAXKEYS *keys; -AES_KEY aeskey; -unsigned char *plain; -char *ptr; -unsigned char encrypted[80]; -int enlen; - - keys = secrets_readKeys(NULL); - if (!keys) - return strdup(crypt); - /* - ** If the input is not a HEX string return the input - ** it probably was not encrypted - */ - for (ptr = crypt; *ptr; ptr++) - { - if (!isxdigit(*ptr)) - { - free(keys); - return strdup(crypt); - } - } - - enlen = strlen(crypt) / 2; - gw_hex2bin(encrypted, crypt, strlen(crypt)); - - if ((plain = (unsigned char *)malloc(80)) == NULL) - { - free(keys); - return NULL; - } - - AES_set_decrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); - - AES_cbc_encrypt(encrypted, plain, enlen, &aeskey, keys->initvector, AES_DECRYPT); - free(keys); - - return (char *)plain; -} - -/** - * Encrypt a password that can be stored in the MaxScale configuration file. - * - * Note the return is always a malloc'd string that the caller must free - * @param path Path the the .secrets file - * @param password The password to encrypt - * @return The encrypted password - */ -char * -encryptPassword(char* path, char *password) -{ -MAXKEYS *keys; -AES_KEY aeskey; -int padded_len; -char *hex_output; -unsigned char padded_passwd[80]; -unsigned char encrypted[80]; - - if ((keys = secrets_readKeys(path)) == NULL) - return NULL; - - memset(padded_passwd, 0, 80); - strncpy((char *)padded_passwd, password, 79); - padded_len = ((strlen(password) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; - - AES_set_encrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); - - AES_cbc_encrypt(padded_passwd, encrypted, padded_len, &aeskey, keys->initvector, AES_ENCRYPT); - hex_output = (char *)malloc(padded_len * 2); - gw_bin2hex(hex_output, encrypted, padded_len); - free(keys); - - return hex_output; -} +/* + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright MariaDB Corporation Ab 2013-2014 + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * Generate a random printable character + * + * @return A random printable character + */ +static unsigned char +secrets_randomchar() +{ + return (char)((rand() % ('~' - ' ')) + ' '); +} + +static int +secrets_random_str(unsigned char *output, int len) +{ + int i; + srand((unsigned long )time(0L) ^ (unsigned long )output); + + for (i = 0; i < len; ++i) + { + output[i] = secrets_randomchar(); + } + return 0; +} + +/** + * This routine reads data from a binary file named ".secrets" and extracts the AES encryption key + * and the AES Init Vector. + * If the path parameter is not null the custom path is interpreted as a folder + * containing the .secrets file. Otherwise the default location is used. + * @return The keys structure or NULL on error + */ +static MAXKEYS * +secrets_readKeys(const char* path) +{ + char secret_file[PATH_MAX+1]; + char *home; + MAXKEYS *keys; + struct stat secret_stats; + int fd; + int len; + static int reported = 0; + + if (path != NULL) + { + snprintf(secret_file, PATH_MAX, "%s/.secrets", path); + } + else + { + snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir()); + } + + /* Try to access secrets file */ + if (access(secret_file, R_OK) == -1) + { + int eno = errno; + errno = 0; + if (eno == ENOENT) + { + if (!reported) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "Encrypted password file %s can't be accessed " + "(%s). Password encryption is not used.", + secret_file, + strerror_r(eno, errbuf, sizeof(errbuf))))); + reported = 1; + } + } + else + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : access for secrets file " + "[%s] failed. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + } + return NULL; + } + + /* open secret file */ + if ((fd = open(secret_file, O_RDONLY)) < 0) + { + int eno = errno; + errno = 0; + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Failed opening secret " + "file [%s]. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + return NULL; + + } + + /* accessing file details */ + if (fstat(fd, &secret_stats) < 0) { + int eno = errno; + errno = 0; + close(fd); + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : fstat for secret file %s " + "failed. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + return NULL; + } + + if (secret_stats.st_size != sizeof(MAXKEYS)) + { + int eno = errno; + errno = 0; + close(fd); + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Secrets file %s has " + "incorrect size. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + return NULL; + } + + if (secret_stats.st_mode != (S_IRUSR|S_IFREG)) + { + close(fd); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Ignoring secrets file " + "%s, invalid permissions.", + secret_file))); + return NULL; + } + + if ((keys = (MAXKEYS *)malloc(sizeof(MAXKEYS))) == NULL) + { + close(fd); + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Memory allocation failed " + "for key structure."))); + return NULL; + } + + /** + * Read all data from file. + * MAXKEYS (secrets.h) is struct for key, _not_ length-related macro. + */ + len = read(fd, keys, sizeof(MAXKEYS)); + + if (len != sizeof(MAXKEYS)) + { + int eno = errno; + errno = 0; + close(fd); + free(keys); + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Read from secrets file " + "%s failed. Read %d, expected %d bytes. Error %d, %s.", + secret_file, + len, + sizeof(MAXKEYS), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + return NULL; + } + + /* Close the file */ + if (close(fd) < 0) { + int eno = errno; + errno = 0; + free(keys); + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Failed closing the " + "secrets file %s. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))))); + return NULL; + } + ss_dassert(keys != NULL); + return keys; +} + +/** + * secrets_writeKeys + * + * This routine writes into a binary file the AES encryption key + * and the AES Init Vector + * + * @param secret_file The file with secret keys + * @return 0 on success and 1 on failure + */ +int secrets_writeKeys(const char *path) +{ + int fd,randfd; + unsigned int randval; + MAXKEYS key; + char secret_file[PATH_MAX + 10]; + + if (strlen(path) > PATH_MAX) + { + skygw_log_write(LOGFILE_ERROR,"Error: Pathname too long."); + return 1; + } + + snprintf(secret_file,PATH_MAX + 9,"%s/.secrets",path); + secret_file[PATH_MAX + 9] = '\0'; + + /* Open for writing | Create | Truncate the file for writing */ + if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed opening secret " + "file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))))); + return 1; + } + + /* Open for writing | Create | Truncate the file for writing */ + if ((randfd = open("/dev/random", O_RDONLY)) < 0) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed opening /dev/random. Error %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))))); + close(fd); + return 1; + } + + if (read(randfd,(void*)&randval,sizeof(unsigned int)) < 1) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed to read /dev/random."))); + close(fd); + close(randfd); + return 1; + } + + close(randfd); + srand(randval); + secrets_random_str(key.enckey, MAXSCALE_KEYLEN); + secrets_random_str(key.initvector, MAXSCALE_IV_LEN); + + /* Write data */ + if (write(fd, &key, sizeof(key)) < 0) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed writing into " + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))))); + close(fd); + return 1; + } + + /* close file */ + if (close(fd) < 0) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed closing the " + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))))); + } + + if (chmod(secret_file, S_IRUSR) < 0) + { + char errbuf[STRERROR_BUFLEN]; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : failed to change the permissions of the" + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))))); + } + + return 0; +} + +/** + * Decrypt a password that is stored inthe MaxScale configuration file. + * If the password is not encrypted, ie is not a HEX string, then the + * original is returned, this allows for backward compatibility with + * unencrypted password. + * + * Note the return is always a malloc'd string that the caller must free + * + * @param crypt The encrypted password + * @return The decrypted password + */ +char * +decryptPassword(const char *crypt) +{ + MAXKEYS *keys; + AES_KEY aeskey; + unsigned char *plain; + const char *ptr; + unsigned char encrypted[80]; + int enlen; + + keys = secrets_readKeys(NULL); + if (!keys) + { + return strdup(crypt); + } + /* + ** If the input is not a HEX string return the input + ** it probably was not encrypted + */ + for (ptr = crypt; *ptr; ptr++) + { + if (!isxdigit(*ptr)) + { + free(keys); + return strdup(crypt); + } + } + + enlen = strlen(crypt) / 2; + gw_hex2bin(encrypted, crypt, strlen(crypt)); + + if ((plain = (unsigned char *)malloc(80)) == NULL) + { + free(keys); + return NULL; + } + + AES_set_decrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); + + AES_cbc_encrypt(encrypted, plain, enlen, &aeskey, keys->initvector, AES_DECRYPT); + free(keys); + + return (char *)plain; +} + +/** + * Encrypt a password that can be stored in the MaxScale configuration file. + * + * Note the return is always a malloc'd string that the caller must free + * @param path Path the the .secrets file + * @param password The password to encrypt + * @return The encrypted password + */ +char * +encryptPassword(const char* path, const char *password) +{ + MAXKEYS *keys; + AES_KEY aeskey; + int padded_len; + char *hex_output; + unsigned char padded_passwd[80]; + unsigned char encrypted[80]; + + if ((keys = secrets_readKeys(path)) == NULL) + { + return NULL; + } + + memset(padded_passwd, 0, 80); + strncpy((char *)padded_passwd, password, 79); + padded_len = ((strlen(password) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; + + AES_set_encrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); + + AES_cbc_encrypt(padded_passwd, encrypted, padded_len, &aeskey, keys->initvector, AES_ENCRYPT); + hex_output = (char *)malloc(padded_len * 2); + gw_bin2hex(hex_output, encrypted, padded_len); + free(keys); + + return hex_output; +} diff --git a/server/include/secrets.h b/server/include/secrets.h index cb2912827..e039de45c 100644 --- a/server/include/secrets.h +++ b/server/include/secrets.h @@ -24,8 +24,8 @@ * @verbatim * Revision History * - * Date Who Description - * 23/06/2013 Massimiliano Pinto Initial implementation + * Date Who Description + * 23/06/2013 Massimiliano Pinto Initial implementation * * @endverbatim */ @@ -40,18 +40,19 @@ #include -#define MAXSCALE_KEYLEN 32 -#define MAXSCALE_IV_LEN 16 +#define MAXSCALE_KEYLEN 32 +#define MAXSCALE_IV_LEN 16 /** * The key structure held in the secrets file */ -typedef struct maxkeys { - unsigned char enckey[MAXSCALE_KEYLEN]; - unsigned char initvector[MAXSCALE_IV_LEN]; +typedef struct maxkeys +{ + unsigned char enckey[MAXSCALE_KEYLEN]; + unsigned char initvector[MAXSCALE_IV_LEN]; } MAXKEYS; -extern int secrets_writeKeys(char *filename); -extern char *decryptPassword(char *); -extern char *encryptPassword(char*,char *); +extern int secrets_writeKeys(const char *filename); +extern char *decryptPassword(const char *); +extern char *encryptPassword(const char*, const char *); #endif From 55dbaa49c0fe8af4a73c9ff467a80377dfa83d20 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 9 Nov 2015 15:53:22 +0200 Subject: [PATCH 120/179] Logging target must be explicitly defined. Whether the log-file should be written to the filesystem or to shared memory must now be explicitly defined when calling skygw_logmanager_init() (instead of passing that via the argc/argv construct). Also, the meaning of '-l' when invoking maxscale has been changed. Earlier -l [file|shm] specified whether the trace and debug logs should be written to shared memory (while the error and message logs always were written to the filesystem) and the _default_ was to write them to shared memory. Now, with only one file, '-l' has still the same meaning, but it decides whether the one and only logfile should be written to shared memory, or the filesystem and the _default_ is to write it to the filesystem. --- log_manager/log_manager.cc | 48 ++++++------------- log_manager/log_manager.h | 10 +++- log_manager/test/testlog.c | 40 ++++++++-------- log_manager/test/testorder.c | 2 +- server/core/gateway.c | 30 +++--------- server/core/maxkeys.c | 2 +- server/core/maxpasswd.c | 2 +- server/include/test_utils.h | 2 +- server/modules/filter/test/harness_common.c | 4 +- .../modules/routing/binlog/maxbinlogcheck.c | 2 +- .../modules/routing/binlog/test/testbinlog.c | 2 +- 11 files changed, 58 insertions(+), 86 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 454a98800..72af88911 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -90,8 +90,6 @@ ssize_t log_ses_count[LOGFILE_LAST] = {0}; */ const char* shm_pathname_prefix = "/dev/shm/"; -/** Logfile ids from call argument '-s' */ -char* shmem_id_str = NULL; /** Errors are written to syslog too by default */ char* syslog_id_str = strdup("LOGFILE_ERROR"); char* syslog_ident_str = NULL; @@ -231,6 +229,7 @@ struct logmanager fnames_conf_t lm_fnames_conf; logfile_t lm_logfile; filewriter_t lm_filewriter; + log_target_t lm_target; #if defined(SS_DEBUG) skygw_chk_t lm_chk_tail; #endif @@ -274,7 +273,7 @@ static void* thr_filewriter_fun(void* data); static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); static void logmanager_unregister(void); -static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]); +static bool logmanager_init_nomutex(const char* logdir, log_target_t target, int argc, char* argv[]); static void logmanager_done_nomutex(void); static bool logmanager_is_valid_id(logfile_id_t id); @@ -305,7 +304,7 @@ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); void flushall_logfiles(bool flush); bool thr_flushall_check(); -static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]) +static bool logmanager_init_nomutex(const char* logdir, log_target_t target, int argc, char* argv[]) { fnames_conf_t* fn; filewriter_t* fw; @@ -319,6 +318,8 @@ static bool logmanager_init_nomutex(const char* logdir, int argc, char* argv[]) err = 1; goto return_succp; } + + lm->lm_target = (target == LOG_TARGET_DEFAULT ? LOG_TARGET_FS : target); #if defined(SS_DEBUG) lm->lm_chk_top = CHK_NUM_LOGMANAGER; lm->lm_chk_tail = CHK_NUM_LOGMANAGER; @@ -414,13 +415,15 @@ return_succp: * Initializes log managing routines in MariaDB Corporation MaxScale. * * @param logdir The directory for the log file. If NULL logging will be made to stdout. - * @param argc number of arguments in argv array - * @param argv arguments array + * @param target Whether the log should be written to filesystem or shared memory. + * Meaningless if logdir is NULL. + * @param argc Number of arguments in argv array. + * @param argv Arguments array. * * @return true if succeed, otherwise false * */ -bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]) +bool skygw_logmanager_init(const char* logdir, log_target_t target, int argc, char* argv[]) { bool succp = false; @@ -432,7 +435,7 @@ bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]) goto return_succp; } - succp = logmanager_init_nomutex(logdir, argc, argv); + succp = logmanager_init_nomutex(logdir, target, argc, argv); return_succp: release_lock(&lmlock); @@ -1620,7 +1623,7 @@ static bool logmanager_register(bool writep) // If someone is logging before the log manager has been inited, // or after the log manager has been finished, the messages are // written to stdout. - succp = logmanager_init_nomutex(NULL, 0, NULL); + succp = logmanager_init_nomutex(NULL, LOG_TARGET_DEFAULT, 0, NULL); } } /** if logmanager existed or was succesfully restarted, increase link */ @@ -1687,8 +1690,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, const char* argstr = "-h - help\n" "-l .......(no default)\n" - "-m ............(argv[0])\n" - "-s .......(no default)\n"; + "-m ............(argv[0])\n"; /** * When init_started is set, clean must be done for it. @@ -1700,7 +1702,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, #endif optind = 1; /**lm_target == LOG_TARGET_SHMEM); bool write_syslog; /** Open syslog immediately. Print pid of loggind process. */ @@ -1811,23 +1809,7 @@ static bool logfiles_init(logmanager_t* lm) { openlog(syslog_ident_str, LOG_PID | LOG_NDELAY, LOG_USER); } - /** - * Initialize log file, pass softlink flag if necessary. - */ - /** - * Check if the file is stored in shared memory. If so, - * a symbolic link will be created to log directory. - */ - if (shmem_id_str != NULL && - strcasestr(shmem_id_str, STRLOGID(LOGFILE_ERROR)) != NULL) - { - store_shmem = true; - } - else - { - store_shmem = false; - } /** * Check if file is also written to syslog. */ diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index f17a32d02..ec75eb81c 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -42,7 +42,6 @@ typedef enum LOGFILE_LAST = LOGFILE_DEBUG } logfile_id_t; - typedef enum { FILEWRITER_INIT, @@ -50,6 +49,13 @@ typedef enum FILEWRITER_DONE } filewriter_state_t; +typedef enum +{ + LOG_TARGET_DEFAULT = 0, + LOG_TARGET_FS = 1, // File system + LOG_TARGET_SHMEM = 2, // Shared memory +} log_target_t; + /** * Thread-specific logging information. */ @@ -145,7 +151,7 @@ int mxs_log_rotate(); int mxs_log_enable_priority(int priority); int mxs_log_disable_priority(int priority); -bool skygw_logmanager_init(const char* logdir, int argc, char* argv[]); +bool skygw_logmanager_init(const char* logdir, log_target_t target, int argc, char* argv[]); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 4f94b0cee..496e25aa2 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -122,7 +122,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Couldn't register exit function.\n"); } - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); if (!succp) { @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init("/tmp", log_argc, log_argv); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -189,7 +189,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init("/tmp", log_argc, log_argv); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -335,7 +335,7 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); @@ -400,7 +400,7 @@ int main(int argc, char* argv[]) #endif /* TEST 3 */ #if defined(TEST4) - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -436,7 +436,7 @@ int main(int argc, char* argv[]) skygw_logmanager_done(); - succp = skygw_logmanager_init("/tmp", log_argc, log_argv); + succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -509,7 +509,7 @@ static void* thr_run(void* data) char* logstr; int err; - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -533,7 +533,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -541,8 +541,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); @@ -556,7 +556,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference " "to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -568,11 +568,11 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); skygw_logmanager_done(); skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("..and you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -581,7 +581,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -592,7 +592,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -604,7 +604,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("..... and you too?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -613,7 +613,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -629,7 +629,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three, four\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -638,7 +638,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -647,7 +647,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", 0, NULL); + skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); skygw_logmanager_done(); simple_mutex_lock(td->mtx, true); *td->nactive -= 1; diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index edb51fec3..91885f862 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -71,7 +71,7 @@ int main(int argc, char** argv) iterations = atoi(argv[1]); interval = atoi(argv[2]); - succp = skygw_logmanager_init(tmp, 1, optstr); + succp = skygw_logmanager_init(tmp, LOG_TARGET_FS, 1, optstr); if (!succp) { diff --git a/server/core/gateway.c b/server/core/gateway.c index cd7e9f64f..49e8cf72b 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1077,7 +1077,7 @@ int main(int argc, char **argv) char* tmp_path; char* tmp_var; int option_index; - int logtofile = 0; /* Use shared memory or file */ + log_target_t log_target = LOG_TARGET_FS; int *syslog_enabled = &config_get_global_options()->syslog; /** Log to syslog */ int *maxscalelog_enabled = &config_get_global_options()->maxlog; /** Log with MaxScale */ ssize_t log_flush_timeout_ms = 0; @@ -1169,9 +1169,9 @@ int main(int argc, char **argv) case 'l': if (strncasecmp(optarg, "file", PATH_MAX) == 0) - logtofile = 1; + log_target = LOG_TARGET_FS; else if (strncasecmp(optarg, "shm", PATH_MAX) == 0) - logtofile = 0; + log_target = LOG_TARGET_SHMEM; else { char* logerr = "Configuration file argument " @@ -1703,8 +1703,6 @@ int main(int argc, char **argv) * argv[0] */ { - char buf[1024]; - char *argv[8]; bool succp; if (mkdir(get_logdir(), 0777) != 0 && errno != EEXIST) @@ -1729,24 +1727,10 @@ int main(int argc, char **argv) logmanager_enable_syslog(*syslog_enabled); logmanager_enable_maxscalelog(*maxscalelog_enabled); - if (logtofile) - { - argv[1] = "-l"; /*< write to syslog */ - /** Logs that should be syslogged */ - argv[2] = "LOGFILE_MESSAGE,LOGFILE_ERROR" - "LOGFILE_DEBUG,LOGFILE_TRACE"; - argv[3] = NULL; - succp = skygw_logmanager_init(get_logdir(), 3, argv); - } - else - { - argv[1] = "-s"; /*< store to shared memory */ - argv[2] = "LOGFILE_DEBUG,LOGFILE_TRACE"; /*< to shm */ - argv[3] = "-l"; /*< write to syslog */ - argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< to syslog */ - argv[5] = NULL; - succp = skygw_logmanager_init(get_logdir(), 5, argv); - } + char* log_argv[] = { "MaxScale", "-l", "LOGFILE_MESSAGE,LOGFILE_ERROR", NULL }; + int log_argc = sizeof(log_argv) / sizeof(log_argv[0]) - 1; + + succp = skygw_logmanager_init(get_logdir(), log_target, log_argc, log_argv); if (!succp) { diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 39651b54c..14850a332 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, arg_count, arg_vector); + skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); free(arg_vector); if (secrets_writeKeys(keyfile)) diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 96e00dd18..f24ecd21c 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -63,7 +63,7 @@ main(int argc, char **argv) arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, arg_count, arg_vector); + skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); free(arg_vector); pw = calloc(81, sizeof(char)); diff --git a/server/include/test_utils.h b/server/include/test_utils.h index 4b1d9bc6f..bd3daa777 100644 --- a/server/include/test_utils.h +++ b/server/include/test_utils.h @@ -20,7 +20,7 @@ void init_test_env(char *path) NULL }; - skygw_logmanager_init(logdir, argc, argv); + skygw_logmanager_init(logdir, LOG_TARGET_DEFAULT, argc, argv); poll_init(); hkinit(); } diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index e657fbdd0..6ec0f12a2 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -18,7 +18,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ char** optstr; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ - skygw_logmanager_init(NULL,0,NULL); + skygw_logmanager_init(NULL,LOG_TARGET_DEFAULT,0,NULL); } if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) @@ -55,7 +55,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ optstr = (char**)malloc(sizeof(char*)*2); optstr[0] = strdup("log_manager"); optstr[1] = NULL; - skygw_logmanager_init(tmp, 1, optstr); + skygw_logmanager_init(tmp, LOG_TARGET_DEFAULT, 1, optstr); free(optstr); rval = process_opts(argc,argv); diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 50e7e489a..2c8966226 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -136,7 +136,7 @@ int main(int argc, char **argv) { arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, arg_count, arg_vector); + skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); skygw_log_set_augmentation(0); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index da75005b4..0ee73df77 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -101,7 +101,7 @@ int main(int argc, char **argv) { arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, arg_count,arg_vector); + skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count,arg_vector); free(arg_vector); skygw_log_disable(LOGFILE_DEBUG); From 24bed47794fab3af54f9fc7966e957f285423140 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 10:17:42 +0200 Subject: [PATCH 121/179] Syslog ident must be provided explicitly. The syslog ident must be provided explicitly when calling skygw_logmanager_init (and not provided via the argv array). It can be NULL, in which case it automatically will be the program name. The openlog() call is now always made, irrespective of what the value of the global syslog flag is. That way it will be possible to turn syslog logging on or off after the fact. --- log_manager/log_manager.cc | 70 ++++++------------- log_manager/log_manager.h | 5 +- log_manager/test/testlog.c | 40 +++++------ log_manager/test/testorder.c | 2 +- server/core/gateway.c | 2 +- server/core/maxkeys.c | 2 +- server/core/maxpasswd.c | 2 +- server/include/test_utils.h | 2 +- server/modules/filter/test/harness_common.c | 4 +- .../modules/routing/binlog/maxbinlogcheck.c | 2 +- .../modules/routing/binlog/test/testbinlog.c | 2 +- 11 files changed, 56 insertions(+), 77 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 72af88911..79f954074 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -91,8 +91,7 @@ ssize_t log_ses_count[LOGFILE_LAST] = {0}; const char* shm_pathname_prefix = "/dev/shm/"; /** Errors are written to syslog too by default */ -char* syslog_id_str = strdup("LOGFILE_ERROR"); -char* syslog_ident_str = NULL; +char* syslog_id_str = strdup("LOGFILE_ERROR"); /** Forward declarations */ @@ -273,7 +272,10 @@ static void* thr_filewriter_fun(void* data); static logfile_t* logmanager_get_logfile(logmanager_t* lm); static bool logmanager_register(bool writep); static void logmanager_unregister(void); -static bool logmanager_init_nomutex(const char* logdir, log_target_t target, int argc, char* argv[]); +static bool logmanager_init_nomutex(const char* ident, + const char* logdir, + log_target_t target, + int argc, char* argv[]); static void logmanager_done_nomutex(void); static bool logmanager_is_valid_id(logfile_id_t id); @@ -304,7 +306,10 @@ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); void flushall_logfiles(bool flush); bool thr_flushall_check(); -static bool logmanager_init_nomutex(const char* logdir, log_target_t target, int argc, char* argv[]) +static bool logmanager_init_nomutex(const char* ident, + const char* logdir, + log_target_t target, + int argc, char* argv[]) { fnames_conf_t* fn; filewriter_t* fw; @@ -345,11 +350,9 @@ static bool logmanager_init_nomutex(const char* logdir, log_target_t target, int fn->fn_state = UNINIT; fw->fwr_state = UNINIT; - if (!do_syslog) - { - free(syslog_id_str); - syslog_id_str = NULL; - } + // The openlog call is always made, but a connection to the system logger will + // not be made until a call to syslog is made. + openlog(ident, LOG_PID | LOG_ODELAY, LOG_USER); /** Initialize configuration including log file naming info */ if (!fnames_conf_init(fn, logdir, argc, argv)) @@ -414,6 +417,7 @@ return_succp: /** * Initializes log managing routines in MariaDB Corporation MaxScale. * + * @param ident The syslog ident. If NULL, then the program name is used. * @param logdir The directory for the log file. If NULL logging will be made to stdout. * @param target Whether the log should be written to filesystem or shared memory. * Meaningless if logdir is NULL. @@ -423,7 +427,10 @@ return_succp: * @return true if succeed, otherwise false * */ -bool skygw_logmanager_init(const char* logdir, log_target_t target, int argc, char* argv[]) +bool skygw_logmanager_init(const char* ident, + const char* logdir, + log_target_t target, + int argc, char* argv[]) { bool succp = false; @@ -435,7 +442,7 @@ bool skygw_logmanager_init(const char* logdir, log_target_t target, int argc, ch goto return_succp; } - succp = logmanager_init_nomutex(logdir, target, argc, argv); + succp = logmanager_init_nomutex(ident, logdir, target, argc, argv); return_succp: release_lock(&lmlock); @@ -474,10 +481,8 @@ static void logmanager_done_nomutex(void) /** Release logfile memory */ logfile_done(lf); - if (syslog_id_str) - { - closelog(); - } + closelog(); + /** Release messages and finally logmanager memory */ fnames_conf_done(&lm->lm_fnames_conf); skygw_message_done(lm->lm_clientmes); @@ -1623,7 +1628,7 @@ static bool logmanager_register(bool writep) // If someone is logging before the log manager has been inited, // or after the log manager has been finished, the messages are // written to stdout. - succp = logmanager_init_nomutex(NULL, LOG_TARGET_DEFAULT, 0, NULL); + succp = logmanager_init_nomutex(NULL, NULL, LOG_TARGET_DEFAULT, 0, NULL); } } /** if logmanager existed or was succesfully restarted, increase link */ @@ -1689,8 +1694,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, bool succp = false; const char* argstr = "-h - help\n" - "-l .......(no default)\n" - "-m ............(argv[0])\n"; + "-l .......(no default)\n"; /** * When init_started is set, clean must be done for it. @@ -1702,7 +1706,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, #endif optind = 1; /**fn_logpath = strdup("/tmp"); // Not used. } - /** Set identity string for syslog if it is not set in config.*/ - if (do_syslog) - { - syslog_ident_str = - (syslog_ident_str == NULL ? - (argv == NULL ? strdup(program_invocation_short_name) : strdup(*argv)) : - syslog_ident_str); - } - /* ss_dfprintf(stderr, "\n\n\tCommand line : "); - for (i = 0; i < argc; i++) - { - ss_dfprintf(stderr, "%s ", argv[i]); - } - ss_dfprintf(stderr, "\n");*/ #if defined(NOT_USED) fprintf(stderr, "Log :\t%s/%s1%s\n\n", @@ -1804,12 +1786,6 @@ static bool logfiles_init(logmanager_t* lm) bool store_shmem = (lm->lm_target == LOG_TARGET_SHMEM); bool write_syslog; - /** Open syslog immediately. Print pid of loggind process. */ - if (syslog_id_str != NULL) - { - openlog(syslog_ident_str, LOG_PID | LOG_NDELAY, LOG_USER); - } - /** * Check if file is also written to syslog. */ diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index ec75eb81c..2318f7ae8 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -151,7 +151,10 @@ int mxs_log_rotate(); int mxs_log_enable_priority(int priority); int mxs_log_disable_priority(int priority); -bool skygw_logmanager_init(const char* logdir, log_target_t target, int argc, char* argv[]); +bool skygw_logmanager_init(const char* ident, + const char* logdir, + log_target_t target, + int argc, char* argv[]); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 496e25aa2..152d3b082 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -122,7 +122,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Couldn't register exit function.\n"); } - succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); if (!succp) { @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -189,7 +189,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -335,7 +335,7 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); @@ -400,7 +400,7 @@ int main(int argc, char* argv[]) #endif /* TEST 3 */ #if defined(TEST4) - succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -436,7 +436,7 @@ int main(int argc, char* argv[]) skygw_logmanager_done(); - succp = skygw_logmanager_init("/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -509,7 +509,7 @@ static void* thr_run(void* data) char* logstr; int err; - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -533,7 +533,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -541,8 +541,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); @@ -556,7 +556,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference " "to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -568,11 +568,11 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); skygw_logmanager_done(); skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("..and you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -581,7 +581,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -592,7 +592,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -604,7 +604,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("..... and you too?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -613,7 +613,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -629,7 +629,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three, four\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -638,7 +638,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -647,7 +647,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init("/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); skygw_logmanager_done(); simple_mutex_lock(td->mtx, true); *td->nactive -= 1; diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 91885f862..3b149ee7b 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -71,7 +71,7 @@ int main(int argc, char** argv) iterations = atoi(argv[1]); interval = atoi(argv[2]); - succp = skygw_logmanager_init(tmp, LOG_TARGET_FS, 1, optstr); + succp = skygw_logmanager_init(NULL, tmp, LOG_TARGET_FS, 1, optstr); if (!succp) { diff --git a/server/core/gateway.c b/server/core/gateway.c index 49e8cf72b..0ae0e5989 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1730,7 +1730,7 @@ int main(int argc, char **argv) char* log_argv[] = { "MaxScale", "-l", "LOGFILE_MESSAGE,LOGFILE_ERROR", NULL }; int log_argc = sizeof(log_argv) / sizeof(log_argv[0]) - 1; - succp = skygw_logmanager_init(get_logdir(), log_target, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, get_logdir(), log_target, log_argc, log_argv); if (!succp) { diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 14850a332..543a5f205 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); free(arg_vector); if (secrets_writeKeys(keyfile)) diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index f24ecd21c..813a9b446 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -63,7 +63,7 @@ main(int argc, char **argv) arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); free(arg_vector); pw = calloc(81, sizeof(char)); diff --git a/server/include/test_utils.h b/server/include/test_utils.h index bd3daa777..199959e5a 100644 --- a/server/include/test_utils.h +++ b/server/include/test_utils.h @@ -20,7 +20,7 @@ void init_test_env(char *path) NULL }; - skygw_logmanager_init(logdir, LOG_TARGET_DEFAULT, argc, argv); + skygw_logmanager_init(NULL, logdir, LOG_TARGET_DEFAULT, argc, argv); poll_init(); hkinit(); } diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index 6ec0f12a2..0e020b571 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -18,7 +18,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ char** optstr; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ - skygw_logmanager_init(NULL,LOG_TARGET_DEFAULT,0,NULL); + skygw_logmanager_init(NULL,NULL,LOG_TARGET_DEFAULT,0,NULL); } if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) @@ -55,7 +55,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ optstr = (char**)malloc(sizeof(char*)*2); optstr[0] = strdup("log_manager"); optstr[1] = NULL; - skygw_logmanager_init(tmp, LOG_TARGET_DEFAULT, 1, optstr); + skygw_logmanager_init(NULL, tmp, LOG_TARGET_DEFAULT, 1, optstr); free(optstr); rval = process_opts(argc,argv); diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 2c8966226..a1fcc8ec6 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -136,7 +136,7 @@ int main(int argc, char **argv) { arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); skygw_log_set_augmentation(0); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index 0ee73df77..b21c48253 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -101,7 +101,7 @@ int main(int argc, char **argv) { arg_vector[0] = "logmanager"; arg_vector[1] = NULL; - skygw_logmanager_init(NULL, LOG_TARGET_DEFAULT, arg_count,arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count,arg_vector); free(arg_vector); skygw_log_disable(LOGFILE_DEBUG); From 0b7de96eff1101446e78d5a5803f71f882e626e5 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 13:25:16 +0200 Subject: [PATCH 122/179] Log: Module variables collected into anonymous struct. Modules variables collected into anonymous struct. Easier to see whether something has module scope. --- log_manager/log_manager.cc | 56 ++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 79f954074..65b8ceb09 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -55,10 +55,20 @@ static int block_start_index; static int prevval; static simple_mutex_t msg_mutex; #endif -static int highprec = 0; -static int do_syslog = 1; -static int do_maxscalelog = 1; -static int use_stdout = 0; +static struct +{ + int highprec; + int do_syslog; + int do_maxscalelog; + int use_stdout; +} log_config = +{ + 0, // highprec + 1, // do_syslog + 1, // do_maxscalelog + 0 // use_stdout +}; + /** * Variable holding the enabled logfiles information. * Used from log users to check enabled logs prior calling @@ -666,7 +676,7 @@ static int logmanager_write_log(logfile_id_t id, { sesid_str_len = 0; } - if (highprec) + if (log_config.highprec) { timestamp_len = get_timestamp_len_hp(); } @@ -717,7 +727,7 @@ static int logmanager_write_log(logfile_id_t id, } #endif /** Book space for log string from buffer */ - if (do_maxscalelog) + if (log_config.do_maxscalelog) { // All messages are now logged to the error log file. wp = blockbuf_get_writepos(&bb, safe_str_len, flush); @@ -744,7 +754,7 @@ static int logmanager_write_log(logfile_id_t id, * to wp. * Returned timestamp_len doesn't include terminating null. */ - if (highprec) + if (log_config.highprec) { timestamp_len = snprint_timestamp_hp(wp, timestamp_len); } @@ -801,7 +811,7 @@ static int logmanager_write_log(logfile_id_t id, } wp[safe_str_len - 1] = '\n'; - if (do_maxscalelog) + if (log_config.do_maxscalelog) { blockbuf_unregister(bb); } @@ -1223,7 +1233,7 @@ static bool logfile_set_enabled(logfile_id_t id, bool val) if (logmanager_is_valid_id(id)) { - if (use_stdout == 0) + if (log_config.use_stdout == 0) { const char *name; @@ -1712,7 +1722,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, { case 'l': /** record list of log file ids for syslogged */ - if (do_syslog) + if (log_config.do_syslog) { if (syslog_id_str != NULL) { @@ -1731,12 +1741,12 @@ static bool fnames_conf_init(fnames_conf_t* fn, if (logdir) { - use_stdout = 0; + log_config.use_stdout = 0; fn->fn_logpath = strdup(logdir); } else { - use_stdout = 1; + log_config.use_stdout = 1; // TODO: Re-arrange things so that fn->fn_logpath can be NULL. fn->fn_logpath = strdup("/tmp"); // Not used. } @@ -1858,7 +1868,7 @@ static bool logfile_create(logfile_t* lf) bool succp; strpart_t spart[3]; /*< string parts of which the file is composed of */ - if (use_stdout) + if (log_config.use_stdout) { // TODO: Refactor so that lf_full_file_name can be NULL in this case. lf->lf_full_file_name = strdup("stdout"); @@ -2000,7 +2010,7 @@ static bool logfile_open_file(filewriter_t* fw, logfile_t* lf) { bool rv = true; - if (use_stdout) + if (log_config.use_stdout) { fw->fwr_file = skygw_file_alloc(lf->lf_full_file_name); fw->fwr_file->sf_file = stdout; @@ -2377,14 +2387,14 @@ static bool logfile_init(logfile_t* logfile, } #if defined(SS_DEBUG) - if (store_shmem && !use_stdout) + if (store_shmem && !log_config.use_stdout) { fprintf(stderr, "%s\t: %s->%s\n", STRLOGNAME(LOGFILE_ERROR), logfile->lf_full_link_name, logfile->lf_full_file_name); } - else if (!use_stdout) + else if (!log_config.use_stdout) { fprintf(stderr, "%s\t: %s\n", STRLOGNAME(LOGFILE_ERROR), @@ -2524,7 +2534,7 @@ static void filewriter_done(filewriter_t* fw) case INIT: fw->fwr_logmes = NULL; fw->fwr_clientmes = NULL; - if (use_stdout) + if (log_config.use_stdout) { skygw_file_free(fw->fwr_file); } @@ -2574,9 +2584,9 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) } else if ((succp = logfile_open_file(fwr, lf))) { - if (use_stdout) + if (log_config.use_stdout) { - skygw_file_free (file); + skygw_file_free(file); } else { @@ -2906,7 +2916,7 @@ void flushall_logfiles(bool flush) */ void skygw_log_sync_all(void) { - if (!use_stdout) + if (!log_config.use_stdout) { skygw_log_write(LOGFILE_TRACE,"Starting log flushing to disk."); } @@ -2927,7 +2937,7 @@ void skygw_log_sync_all(void) */ void skygw_set_highp(int val) { - highprec = val; + log_config.highprec = val; } @@ -2937,7 +2947,7 @@ void skygw_set_highp(int val) */ void logmanager_enable_syslog(int val) { - do_syslog = val; + log_config.do_syslog = val; } /** @@ -2946,7 +2956,7 @@ void logmanager_enable_syslog(int val) */ void logmanager_enable_maxscalelog(int val) { - do_maxscalelog = val; + log_config.do_maxscalelog = val; } From acb0a523a7ec90a226394f0118eb352430420e54 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 14:37:49 +0200 Subject: [PATCH 123/179] Log: No more argv parsing for log manager. Earlier, the global setting for the syslog decided whether syslog was enabled when skygw_logmanager_init was called, but not whether logging to syslog actually was made. Now syslog logging is enabled by default and the global setting decides whether or not syslog logging actually is made. That is, this opens up the possiblity for making it possible to turn on and off sysloging at runtime. Further, although the API led you to believe otherwise, it was hardwired that LOGFILE_ERROR and LOGFILE_MESSAGE messages were written to syslog. The changed removed the need for passing an argv array explicitly. --- log_manager/log_manager.cc | 119 ++++-------------- log_manager/log_manager.h | 3 +- log_manager/test/testlog.c | 42 +++---- log_manager/test/testorder.c | 11 +- server/core/gateway.c | 12 +- server/core/maxkeys.c | 15 +-- server/core/maxpasswd.c | 15 +-- server/include/test_utils.h | 10 +- server/modules/filter/test/harness_common.c | 9 +- .../modules/routing/binlog/maxbinlogcheck.c | 16 +-- .../modules/routing/binlog/test/testbinlog.c | 15 +-- 11 files changed, 56 insertions(+), 211 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 65b8ceb09..fb63713ae 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -184,7 +184,6 @@ struct logfile flat_obj_state_t lf_state; bool lf_init_started; bool lf_store_shmem; - bool lf_write_syslog; logmanager_t* lf_lmgr; /** fwr_logmes is for messages from log clients */ skygw_message_t* lf_logmes; @@ -260,8 +259,7 @@ typedef struct strpart static bool logfiles_init(logmanager_t* lmgr); static bool logfile_init(logfile_t* logfile, logmanager_t* logmanager, - bool store_shmem, - bool write_syslog); + bool store_shmem); static void logfile_done(logfile_t* logfile); static void logfile_free_memory(logfile_t* lf); static void logfile_flush(logfile_t* lf); @@ -275,7 +273,7 @@ static bool filewriter_init(logmanager_t* logmanager, skygw_message_t* clientmes, skygw_message_t* logmes); static void filewriter_done(filewriter_t* filewriter); -static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir, int argc, char* argv[]); +static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir); static void fnames_conf_done(fnames_conf_t* fn); static void fnames_conf_free_memory(fnames_conf_t* fn); static void* thr_filewriter_fun(void* data); @@ -284,8 +282,7 @@ static bool logmanager_register(bool writep); static void logmanager_unregister(void); static bool logmanager_init_nomutex(const char* ident, const char* logdir, - log_target_t target, - int argc, char* argv[]); + log_target_t target); static void logmanager_done_nomutex(void); static bool logmanager_is_valid_id(logfile_id_t id); @@ -318,8 +315,7 @@ bool thr_flushall_check(); static bool logmanager_init_nomutex(const char* ident, const char* logdir, - log_target_t target, - int argc, char* argv[]) + log_target_t target) { fnames_conf_t* fn; filewriter_t* fw; @@ -365,7 +361,7 @@ static bool logmanager_init_nomutex(const char* ident, openlog(ident, LOG_PID | LOG_ODELAY, LOG_USER); /** Initialize configuration including log file naming info */ - if (!fnames_conf_init(fn, logdir, argc, argv)) + if (!fnames_conf_init(fn, logdir)) { err = 1; goto return_succp; @@ -431,16 +427,11 @@ return_succp: * @param logdir The directory for the log file. If NULL logging will be made to stdout. * @param target Whether the log should be written to filesystem or shared memory. * Meaningless if logdir is NULL. - * @param argc Number of arguments in argv array. - * @param argv Arguments array. * * @return true if succeed, otherwise false * */ -bool skygw_logmanager_init(const char* ident, - const char* logdir, - log_target_t target, - int argc, char* argv[]) +bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t target) { bool succp = false; @@ -448,11 +439,13 @@ bool skygw_logmanager_init(const char* ident, if (lm != NULL) { + // TODO: This is not ok. If the parameters are different then + // TODO: we pretend something is what it is not. succp = true; goto return_succp; } - succp = logmanager_init_nomutex(ident, logdir, target, argc, argv); + succp = logmanager_init_nomutex(ident, logdir, target); return_succp: release_lock(&lmlock); @@ -785,7 +778,7 @@ static int logmanager_write_log(logfile_id_t id, memset(wp + safe_str_len - 4, '.', 3); } /** write to syslog */ - if (lf->lf_write_syslog) + if (log_config.do_syslog) { // Strip away the timestamp and the prefix (e.g. "[Error]: "). const char *message = wp + timestamp_len + prefix_len; @@ -1638,7 +1631,7 @@ static bool logmanager_register(bool writep) // If someone is logging before the log manager has been inited, // or after the log manager has been finished, the messages are // written to stdout. - succp = logmanager_init_nomutex(NULL, NULL, LOG_TARGET_DEFAULT, 0, NULL); + succp = logmanager_init_nomutex(NULL, NULL, LOG_TARGET_DEFAULT); } } /** if logmanager existed or was succesfully restarted, increase link */ @@ -1687,24 +1680,15 @@ static void logmanager_unregister(void) * * @param fn The fnames_conf_t structure to initialize. * @param logdir The directory for the log file. If NULL logging will be made to stdout. - * @param argc number of arguments in argv array - * @param argv arguments array * * @return True if the initialization was performed, false otherwise. * * @details Note that input parameter lenghts are checked here. * */ -static bool fnames_conf_init(fnames_conf_t* fn, - const char* logdir, - int argc, - char* argv[]) +static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir) { - int opt; - bool succp = false; - const char* argstr = - "-h - help\n" - "-l .......(no default)\n"; + bool succp = false; /** * When init_started is set, clean must be done for it. @@ -1714,60 +1698,28 @@ static bool fnames_conf_init(fnames_conf_t* fn, fn->fn_chk_top = CHK_NUM_FNAMES; fn->fn_chk_tail = CHK_NUM_FNAMES; #endif - optind = 1; /**fn_logpath = strdup(logdir); + dir = logdir; } else { log_config.use_stdout = 1; // TODO: Re-arrange things so that fn->fn_logpath can be NULL. - fn->fn_logpath = strdup("/tmp"); // Not used. + dir = "/tmp"; } -#if defined(NOT_USED) - fprintf(stderr, - "Log :\t%s/%s1%s\n\n", - fn->fn_logpath, - LOGFILE_NAME_PREFIX, - LOGFILE_NAME_SUFFIX); -#endif - succp = true; - fn->fn_state = RUN; - CHK_FNAMES_CONF(fn); + fn->fn_logpath = strdup(dir); -return_conf_init: - if (!succp) + if (fn->fn_logpath) { - fnames_conf_done(fn); + succp = true; + fn->fn_state = RUN; + CHK_FNAMES_CONF(fn); } - ss_dassert(fn->fn_state == RUN || fn->fn_state == DONE); + return succp; } @@ -1792,27 +1744,9 @@ return_conf_init: */ static bool logfiles_init(logmanager_t* lm) { - bool succp = true; - bool store_shmem = (lm->lm_target == LOG_TARGET_SHMEM); - bool write_syslog; + bool store_shmem = (lm->lm_target == LOG_TARGET_SHMEM); - /** - * Check if file is also written to syslog. - */ - if (syslog_id_str != NULL && - strcasestr(syslog_id_str, STRLOGID(LOGFILE_ERROR)) != NULL) - { - write_syslog = true; - } - else - { - write_syslog = false; - } - - succp = logfile_init(&lm->lm_logfile, - lm, - store_shmem, - write_syslog); + bool succp = logfile_init(&lm->lm_logfile, lm, store_shmem); if (!succp) { @@ -2299,14 +2233,12 @@ static bool file_is_symlink(char* filename) * @param logfile log file * @param logmanager log manager pointer * @param store_shmem flag to indicate whether log is physically written to shmem - * @param write_syslog flag to indicate whether log is also written to syslog * * @return true if succeed, false otherwise */ static bool logfile_init(logfile_t* logfile, logmanager_t* logmanager, - bool store_shmem, - bool write_syslog) + bool store_shmem) { bool succp = false; fnames_conf_t* fn = &logmanager->lm_fnames_conf; @@ -2325,7 +2257,6 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_rotateflag = false; logfile->lf_spinlock = 0; logfile->lf_store_shmem = store_shmem; - logfile->lf_write_syslog = write_syslog; logfile->lf_buf_size = MAX_LOGSTRLEN; /** * If file is stored in shared memory in /dev/shm, a link diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 2318f7ae8..e273d4a1d 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -153,8 +153,7 @@ int mxs_log_disable_priority(int priority); bool skygw_logmanager_init(const char* ident, const char* logdir, - log_target_t target, - int argc, char* argv[]); + log_target_t target); void skygw_logmanager_done(void); void skygw_logmanager_exit(void); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 152d3b082..fc9c65255 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -77,8 +77,6 @@ int main(int argc, char* argv[]) struct tm tm; char c; int nthr = N_THR; - int log_argc = 0; - char** log_argv = NULL; while ((c = getopt(argc, argv, "t:")) != -1) { @@ -122,7 +120,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Couldn't register exit function.\n"); } - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); if (!succp) { @@ -141,7 +139,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -189,7 +187,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -335,7 +333,7 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); @@ -400,7 +398,7 @@ int main(int argc, char* argv[]) #endif /* TEST 3 */ #if defined(TEST4) - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -436,7 +434,7 @@ int main(int argc, char* argv[]) skygw_logmanager_done(); - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -509,7 +507,7 @@ static void* thr_run(void* data) char* logstr; int err; - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -533,7 +531,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -541,8 +539,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); @@ -556,7 +554,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference " "to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -568,11 +566,11 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); skygw_logmanager_done(); skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..and you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -581,7 +579,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -592,7 +590,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -604,7 +602,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..... and you too?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -613,7 +611,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -629,7 +627,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, four\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -638,7 +636,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -647,7 +645,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS, 0, NULL); + skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); skygw_logmanager_done(); simple_mutex_lock(td->mtx, true); *td->nactive -= 1; diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 3b149ee7b..757cfd5bb 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -31,7 +31,6 @@ int main(int argc, char** argv) char cwd[1024]; char tmp[2048]; char *message; - char** optstr; long msg_index = 1; struct timespec ts1; ts1.tv_sec = 0; @@ -55,7 +54,6 @@ int main(int argc, char** argv) } if (getcwd(cwd, sizeof(cwd)) == NULL || - (optstr = (char**)malloc(sizeof(char*) * 4)) == NULL || (message = (char*)malloc(sizeof(char) * block_size)) == NULL) { fprintf(stderr,"Fatal Error, exiting..."); @@ -65,13 +63,11 @@ int main(int argc, char** argv) memset(tmp, 0, 1024); sprintf(tmp, "%s", cwd); - optstr[0] = strdup("log_manager"); - optstr[1] = NULL; iterations = atoi(argv[1]); interval = atoi(argv[2]); - succp = skygw_logmanager_init(NULL, tmp, LOG_TARGET_FS, 1, optstr); + succp = skygw_logmanager_init(NULL, tmp, LOG_TARGET_FS); if (!succp) { @@ -114,10 +110,5 @@ int main(int argc, char** argv) skygw_log_flush(LOGFILE_ERROR); skygw_logmanager_done(); free(message); - free(optstr[0]); - free(optstr[1]); - free(optstr[2]); - free(optstr[3]); - free(optstr); return 0; } diff --git a/server/core/gateway.c b/server/core/gateway.c index 0ae0e5989..29e6cfaa8 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1089,7 +1089,7 @@ int main(int argc, char **argv) write_footer, NULL}; - *syslog_enabled = 0; + *syslog_enabled = 1; *maxscalelog_enabled = 1; sigemptyset(&sigpipe_mask); @@ -1698,9 +1698,6 @@ int main(int argc, char **argv) /** * Init Log Manager for MaxScale. - * The skygw_logmanager_init expects to take arguments as passed to main - * and proesses them with getopt, therefore we need to give it a dummy - * argv[0] */ { bool succp; @@ -1713,8 +1710,6 @@ int main(int argc, char **argv) goto return_main; } - argv[0] = "MaxScale"; - if (!(*syslog_enabled)) { printf("Syslog logging is disabled.\n"); @@ -1727,10 +1722,7 @@ int main(int argc, char **argv) logmanager_enable_syslog(*syslog_enabled); logmanager_enable_maxscalelog(*maxscalelog_enabled); - char* log_argv[] = { "MaxScale", "-l", "LOGFILE_MESSAGE,LOGFILE_ERROR", NULL }; - int log_argc = sizeof(log_argv) / sizeof(log_argv[0]) - 1; - - succp = skygw_logmanager_init(NULL, get_logdir(), log_target, log_argc, log_argv); + succp = skygw_logmanager_init(NULL, get_logdir(), log_target); if (!succp) { diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 543a5f205..3b74d39af 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -35,10 +35,7 @@ int main(int argc, char **argv) { - int arg_count = 1; - char *home; char *keyfile; - char** arg_vector; int rval = 0; if (argc < 2) @@ -50,18 +47,8 @@ int main(int argc, char **argv) { keyfile = argv[1]; } - arg_vector = malloc(sizeof(char*) * (arg_count + 1)); - if (arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation failed.\n"); - return 1; - } - - arg_vector[0] = "logmanager"; - arg_vector[1] = NULL; - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); - free(arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); if (secrets_writeKeys(keyfile)) { diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 813a9b446..1742b9341 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -42,9 +42,7 @@ main(int argc, char **argv) { char *enc; char *pw; - int arg_count = 1; char *home; - char** arg_vector; int rval = 0; if (argc != 3) @@ -53,18 +51,7 @@ main(int argc, char **argv) return 1; } - arg_vector = malloc(sizeof(char*) * (arg_count + 1)); - - if (arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation failed.\n"); - return 1; - } - - arg_vector[0] = "logmanager"; - arg_vector[1] = NULL; - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); - free(arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); pw = calloc(81, sizeof(char)); diff --git a/server/include/test_utils.h b/server/include/test_utils.h index 199959e5a..f6707e9ca 100644 --- a/server/include/test_utils.h +++ b/server/include/test_utils.h @@ -12,15 +12,7 @@ void init_test_env(char *path) const char* logdir = path ? path : TEST_LOG_DIR; - char* argv[] = - { - "log_manager", - "-l", - "LOGFILE_ERROR", - NULL - }; - - skygw_logmanager_init(NULL, logdir, LOG_TARGET_DEFAULT, argc, argv); + skygw_logmanager_init(NULL, logdir, LOG_TARGET_DEFAULT); poll_init(); hkinit(); } diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index 0e020b571..0dc79909d 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -15,10 +15,9 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ DCB* dcb; char cwd[1024]; char tmp[2048]; - char** optstr; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ - skygw_logmanager_init(NULL,NULL,LOG_TARGET_DEFAULT,0,NULL); + skygw_logmanager_init(NULL,NULL,LOG_TARGET_DEFAULT); } if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) @@ -52,11 +51,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ getcwd(cwd,sizeof(cwd)); sprintf(tmp,"%s",cwd); - optstr = (char**)malloc(sizeof(char*)*2); - optstr[0] = strdup("log_manager"); - optstr[1] = NULL; - skygw_logmanager_init(NULL, tmp, LOG_TARGET_DEFAULT, 1, optstr); - free(optstr); + skygw_logmanager_init(NULL, tmp, LOG_TARGET_DEFAULT); rval = process_opts(argc,argv); diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index a1fcc8ec6..016f43235 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -86,8 +86,6 @@ return 1; } int main(int argc, char **argv) { - char** arg_vector; - int arg_count = 1; ROUTER_INSTANCE *inst; int fd; int ret; @@ -126,22 +124,10 @@ int main(int argc, char **argv) { num_args = optind; - arg_vector = malloc(sizeof(char*)*(arg_count + 1)); - - if(arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation failed for log manager arg_vector.\n"); - return 1; - } - - arg_vector[0] = "logmanager"; - arg_vector[1] = NULL; - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count, arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); skygw_log_set_augmentation(0); - free(arg_vector); - if (!debug_out) skygw_log_disable(LOGFILE_DEBUG); else diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index b21c48253..2cb796ea8 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -73,11 +73,9 @@ static struct option long_options[] = { }; int main(int argc, char **argv) { - char** arg_vector; ROUTER_INSTANCE *inst; int ret; int rc; - int arg_count = 1; char error_string[BINLOG_ERROR_MSG_LEN + 1] = ""; CHANGE_MASTER_OPTIONS change_master; char query[255+1]=""; @@ -91,18 +89,7 @@ int main(int argc, char **argv) { roptions = strdup("server-id=3,heartbeat=200,binlogdir=/not_exists/my_dir,transaction_safety=1,master_version=5.6.99-common,master_hostname=common_server,master_uuid=xxx-fff-cccc-fff,master-id=999"); - arg_vector = malloc(sizeof(char*)*(arg_count + 1)); - - if(arg_vector == NULL) - { - fprintf(stderr,"Error: Memory allocation FAILED for log manager arg_vector.\n"); - return 1; - } - - arg_vector[0] = "logmanager"; - arg_vector[1] = NULL; - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT, arg_count,arg_vector); - free(arg_vector); + skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); skygw_log_disable(LOGFILE_DEBUG); skygw_log_disable(LOGFILE_TRACE); From 42cf1c58d6533a014aca386d93633aa0949049e8 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 18:12:25 +0200 Subject: [PATCH 124/179] No need to handle impossible things. The string given to logmanager_write_log cannot be NULL. The id given to logmanager_write_log cannot be invalid. Consequently we need not handle those possibilities. --- log_manager/log_manager.cc | 294 +++++++++++++++++-------------------- 1 file changed, 138 insertions(+), 156 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index fb63713ae..0c7582b4f 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -627,194 +627,176 @@ static int logmanager_write_log(logfile_id_t id, size_t timestamp_len; int i; + assert(str); + assert(logmanager_is_valid_id(id)); CHK_LOGMANAGER(lm); - if (!logmanager_is_valid_id(id)) - { - err = -1; - ss_dassert(false); - goto return_err; - } // All messages are now logged to the error log file. lf = &lm->lm_logfile; CHK_LOGFILE(lf); + /** Length of string that will be written, limited by bufsize */ + size_t safe_str_len; + /** Length of session id */ + size_t sesid_str_len; + size_t cmplen = 0; /** - * When string pointer is NULL, operation is flush. + * 2 braces, 2 spaces and terminating char + * If session id is stored to tls_log_info structure, allocate + * room for session id too. */ - if (str == NULL) + if (id == LOGFILE_TRACE && tls_log_info.li_sesid != 0) { - if (flush) - { - logfile_flush(lf); /*< wakes up file writer */ - } + sesid_str_len = 5 * sizeof(char) + get_decimal_len(tls_log_info.li_sesid); } else { - /** Length of string that will be written, limited by bufsize */ - size_t safe_str_len; - /** Length of session id */ - size_t sesid_str_len; - size_t cmplen = 0; - /** - * 2 braces, 2 spaces and terminating char - * If session id is stored to tls_log_info structure, allocate - * room for session id too. - */ - if (id == LOGFILE_TRACE && tls_log_info.li_sesid != 0) - { - sesid_str_len = 5 * sizeof(char) + get_decimal_len(tls_log_info.li_sesid); - } - else - { - sesid_str_len = 0; - } - if (log_config.highprec) - { - timestamp_len = get_timestamp_len_hp(); - } - else - { - timestamp_len = get_timestamp_len(); - } - cmplen = sesid_str_len > 0 ? sesid_str_len - sizeof(char) : 0; + sesid_str_len = 0; + } + if (log_config.highprec) + { + timestamp_len = get_timestamp_len_hp(); + } + else + { + timestamp_len = get_timestamp_len(); + } + cmplen = sesid_str_len > 0 ? sesid_str_len - sizeof(char) : 0; - bool overflow = false; - /** Find out how much can be safely written with current block size */ - if (timestamp_len - sizeof(char) + cmplen + str_len > lf->lf_buf_size) - { - safe_str_len = lf->lf_buf_size; - overflow = true; - } - else - { - safe_str_len = timestamp_len - sizeof(char) + cmplen + str_len; - } - /** - * Seek write position and register to block buffer. - * Then print formatted string to write position. - */ + bool overflow = false; + /** Find out how much can be safely written with current block size */ + if (timestamp_len - sizeof(char) + cmplen + str_len > lf->lf_buf_size) + { + safe_str_len = lf->lf_buf_size; + overflow = true; + } + else + { + safe_str_len = timestamp_len - sizeof(char) + cmplen + str_len; + } + /** + * Seek write position and register to block buffer. + * Then print formatted string to write position. + */ #if defined (SS_LOG_DEBUG) + { + char *copy, *tok; + int tokval; + + simple_mutex_lock(&msg_mutex, true); + copy = strdup(str); + tok = strtok(copy, "|"); + tok = strtok(NULL, "|"); + + if (strstr(str, "message|") && tok) { - char *copy, *tok; - int tokval; + tokval = atoi(tok); - simple_mutex_lock(&msg_mutex, true); - copy = strdup(str); - tok = strtok(copy, "|"); - tok = strtok(NULL, "|"); - - if (strstr(str, "message|") && tok) + if (prevval > 0) { - tokval = atoi(tok); - - if (prevval > 0) - { - ss_dassert(tokval == (prevval + 1)); - } - prevval = tokval; + ss_dassert(tokval == (prevval + 1)); } - free(copy); - simple_mutex_unlock(&msg_mutex); + prevval = tokval; } + free(copy); + simple_mutex_unlock(&msg_mutex); + } #endif - /** Book space for log string from buffer */ - if (log_config.do_maxscalelog) - { - // All messages are now logged to the error log file. - wp = blockbuf_get_writepos(&bb, safe_str_len, flush); - } - else - { - wp = (char*)malloc(sizeof(char) * (timestamp_len - sizeof(char) + cmplen + str_len + 1)); - } + /** Book space for log string from buffer */ + if (log_config.do_maxscalelog) + { + // All messages are now logged to the error log file. + wp = blockbuf_get_writepos(&bb, safe_str_len, flush); + } + else + { + wp = (char*)malloc(sizeof(char) * (timestamp_len - sizeof(char) + cmplen + str_len + 1)); + } - if (wp == NULL) - { - return -1; - } + if (wp == NULL) + { + return -1; + } #if defined (SS_LOG_DEBUG) - { - sprintf(wp, "[msg:%d]", atomic_add(&write_index, 1)); - safe_str_len -= strlen(wp); - wp += strlen(wp); - } + { + sprintf(wp, "[msg:%d]", atomic_add(&write_index, 1)); + safe_str_len -= strlen(wp); + wp += strlen(wp); + } #endif + /** + * Write timestamp with at most characters + * to wp. + * Returned timestamp_len doesn't include terminating null. + */ + if (log_config.highprec) + { + timestamp_len = snprint_timestamp_hp(wp, timestamp_len); + } + else + { + timestamp_len = snprint_timestamp(wp, timestamp_len); + } + if (sesid_str_len != 0) + { /** - * Write timestamp with at most characters - * to wp. - * Returned timestamp_len doesn't include terminating null. + * Write session id */ - if (log_config.highprec) - { - timestamp_len = snprint_timestamp_hp(wp, timestamp_len); - } - else - { - timestamp_len = snprint_timestamp(wp, timestamp_len); - } - if (sesid_str_len != 0) - { - /** - * Write session id - */ - snprintf(wp + timestamp_len, sesid_str_len, "[%lu] ", tls_log_info.li_sesid); - sesid_str_len -= 1; /*< don't calculate terminating char anymore */ - } - /** - * Write next string to overwrite terminating null character - * of the timestamp string. - */ - snprintf(wp + timestamp_len + sesid_str_len, - safe_str_len-timestamp_len-sesid_str_len, - "%s", - str); + snprintf(wp + timestamp_len, sesid_str_len, "[%lu] ", tls_log_info.li_sesid); + sesid_str_len -= 1; /*< don't calculate terminating char anymore */ + } + /** + * Write next string to overwrite terminating null character + * of the timestamp string. + */ + snprintf(wp + timestamp_len + sesid_str_len, + safe_str_len-timestamp_len-sesid_str_len, + "%s", + str); - /** Add an ellipsis to an overflowing message to signal truncation. */ - if (overflow && safe_str_len > 4) - { - memset(wp + safe_str_len - 4, '.', 3); - } - /** write to syslog */ - if (log_config.do_syslog) - { - // Strip away the timestamp and the prefix (e.g. "[Error]: "). - const char *message = wp + timestamp_len + prefix_len; + /** Add an ellipsis to an overflowing message to signal truncation. */ + if (overflow && safe_str_len > 4) + { + memset(wp + safe_str_len - 4, '.', 3); + } + /** write to syslog */ + if (log_config.do_syslog) + { + // Strip away the timestamp and the prefix (e.g. "[Error]: "). + const char *message = wp + timestamp_len + prefix_len; - switch (id) - { - case LOGFILE_ERROR: - syslog(LOG_ERR, "%s", message); - break; - - case LOGFILE_MESSAGE: - syslog(LOG_NOTICE, "%s", message); - break; - - default: - break; - } - } - /** remove double line feed */ - if (wp[safe_str_len - 2] == '\n') + switch (id) { - wp[safe_str_len - 2] = ' '; - } - wp[safe_str_len - 1] = '\n'; + case LOGFILE_ERROR: + syslog(LOG_ERR, "%s", message); + break; - if (log_config.do_maxscalelog) - { - blockbuf_unregister(bb); - } - else - { - free(wp); - } - } /* if (str == NULL) */ + case LOGFILE_MESSAGE: + syslog(LOG_NOTICE, "%s", message); + break; + + default: + break; + } + } + /** remove double line feed */ + if (wp[safe_str_len - 2] == '\n') + { + wp[safe_str_len - 2] = ' '; + } + wp[safe_str_len - 1] = '\n'; + + if (log_config.do_maxscalelog) + { + blockbuf_unregister(bb); + } + else + { + free(wp); + } -return_err: return err; } From 001d2df96c1c00517d9fb53b67ae470ce555cd3a Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 22:04:37 +0200 Subject: [PATCH 125/179] Log: Consistency of global variables ensured. The value of global variables that can change copied before being accessed to ensure that the used value is the same for the duration of a function call. No locks are needed, because even if the copying would not be atomic, it doesn't matter since all that matters is that the used value does not change for the duration. --- log_manager/log_manager.cc | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 0c7582b4f..3cac663ad 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -57,10 +57,10 @@ static simple_mutex_t msg_mutex; #endif static struct { - int highprec; - int do_syslog; - int do_maxscalelog; - int use_stdout; + int highprec; // Can change during the lifetime of log_manager. + int do_syslog; // Can change during the lifetime of log_manager. + int do_maxscalelog; // Can change during the lifetime of log_manager. + int use_stdout; // Can NOT changed during the lifetime of log_manager. } log_config = { 0, // highprec @@ -627,6 +627,13 @@ static int logmanager_write_log(logfile_id_t id, size_t timestamp_len; int i; + // The config parameters are copied to local variables, because the values in + // log_config may change during the course of the function, with would have + // unpleasant side-effects. + int highprec = log_config.highprec; + int do_maxscalelog = log_config.do_maxscalelog; + int do_syslog = log_config.do_syslog; + assert(str); assert(logmanager_is_valid_id(id)); CHK_LOGMANAGER(lm); @@ -653,7 +660,7 @@ static int logmanager_write_log(logfile_id_t id, { sesid_str_len = 0; } - if (log_config.highprec) + if (highprec) { timestamp_len = get_timestamp_len_hp(); } @@ -704,7 +711,7 @@ static int logmanager_write_log(logfile_id_t id, } #endif /** Book space for log string from buffer */ - if (log_config.do_maxscalelog) + if (do_maxscalelog) { // All messages are now logged to the error log file. wp = blockbuf_get_writepos(&bb, safe_str_len, flush); @@ -731,7 +738,7 @@ static int logmanager_write_log(logfile_id_t id, * to wp. * Returned timestamp_len doesn't include terminating null. */ - if (log_config.highprec) + if (highprec) { timestamp_len = snprint_timestamp_hp(wp, timestamp_len); } @@ -762,7 +769,7 @@ static int logmanager_write_log(logfile_id_t id, memset(wp + safe_str_len - 4, '.', 3); } /** write to syslog */ - if (log_config.do_syslog) + if (do_syslog) { // Strip away the timestamp and the prefix (e.g. "[Error]: "). const char *message = wp + timestamp_len + prefix_len; @@ -788,7 +795,7 @@ static int logmanager_write_log(logfile_id_t id, } wp[safe_str_len - 1] = '\n'; - if (log_config.do_maxscalelog) + if (do_maxscalelog) { blockbuf_unregister(bb); } @@ -2850,7 +2857,7 @@ void skygw_log_sync_all(void) */ void skygw_set_highp(int val) { - log_config.highprec = val; + log_config.highprec = !!val; } @@ -2860,7 +2867,7 @@ void skygw_set_highp(int val) */ void logmanager_enable_syslog(int val) { - log_config.do_syslog = val; + log_config.do_syslog = !!val; } /** @@ -2869,7 +2876,7 @@ void logmanager_enable_syslog(int val) */ void logmanager_enable_maxscalelog(int val) { - log_config.do_maxscalelog = val; + log_config.do_maxscalelog = !!val; } From b4e9dcd567c0c70d3eb82e061e96fdc2333a6dff Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 22:21:12 +0200 Subject: [PATCH 126/179] Log: succp renamed to succ. --- log_manager/log_manager.cc | 148 ++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 3cac663ad..155fe4385 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -320,14 +320,14 @@ static bool logmanager_init_nomutex(const char* ident, fnames_conf_t* fn; filewriter_t* fw; int err; - bool succp = false; + bool succ = false; lm = (logmanager_t *)calloc(1, sizeof(logmanager_t)); if (lm == NULL) { err = 1; - goto return_succp; + goto return_succ; } lm->lm_target = (target == LOG_TARGET_DEFAULT ? LOG_TARGET_FS : target); @@ -345,7 +345,7 @@ static bool logmanager_init_nomutex(const char* ident, if (lm->lm_clientmes == NULL || lm->lm_logmes == NULL) { err = 1; - goto return_succp; + goto return_succ; } lm->lm_enabled_logfiles |= LOGFILE_ERROR; @@ -364,14 +364,14 @@ static bool logmanager_init_nomutex(const char* ident, if (!fnames_conf_init(fn, logdir)) { err = 1; - goto return_succp; + goto return_succ; } /** Initialize logfiles */ if (!logfiles_init(lm)) { err = 1; - goto return_succp; + goto return_succ; } /** @@ -386,7 +386,7 @@ static bool logmanager_init_nomutex(const char* ident, if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) { err = 1; - goto return_succp; + goto return_succ; } /** Initialize and start filewriter thread */ @@ -395,27 +395,27 @@ static bool logmanager_init_nomutex(const char* ident, if (fw->fwr_thread == NULL) { err = 1; - goto return_succp; + goto return_succ; } if ((err = skygw_thread_start(fw->fwr_thread)) != 0) { - goto return_succp; + goto return_succ; } /** Wait message from filewriter_thr */ skygw_message_wait(fw->fwr_clientmes); - succp = true; + succ = true; lm->lm_enabled = true; -return_succp: +return_succ: if (err != 0) { /** This releases memory of all created objects */ logmanager_done_nomutex(); fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n"); } - return succp; + return succ; } @@ -433,7 +433,7 @@ return_succp: */ bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t target) { - bool succp = false; + bool succ = false; acquire_lock(&lmlock); @@ -441,16 +441,16 @@ bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t t { // TODO: This is not ok. If the parameters are different then // TODO: we pretend something is what it is not. - succp = true; - goto return_succp; + succ = true; + goto return_succ; } - succp = logmanager_init_nomutex(ident, logdir, target); + succ = logmanager_init_nomutex(ident, logdir, target); -return_succp: +return_succ: release_lock(&lmlock); - return succp; + return succ; } /** @@ -874,7 +874,7 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, mlist_node_t* node; blockbuf_t* bb; #if defined(SS_DEBUG) - bool succp; + bool succ; #endif CHK_LOGMANAGER(lm); @@ -958,8 +958,8 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, bb_list->mlist_versno += 1; ss_dassert(bb_list->mlist_versno % 2 == 1); - ss_debug(succp =) mlist_add_data_nomutex(bb_list, bb); - ss_dassert(succp); + ss_debug(succ =) mlist_add_data_nomutex(bb_list, bb); + ss_dassert(succ); /** * Increase version to even to mark completion of update. @@ -1059,8 +1059,8 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, bb_list->mlist_versno += 1; ss_dassert(bb_list->mlist_versno % 2 == 1); - ss_debug(succp =) mlist_add_data_nomutex(bb_list, bb); - ss_dassert(succp); + ss_debug(succ =) mlist_add_data_nomutex(bb_list, bb); + ss_dassert(succ); /** * Increase version to even to mark completion of update. @@ -1583,7 +1583,7 @@ int skygw_log_rotate(logfile_id_t id) */ static bool logmanager_register(bool writep) { - bool succp = true; + bool succ = true; acquire_lock(&lmlock); @@ -1597,8 +1597,8 @@ static bool logmanager_register(bool writep) */ if (!writep || fatal_error) { - succp = false; - goto return_succp; + succ = false; + goto return_succ; } ss_dassert(lm == NULL || (lm != NULL && !lm->lm_enabled)); @@ -1620,23 +1620,23 @@ static bool logmanager_register(bool writep) // If someone is logging before the log manager has been inited, // or after the log manager has been finished, the messages are // written to stdout. - succp = logmanager_init_nomutex(NULL, NULL, LOG_TARGET_DEFAULT); + succ = logmanager_init_nomutex(NULL, NULL, LOG_TARGET_DEFAULT); } } /** if logmanager existed or was succesfully restarted, increase link */ - if (succp) + if (succ) { lm->lm_nlinks += 1; } -return_succp: +return_succ: - if (!succp) + if (!succ) { fatal_error = true; } release_lock(&lmlock); - return succp; + return succ; } /** @@ -1677,7 +1677,7 @@ static void logmanager_unregister(void) */ static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir) { - bool succp = false; + bool succ = false; /** * When init_started is set, clean must be done for it. @@ -1704,12 +1704,12 @@ static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir) if (fn->fn_logpath) { - succp = true; + succ = true; fn->fn_state = RUN; CHK_FNAMES_CONF(fn); } - return succp; + return succ; } @@ -1720,7 +1720,7 @@ static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir) * Parameters: * @param lm Log manager pointer * - * @return succp true if succeed, otherwise false. + * @return true if succeed, otherwise false. * * * @details If logfile is supposed to be located to shared memory @@ -1735,14 +1735,14 @@ static bool logfiles_init(logmanager_t* lm) { bool store_shmem = (lm->lm_target == LOG_TARGET_SHMEM); - bool succp = logfile_init(&lm->lm_logfile, lm, store_shmem); + bool succ = logfile_init(&lm->lm_logfile, lm, store_shmem); - if (!succp) + if (!succ) { fprintf(stderr, "*\n* Error : Initializing log files failed.\n"); } - return succp; + return succ; } static void logfile_flush(logfile_t* lf) @@ -1788,16 +1788,16 @@ static bool logfile_create(logfile_t* lf) bool nameconflicts; bool store_shmem; bool writable; - bool succp; + bool succ; strpart_t spart[3]; /*< string parts of which the file is composed of */ if (log_config.use_stdout) { // TODO: Refactor so that lf_full_file_name can be NULL in this case. lf->lf_full_file_name = strdup("stdout"); - succp = true; + succ = true; // TODO: Refactor to get rid of the gotos. - goto return_succp; + goto return_succ; } /** * sparts is an array but next pointers are used to walk through @@ -1864,8 +1864,8 @@ static bool logfile_create(logfile_t* lf) */ if (!writable) { - succp = false; - goto return_succp; + succ = false; + goto return_succ; } } @@ -1887,8 +1887,8 @@ static bool logfile_create(logfile_t* lf) */ if (!writable) { - succp = false; - goto return_succp; + succ = false; + goto return_succ; } } } @@ -1911,10 +1911,10 @@ static bool logfile_create(logfile_t* lf) } while (namecreatefail || nameconflicts); - succp = true; + succ = true; -return_succp: - return succp; +return_succ: + return succ; } /** @@ -2197,7 +2197,7 @@ static bool check_file_and_path(char* filename, bool* writable, bool do_log) static bool file_is_symlink(char* filename) { int rc; - bool succp = false; + bool succ = false; struct stat b; if (filename != NULL) @@ -2206,10 +2206,10 @@ static bool file_is_symlink(char* filename) if (rc != -1 && S_ISLNK(b.st_mode)) { - succp = true; + succ = true; } } - return succp; + return succ; } @@ -2229,7 +2229,7 @@ static bool logfile_init(logfile_t* logfile, logmanager_t* logmanager, bool store_shmem) { - bool succp = false; + bool succ = false; fnames_conf_t* fn = &logmanager->lm_fnames_conf; logfile->lf_state = INIT; #if defined(SS_DEBUG) @@ -2264,8 +2264,8 @@ static bool logfile_init(logfile_t* logfile, if (c == NULL) { - succp = false; - goto return_with_succp; + succ = false; + goto return_with_succ; } sprintf(c, "%smaxscale.%d", shm_pathname_prefix, pid); logfile->lf_filepath = c; @@ -2273,8 +2273,8 @@ static bool logfile_init(logfile_t* logfile, if (mkdir(c, S_IRWXU | S_IRWXG) != 0 && errno != EEXIST) { - succp = false; - goto return_with_succp; + succ = false; + goto return_with_succ; } logfile->lf_linkpath = strdup(fn->fn_logpath); logfile->lf_linkpath = add_slash(logfile->lf_linkpath); @@ -2285,9 +2285,9 @@ static bool logfile_init(logfile_t* logfile, } logfile->lf_filepath = add_slash(logfile->lf_filepath); - if (!(succp = logfile_create(logfile))) + if (!(succ = logfile_create(logfile))) { - goto return_with_succp; + goto return_with_succ; } /** * Create a block buffer list for log file. Clients' writes go to buffers @@ -2303,7 +2303,7 @@ static bool logfile_init(logfile_t* logfile, "*\n* Error : Initializing buffers for log files " "failed."); logfile_free_memory(logfile); - goto return_with_succp; + goto return_with_succ; } #if defined(SS_DEBUG) @@ -2321,17 +2321,17 @@ static bool logfile_init(logfile_t* logfile, logfile->lf_full_file_name); } #endif - succp = true; + succ = true; logfile->lf_state = RUN; CHK_LOGFILE(logfile); -return_with_succp: - if (!succp) +return_with_succ: + if (!succ) { logfile_done(logfile); } ss_dassert(logfile->lf_state == RUN || logfile->lf_state == DONE); - return succp; + return succ; } /** @@ -2401,7 +2401,7 @@ static bool filewriter_init(logmanager_t* logmanager, skygw_message_t* clientmes, skygw_message_t* logmes) { - bool succp = false; + bool succ = false; logfile_t* lf; CHK_LOGMANAGER(logmanager); @@ -2419,30 +2419,30 @@ static bool filewriter_init(logmanager_t* logmanager, if (fw->fwr_logmes == NULL || fw->fwr_clientmes == NULL) { - goto return_succp; + goto return_succ; } lf = logmanager_get_logfile(logmanager); - if (!(succp = logfile_open_file(fw, lf))) + if (!(succ = logfile_open_file(fw, lf))) { fprintf(stderr, "Error : opening log file %s failed. Exiting " "MaxScale\n", lf->lf_full_file_name); - goto return_succp; + goto return_succ; } fw->fwr_state = RUN; CHK_FILEWRITER(fw); - succp = true; + succ = true; -return_succp: - if (!succp) +return_succ: + if (!succ) { filewriter_done(fw); } ss_dassert(fw->fwr_state == RUN || fw->fwr_state == DONE); - return succp; + return succ; } static void filewriter_done(filewriter_t* fw) @@ -2494,15 +2494,15 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) */ if (rotate_logfile) { - bool succp; + bool succ; lf->lf_name_seqno += 1; /*< new sequence number */ - if (!(succp = logfile_create(lf))) + if (!(succ = logfile_create(lf))) { lf->lf_name_seqno -= 1; /*< restore */ } - else if ((succp = logfile_open_file(fwr, lf))) + else if ((succ = logfile_open_file(fwr, lf))) { if (log_config.use_stdout) { @@ -2514,7 +2514,7 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) } } - if (!succp) + if (!succ) { LOGIF(LE, (skygw_log_write( LOGFILE_ERROR, From b6783c24d049cb97e1b477c0119580d7912b6f90 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 10 Nov 2015 22:55:10 +0200 Subject: [PATCH 127/179] Log: Some gotos removed. --- log_manager/log_manager.cc | 105 ++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 61 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 155fe4385..94be58b40 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -268,10 +268,8 @@ static bool logfile_create(logfile_t* lf); static bool logfile_open_file(filewriter_t* fw, logfile_t* lf); static char* form_full_file_name(strpart_t* parts, logfile_t* lf, int seqnoidx); -static bool filewriter_init(logmanager_t* logmanager, - filewriter_t* fw, - skygw_message_t* clientmes, - skygw_message_t* logmes); +static bool filewriter_init(logmanager_t* logmanager, + filewriter_t* fw); static void filewriter_done(filewriter_t* filewriter); static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir); static void fnames_conf_done(fnames_conf_t* fn); @@ -383,7 +381,7 @@ static bool logmanager_init_nomutex(const char* ident, * Initialize filewriter data and open the log file * for each log file type. */ - if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) + if (!filewriter_init(lm, fw)) { err = 1; goto return_succ; @@ -437,17 +435,17 @@ bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t t acquire_lock(&lmlock); - if (lm != NULL) + if (!lm) + { + succ = logmanager_init_nomutex(ident, logdir, target); + } + else { // TODO: This is not ok. If the parameters are different then // TODO: we pretend something is what it is not. succ = true; - goto return_succ; } - succ = logmanager_init_nomutex(ident, logdir, target); - -return_succ: release_lock(&lmlock); return succ; @@ -515,34 +513,30 @@ void skygw_logmanager_done(void) { acquire_lock(&lmlock); - if (lm == NULL) + if (lm) { - release_lock(&lmlock); - return; - } - CHK_LOGMANAGER(lm); - /** Mark logmanager unavailable */ - lm->lm_enabled = false; + CHK_LOGMANAGER(lm); + /** Mark logmanager unavailable */ + lm->lm_enabled = false; - /** Wait until all users have left or someone shuts down - * logmanager between lock release and acquire. - */ - while (lm != NULL && lm->lm_nlinks != 0) - { - release_lock(&lmlock); - pthread_yield(); - acquire_lock(&lmlock); + /** Wait until all users have left or someone shuts down + * logmanager between lock release and acquire. + */ + while (lm != NULL && lm->lm_nlinks != 0) + { + release_lock(&lmlock); + pthread_yield(); + acquire_lock(&lmlock); + } + + /** Shut down if not already shutted down. */ + if (lm) + { + ss_dassert(lm->lm_nlinks == 0); + logmanager_done_nomutex(); + } } - /** Logmanager was already shut down. Return successfully. */ - if (lm == NULL) - { - goto return_void; - } - ss_dassert(lm->lm_nlinks == 0); - logmanager_done_nomutex(); - -return_void: release_lock(&lmlock); } @@ -2388,23 +2382,19 @@ static void logfile_free_memory(logfile_t* lf) /** * @node Initialize filewriter data and open the log file for each log file type. * - * @param logmanager Log manager struct - * @param fw File writer struct - * @param clientmes Messaging from file writer to log manager - * @param logmes Messaging from loggers to file writer thread + * @param logmanager Log manager struct + * @param fw File writer struct * * @return true if succeed, false if failed * */ -static bool filewriter_init(logmanager_t* logmanager, - filewriter_t* fw, - skygw_message_t* clientmes, - skygw_message_t* logmes) +static bool filewriter_init(logmanager_t* logmanager, filewriter_t* fw) { - bool succ = false; - logfile_t* lf; + bool succ = false; CHK_LOGMANAGER(logmanager); + assert(logmanager->lm_clientmes); + assert(logmanager->lm_logmes); fw->fwr_state = INIT; #if defined(SS_DEBUG) @@ -2413,34 +2403,27 @@ static bool filewriter_init(logmanager_t* logmanager, #endif fw->fwr_logmgr = logmanager; /** Message from filewriter to clients */ - fw->fwr_logmes = logmes; + fw->fwr_logmes = logmanager->lm_logmes; /** Message from clients to filewriter */ - fw->fwr_clientmes = clientmes; + fw->fwr_clientmes = logmanager->lm_clientmes; - if (fw->fwr_logmes == NULL || fw->fwr_clientmes == NULL) + logfile_t* lf = logmanager_get_logfile(logmanager); + + if (logfile_open_file(fw, lf)) { - goto return_succ; + fw->fwr_state = RUN; + CHK_FILEWRITER(fw); + succ = true; } - - lf = logmanager_get_logfile(logmanager); - - if (!(succ = logfile_open_file(fw, lf))) + else { fprintf(stderr, "Error : opening log file %s failed. Exiting " "MaxScale\n", lf->lf_full_file_name); - goto return_succ; - } - fw->fwr_state = RUN; - CHK_FILEWRITER(fw); - succ = true; - -return_succ: - if (!succ) - { filewriter_done(fw); } + ss_dassert(fw->fwr_state == RUN || fw->fwr_state == DONE); return succ; } From 49d4a2019e40218195a0be6b109262ed63864ec5 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 11 Nov 2015 15:43:23 +0000 Subject: [PATCH 128/179] Clarify and fix logic around router capabilities, with particular reference to crash relating to binlog router. --- server/modules/protocol/mysql_client.c | 101 ++++++------------------- 1 file changed, 25 insertions(+), 76 deletions(-) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 3597ceac9..113a10e0f 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -754,87 +754,32 @@ int gw_read_client_event( router_instance = session->service->router_instance; rsession = session->router_session; - if (router_instance != NULL && rsession != NULL) - { - - /** Ask what type of input the router expects */ - cap = router->getCapabilities(router_instance, rsession); - - if (cap == 0 || (cap == RCAP_TYPE_PACKET_INPUT)) - { - stmt_input = false; - } - else if (cap == RCAP_TYPE_STMT_INPUT) - { - stmt_input = true; - /** Mark buffer to as MySQL type */ - gwbuf_set_type(read_buffer, GWBUF_TYPE_MYSQL); - } - - /** - * If router doesn't implement getCapabilities correctly we end - * up here. - */ - else - { - GWBUF* errbuf; - bool succp; - - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_read_client_event] Reading router " - "capabilities failed.", - pthread_self()))); - - errbuf = mysql_create_custom_error( - 1, - 0, - "Read invalid router capabilities. Routing failed. " - "Session will be closed."); - - router->handleError( - router_instance, - rsession, - errbuf, - dcb, - ERRACT_REPLY_CLIENT, - &succp); - gwbuf_free(errbuf); - /** - * If there are not enough backends close - * session - */ - if (!succp) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing the query failed. " - "Session will be closed."))); - } - rc = 1; - while (read_buffer) - { - read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); - } - goto return_rc; - } - } - else - { - /** Send ERR 1045 to client */ - mysql_send_auth_error( + if (NULL == router_instance || NULL == rsession) + { + /** Send ERR 1045 to client */ + mysql_send_auth_error( dcb, 2, 0, "failed to create new session"); - while (read_buffer) - { - read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); - } - return 0; - } + while (read_buffer) + { + read_buffer = gwbuf_consume(read_buffer, GWBUF_LENGTH(read_buffer)); + } + return 0; } + /** Ask what type of input the router expects */ + cap = router->getCapabilities(router_instance, rsession); + + if (cap & RCAP_TYPE_STMT_INPUT) + { + stmt_input = true; + /** Mark buffer to as MySQL type */ + gwbuf_set_type(read_buffer, GWBUF_TYPE_MYSQL); + } + } + if (stmt_input) { /** @@ -1162,12 +1107,16 @@ int gw_read_client_event( read_buffer = NULL; } } - else + else if (NULL != session->router_session || cap & RCAP_TYPE_NO_RSESSION) { /** Feed whole packet to router */ rc = SESSION_ROUTE_QUERY(session, read_buffer); read_buffer = NULL; } + else + { + rc = 0; + } /** Routing succeed */ if (rc) From cd6f7ce046ffe18328068148381224a0c92c8048 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 4 Nov 2015 11:50:21 +0200 Subject: [PATCH 129/179] Fix to MXS-447: https://mariadb.atlassian.net/browse/MXS-447 Monitors are now started after they have been fully configured. --- server/core/config.c | 35 +++++++++++++++++++++++++---------- server/core/monitor.c | 37 +++++++++++++++++++++++++++++++++++++ server/include/maxconfig.h | 1 + server/include/monitor.h | 5 +++++ 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/server/core/config.c b/server/core/config.c index 8e152cd41..a1497adc8 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -343,6 +343,12 @@ int rval, ini_rval; rval = process_config_context(config.next); free_config_context(config.next); + /** Start all monitors */ + if(rval) + { + monitorStartAll(); + } + return rval; } @@ -1156,7 +1162,7 @@ process_config_context(CONFIG_CONTEXT *context) gateway.id = getpid(); } - monitorStart(obj->element,obj->parameters); + monitorAddParameters(obj->element, obj->parameters); /* set monitor interval */ if (interval > 0) @@ -1253,6 +1259,7 @@ process_config_context(CONFIG_CONTEXT *context) obj = obj->next; } /*< while */ + /** TODO: consistency check function */ hashtable_free(monitorhash); @@ -1460,6 +1467,22 @@ return_p2: return p2; } +/** + * Free a configuration parameter + * @param p1 Parameter to free + */ +void free_config_parameter(CONFIG_PARAMETER* p1) +{ + while (p1) + { + free(p1->name); + free(p1->value); + CONFIG_PARAMETER* p2 = p1->next; + free(p1); + p1 = p2; + } +} + /** * Free a config tree * @@ -1474,15 +1497,7 @@ CONFIG_PARAMETER *p1, *p2; while (context) { free(context->object); - p1 = context->parameters; - while (p1) - { - free(p1->name); - free(p1->value); - p2 = p1->next; - free(p1); - p1 = p2; - } + free_config_parameter(context->parameters); obj = context->next; free(context); context = obj; diff --git a/server/core/monitor.c b/server/core/monitor.c index f55b78e0c..fd2852d23 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -118,6 +118,7 @@ MONITOR *ptr; ptr->next = mon->next; } spinlock_release(&monLock); + free_config_parameter(mon->parameters); free(mon->name); free(mon); } @@ -137,6 +138,23 @@ monitorStart(MONITOR *monitor, void* params) spinlock_release(&monitor->lock); } +/** + * Start all monitors + */ +void monitorStartAll() +{ + MONITOR *ptr; + + spinlock_acquire(&monLock); + ptr = allMonitors; + while (ptr) + { + monitorStart(ptr, ptr->parameters); + ptr = ptr->next; + } + spinlock_release(&monLock); +} + /** * Stop a given monitor * @@ -522,3 +540,22 @@ bool check_monitor_permissions(MONITOR* monitor) free(dpasswd); return rval; } + +/** + * Add parameters to the monitor + * @param monitor Monitor + * @param params Config parameters + */ +void monitorAddParameters(MONITOR *monitor, CONFIG_PARAMETER *params) +{ + while (params) + { + CONFIG_PARAMETER* clone = config_clone_param(params); + if (clone) + { + clone->next = monitor->parameters; + monitor->parameters = clone; + } + params = params->next; + } +} diff --git a/server/include/maxconfig.h b/server/include/maxconfig.h index f6fb52596..fc134c6b7 100644 --- a/server/include/maxconfig.h +++ b/server/include/maxconfig.h @@ -120,6 +120,7 @@ extern unsigned int config_pollsleep(); CONFIG_PARAMETER* config_get_param(CONFIG_PARAMETER* params, const char* name); config_param_type_t config_get_paramtype(CONFIG_PARAMETER* param); CONFIG_PARAMETER* config_clone_param(CONFIG_PARAMETER* param); +void free_config_parameter(CONFIG_PARAMETER* p1); extern int config_truth_value(char *); extern double config_percentage_value(char *str); bool config_set_qualified_param( diff --git a/server/include/monitor.h b/server/include/monitor.h index 1841112ca..5c2bb1f69 100644 --- a/server/include/monitor.h +++ b/server/include/monitor.h @@ -21,6 +21,7 @@ #include #include #include +#include /** * @file monitor.h The interface to the monitor module @@ -140,6 +141,7 @@ typedef struct monitor { char* user; /*< Monitor username */ char* password; /*< Monitor password */ SPINLOCK lock; + CONFIG_PARAMETER* parameters; /*< configuration parameters */ MONITOR_SERVERS* databases; /*< List of databases the monitor monitors */ monitor_state_t state; /**< The state of the monitor */ int connect_timeout; /**< Connect timeout in seconds for mysql_real_connect */ @@ -160,9 +162,11 @@ extern void monitor_free(MONITOR *); extern MONITOR *monitor_find(char *); extern void monitorAddServer(MONITOR *, SERVER *); extern void monitorAddUser(MONITOR *, char *, char *); +extern void monitorAddParameters(MONITOR *monitor, CONFIG_PARAMETER *params); extern void monitorStop(MONITOR *); extern void monitorStart(MONITOR *, void*); extern void monitorStopAll(); +extern void monitorStartAll(); extern void monitorShowAll(DCB *); extern void monitorShow(DCB *, MONITOR *); extern void monitorList(DCB *); @@ -170,4 +174,5 @@ extern void monitorSetInterval (MONITOR *, unsigned long); extern void monitorSetNetworkTimeout(MONITOR *, int, int); extern RESULTSET *monitorGetList(); bool check_monitor_permissions(MONITOR* monitor); + #endif From 8363673be639975011f26113572b7c642bf1b5ef Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 7 Nov 2015 18:45:35 +0200 Subject: [PATCH 130/179] Added number of inserted elements to hashtable Added tracking of the number of inserted elements to the hashtable. Also added utility function to get the size of the hashtable. --- server/core/hashtable.c | 18 ++++++++++++++++++ server/include/hashtable.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/server/core/hashtable.c b/server/core/hashtable.c index c43b76916..3a0becd58 100644 --- a/server/core/hashtable.c +++ b/server/core/hashtable.c @@ -148,6 +148,7 @@ hashtable_alloc_real( rval->vfreefn = nullfn; rval->n_readers = 0; rval->writelock = 0; + rval->n_elements = 0; spinlock_init(&rval->spin); if ((rval->entries = (HASHENTRIES **)calloc(rval->hashsize, sizeof(HASHENTRIES *))) == NULL) { @@ -296,6 +297,7 @@ hashtable_add(HASHTABLE *table, void *key, void *value) ptr->next = table->entries[hashkey % table->hashsize]; table->entries[hashkey % table->hashsize] = ptr; } + table->n_elements++; hashtable_write_unlock(table); return 1; @@ -362,6 +364,8 @@ HASHENTRIES *entry, *ptr; table->vfreefn(entry->value); free(entry); } + table->n_elements--; + assert(table->n_elements >= 0); hashtable_write_unlock(table); return 1; } @@ -770,3 +774,17 @@ char buf[40]; close(fd); return rval; } + +/** + * Return the number of elements added to the hashtable + * @param table Hashtable to measure + * @return Number of inserted elements or 0 if table is NULL + */ +int hashtable_size(HASHTABLE *table) +{ + assert(table); + spinlock_acquire(&table->spin); + int rval = table->n_elements; + spinlock_release(&table->spin); + return rval; +} diff --git a/server/include/hashtable.h b/server/include/hashtable.h index 26e44b799..aabcc84b4 100644 --- a/server/include/hashtable.h +++ b/server/include/hashtable.h @@ -85,6 +85,7 @@ typedef struct hashtable { int n_readers; /**< Number of clients reading the table */ int writelock; /**< The table is locked by a writer */ bool ht_isflat; /**< Indicates whether hashtable is in stack or heap */ + int n_elements; /*< Number of added elements */ #if defined(SS_DEBUG) skygw_chk_t ht_chk_tail; #endif @@ -130,4 +131,5 @@ extern HASHITERATOR *hashtable_iterator(HASHTABLE *); extern void *hashtable_next(HASHITERATOR *); /**< Return the key of the hash table iterator */ extern void hashtable_iterator_free(HASHITERATOR *); +extern int hashtable_size(HASHTABLE *table); #endif From c5c416e7fee99aba84f854ba20e2821c47fcd5e4 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 15:17:29 +0200 Subject: [PATCH 131/179] Fixed modification of parameters Monitor parameters were being modified in externcmd_allocate which caused truncation of the arguments to the commands. --- server/core/externcmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/core/externcmd.c b/server/core/externcmd.c index 8e8735ac3..b422529d4 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -6,15 +6,17 @@ * @param argv Array of char pointers to be filled with tokenized arguments * @return 0 on success, -1 on error */ -int tokenize_arguments(char* args, char** argv) +int tokenize_arguments(char* argstr, char** argv) { int i = 0; bool quoted = false; bool read = false; bool escaped = false; char *ptr,*start; + char args[strlen(argstr)]; char qc; + strcpy(args, argstr); start = args; ptr = start; From 264944ff23215ac6b545d313fdab034b6338929e Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 17:10:16 +0200 Subject: [PATCH 132/179] Service users are set to NULL after they are freed. --- server/core/service.c | 5 ++++- server/modules/routing/binlog/blr.c | 2 ++ server/modules/routing/maxinfo/maxinfo.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/server/core/service.c b/server/core/service.c index b77043888..826c61bee 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -348,6 +348,7 @@ GWPROTOCOL *funcs; { users_free(service->users); dcb_close(port->listener); + service->users = NULL; port->listener = NULL; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, @@ -382,8 +383,9 @@ GWPROTOCOL *funcs; service->name))); users_free(service->users); - dcb_close(port->listener); + dcb_close(port->listener); port->listener = NULL; + service->users = NULL; goto retblock; } } @@ -396,6 +398,7 @@ GWPROTOCOL *funcs; port->protocol, service->name))); users_free(service->users); + service->users = NULL; dcb_close(port->listener); port->listener = NULL; } diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index ee55505ad..013e687f7 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -579,6 +579,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; inst->service->name))); if (service->users) { users_free(service->users); + service->users = NULL; } free(inst); @@ -657,6 +658,7 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; if (service->users) { users_free(service->users); + service->users = NULL; } if (service->dbref && service->dbref->server) { diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 0efe22b63..96085a6b4 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -786,7 +786,7 @@ maxinfo_add_mysql_user(SERVICE *service) { "maxinfo: create hex_sha1_sha1_password failed for service user %s", service_user))); users_free(service->users); - + service->users = NULL; return 1; } From 30d1fc66b7dcd7877b2d6b962b22e2aa75d0f1f5 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 17:41:48 +0200 Subject: [PATCH 133/179] getCapabilities no longer takes arguments and returns an int. --- server/core/test/CMakeLists.txt | 2 +- server/include/router.h | 2 +- server/modules/include/readwritesplit.h | 1 - server/modules/include/schemarouter.h | 1 - server/modules/include/shardrouter.h | 1 - server/modules/protocol/mysql_backend.c | 2 +- server/modules/routing/binlog/blr.c | 5 ++-- server/modules/routing/cli.c | 6 ++-- server/modules/routing/debugcli.c | 6 ++-- server/modules/routing/maxinfo/maxinfo.c | 8 ++---- server/modules/routing/readconnroute.c | 8 ++---- .../routing/readwritesplit/readwritesplit.c | 25 +++-------------- .../routing/schemarouter/schemarouter.c | 25 +++-------------- .../routing/schemarouter/shardrouter.c | 28 ++++--------------- server/modules/routing/testroute.c | 6 ++-- 15 files changed, 30 insertions(+), 96 deletions(-) diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 6fc1080d2..149a38f09 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -14,7 +14,7 @@ add_executable(test_users testusers.c) add_executable(test_adminusers testadminusers.c) add_executable(testmemlog testmemlog.c ../random_jkiss.c) add_executable(testfeedback testfeedback.c) -add_executable(testmaxscalepcre2 testmaxscalepcre2.c) +add_executable(testmaxscalepcre2 testmaxscalepcre2.c ../random_jkiss.c) target_link_libraries(test_mysql_users MySQLClient fullcore) target_link_libraries(test_hash fullcore log_manager) target_link_libraries(test_hint fullcore log_manager) diff --git a/server/include/router.h b/server/include/router.h index 5a7152d1b..655075be5 100644 --- a/server/include/router.h +++ b/server/include/router.h @@ -86,7 +86,7 @@ typedef struct router_object { DCB* backend_dcb, error_action_t action, bool* succp); - uint8_t (*getCapabilities)(ROUTER *instance, void* router_session); + int (*getCapabilities)(); } ROUTER_OBJECT; /** diff --git a/server/modules/include/readwritesplit.h b/server/modules/include/readwritesplit.h index 58eb48996..0e229f807 100644 --- a/server/modules/include/readwritesplit.h +++ b/server/modules/include/readwritesplit.h @@ -290,7 +290,6 @@ struct router_client_session { rwsplit_config_t rses_config; /*< copied config info from router instance */ int rses_nbackends; int rses_nsescmd; /*< Number of executed session commands */ - int rses_capabilities; /*< input type, for example */ bool rses_autocommit_enabled; bool rses_transaction_active; bool rses_load_active; /*< If LOAD DATA LOCAL INFILE is diff --git a/server/modules/include/schemarouter.h b/server/modules/include/schemarouter.h index e184e96e3..d4f220903 100644 --- a/server/modules/include/schemarouter.h +++ b/server/modules/include/schemarouter.h @@ -316,7 +316,6 @@ struct router_client_session { backend_ref_t* rses_backend_ref; /*< Pointer to backend reference array */ schemarouter_config_t rses_config; /*< Copied config info from router instance */ int rses_nbackends; /*< Number of backends */ - int rses_capabilities; /*< Input type, for example */ bool rses_autocommit_enabled; /*< Is autocommit enabled */ bool rses_transaction_active; /*< Is a transaction active */ struct router_instance *router; /*< The router instance */ diff --git a/server/modules/include/shardrouter.h b/server/modules/include/shardrouter.h index 3fc70fcc1..f288505c1 100644 --- a/server/modules/include/shardrouter.h +++ b/server/modules/include/shardrouter.h @@ -192,7 +192,6 @@ struct router_client_session { rses_property_t* rses_properties[RSES_PROP_TYPE_COUNT]; shard_config_t rses_config; /*< copied config info from router instance */ - int rses_capabilities; /*< input type, for example */ bool rses_autocommit_enabled; bool rses_transaction_active; struct router_instance *router; /*< The router instance */ diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 29e5be84a..e48c00f98 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -573,7 +573,7 @@ static int gw_read_backend_event(DCB *dcb) { if (dcb->session->state == SESSION_STATE_ROUTER_READY && dcb->session->client != NULL && dcb->session->client->state == DCB_STATE_POLLING && - (session->router_session || router->getCapabilities(router_instance, NULL) & RCAP_TYPE_NO_RSESSION)) + (session->router_session || router->getCapabilities() & RCAP_TYPE_NO_RSESSION)) { client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol); diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 329e60d0c..854ef1f28 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -99,7 +99,7 @@ static void errorReply( error_action_t action, bool *succp); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); static int blr_handler_config(void *userdata, const char *section, const char *name, const char *value); static int blr_handle_config_item(const char *name, const char *value, ROUTER_INSTANCE *inst); static int blr_set_service_mysql_user(SERVICE *service); @@ -113,7 +113,6 @@ extern int blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debu void blr_master_close(ROUTER_INSTANCE *); char * blr_last_event_description(ROUTER_INSTANCE *router); extern int MaxScaleUptime(); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); char *blr_get_event_description(ROUTER_INSTANCE *router, uint8_t event); /** The module object definition */ @@ -1517,7 +1516,7 @@ static void rses_end_locked_router_action(ROUTER_SLAVE * rses) } -static uint8_t getCapabilities(ROUTER *inst, void *router_session) +static int getCapabilities() { return RCAP_TYPE_NO_RSESSION; } diff --git a/server/modules/routing/cli.c b/server/modules/routing/cli.c index 311c15c3f..19bb15cc7 100644 --- a/server/modules/routing/cli.c +++ b/server/modules/routing/cli.c @@ -62,7 +62,7 @@ static void closeSession(ROUTER *instance, void *router_session); static void freeSession(ROUTER *instance, void *router_session); static int execute(ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(ROUTER *instance, DCB *dcb); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); /** The module object definition */ static ROUTER_OBJECT MyObject = { @@ -287,9 +287,7 @@ diagnostics(ROUTER *instance, DCB *dcb) return; /* Nothing to do currently */ } -static uint8_t getCapabilities( - ROUTER* inst, - void* router_session) +static int getCapabilities() { return 0; } diff --git a/server/modules/routing/debugcli.c b/server/modules/routing/debugcli.c index 3467136e6..9f6213809 100644 --- a/server/modules/routing/debugcli.c +++ b/server/modules/routing/debugcli.c @@ -61,7 +61,7 @@ static void closeSession(ROUTER *instance, void *router_session); static void freeSession(ROUTER *instance, void *router_session); static int execute(ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(ROUTER *instance, DCB *dcb); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); /** The module object definition */ static ROUTER_OBJECT MyObject = { @@ -310,9 +310,7 @@ diagnostics(ROUTER *instance, DCB *dcb) return; /* Nothing to do currently */ } -static uint8_t getCapabilities( - ROUTER* inst, - void* router_session) +static int getCapabilities() { return 0; } diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index c4de0743d..04d74ca7c 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -82,7 +82,7 @@ static void closeSession(ROUTER *instance, void *router_session); static void freeSession(ROUTER *instance, void *router_session); static int execute(ROUTER *instance, void *router_session, GWBUF *queue); static void diagnostics(ROUTER *instance, DCB *dcb); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); static void handleError( ROUTER *instance, void *router_session, @@ -415,10 +415,8 @@ diagnostics(ROUTER *instance, DCB *dcb) * * Not used for the maxinfo router */ -static uint8_t -getCapabilities( - ROUTER* inst, - void* router_session) +static int +getCapabilities() { return 0; } diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index 11310a9ec..545cb5423 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -124,7 +124,7 @@ static void handleError( DCB *problem_dcb, error_action_t action, bool *succp); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); /** The module object definition */ @@ -957,11 +957,9 @@ static void rses_end_locked_router_action( } -static uint8_t getCapabilities( - ROUTER* inst, - void* router_session) +static int getCapabilities() { - return 0; + return RCAP_TYPE_PACKET_INPUT; } /******************************** diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 63fa57ad0..086dc4514 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -130,7 +130,7 @@ static bool route_single_stmt( GWBUF* querybuf); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities(); #if defined(NOT_USED) static bool router_option_configured( @@ -912,7 +912,6 @@ 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 */ @@ -4447,27 +4446,11 @@ static void tracelog_routed_query( /** - * Return rc, rc < 0 if router session is closed. rc == 0 if there are no - * capabilities specified, rc > 0 when there are capabilities. + * Return RCAP_TYPE_STMT_INPUT. */ -static uint8_t getCapabilities ( - ROUTER* inst, - void* router_session) +static int getCapabilities () { - ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; - uint8_t rc; - - if (!rses_begin_locked_router_action(rses)) - { - rc = 0xff; - goto return_rc; - } - rc = rses->rses_capabilities; - - rses_end_locked_router_action(rses); - -return_rc: - return rc; + return RCAP_TYPE_STMT_INPUT; } /** diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 59ca01830..3bf85d16c 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -99,7 +99,7 @@ static route_target_t get_shard_route_target ( bool trx_active, HINT* hint); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); static bool connect_backend_servers( backend_ref_t* backend_ref, @@ -1241,7 +1241,6 @@ static void* newSession( goto return_rses; } /** Copy backend pointers to router session. */ - client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT; client_rses->rses_backend_ref = backend_ref; client_rses->rses_nbackends = router_nservers; /*< # of backend servers */ @@ -3934,27 +3933,11 @@ static void tracelog_routed_query( /** - * Return rc, rc < 0 if router session is closed. rc == 0 if there are no - * capabilities specified, rc > 0 when there are capabilities. + * Return RCAP_TYPE_STMT_INPUT. */ -static uint8_t getCapabilities ( - ROUTER* inst, - void* router_session) +static int getCapabilities () { - ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; - uint8_t rc; - - if (!rses_begin_locked_router_action(rses)) - { - rc = 0xff; - goto return_rc; - } - rc = rses->rses_capabilities; - - rses_end_locked_router_action(rses); - -return_rc: - return rc; + return RCAP_TYPE_STMT_INPUT; } /** diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 45020beef..8e7dd479f 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -116,7 +116,7 @@ static route_target_t get_shard_route_target( bool trx_active, HINT* hint); -static uint8_t getCapabilities(ROUTER* inst, void* router_session); +static int getCapabilities(); void subsvc_clear_state(SUBSERVICE* svc,subsvc_state_t state); void subsvc_set_state(SUBSERVICE* svc,subsvc_state_t state); @@ -1158,9 +1158,6 @@ newSession( free(dummy_upstream); } - - /** Copy backend pointers to router session. */ - client_rses->rses_capabilities = RCAP_TYPE_STMT_INPUT; router->stats.n_sessions += 1; /** @@ -2571,27 +2568,12 @@ mysql_sescmd_get_property( } /** - * Return rc, rc < 0 if router session is closed. rc == 0 if there are no - * capabilities specified, rc > 0 when there are capabilities. + * Return RCAP_TYPE_STMT_INPUT */ -static uint8_t -getCapabilities(ROUTER* inst, - void* router_session) +static int +getCapabilities() { - ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *) router_session; - uint8_t rc; - - if(!rses_begin_locked_router_action(rses)) - { - rc = 0xff; - goto return_rc; - } - rc = rses->rses_capabilities; - - rses_end_locked_router_action(rses); - -return_rc: - return rc; + return RCAP_TYPE_STMT_INPUT; } /** diff --git a/server/modules/routing/testroute.c b/server/modules/routing/testroute.c index 968e3892c..b0d963601 100644 --- a/server/modules/routing/testroute.c +++ b/server/modules/routing/testroute.c @@ -35,7 +35,7 @@ static void freeSession(ROUTER *instance, void *session); static int routeQuery(ROUTER *instance, void *session, GWBUF *queue); static void clientReply(ROUTER *instance, void *session, GWBUF *queue,DCB*); static void diagnostic(ROUTER *instance, DCB *dcb); -static uint8_t getCapabilities (ROUTER* inst, void* router_session); +static int getCapabilities (); static void handleError( ROUTER *instance, void *router_session, @@ -166,9 +166,7 @@ diagnostic(ROUTER *instance, DCB *dcb) { } -static uint8_t getCapabilities( - ROUTER* inst, - void* router_session) +static int getCapabilities() { return 0; } From 3ea55e3b507b1c0ba1b3de0f47fb97e4b1730567 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 30 Oct 2015 21:02:14 +0200 Subject: [PATCH 134/179] Fix to MXS-437: https://mariadb.atlassian.net/browse/MXS-437 Maxinfo now allows users to flush logs and change the server status through the MySQL interface. --- .../Tutorials/MaxScale-Information-Schema.md | 2 + server/core/server.c | 30 +++ server/include/server.h | 1 + server/modules/include/maxinfo.h | 8 +- server/modules/routing/maxinfo/maxinfo_exec.c | 253 +++++++++++++++++- .../modules/routing/maxinfo/maxinfo_parse.c | 56 +++- 6 files changed, 347 insertions(+), 3 deletions(-) diff --git a/Documentation/Tutorials/MaxScale-Information-Schema.md b/Documentation/Tutorials/MaxScale-Information-Schema.md index 66bb3ab5b..fcbcd3937 100644 --- a/Documentation/Tutorials/MaxScale-Information-Schema.md +++ b/Documentation/Tutorials/MaxScale-Information-Schema.md @@ -67,6 +67,8 @@ Uptime: 72 Threads: 1 Sessions: 11 The SQL command used to interact with maxinfo is the show command, a variety of show commands are available and will be described in the following sections. +Maxinfo also supports the `FLUSH LOGS`, `SET SERVER ` and `CLEAR SERVER ` commands. These behave the same as their MaxAdmin counterpart. + ## Show variables The show variables command will display a set of name and value pairs for a number of MaxScale system variables. diff --git a/server/core/server.c b/server/core/server.c index 919b5bcbe..7ade3b499 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -907,3 +907,33 @@ server_update_port(SERVER *server, unsigned short port) spinlock_release(&server_spin); } +static struct { + char *str; + unsigned int bit; +} ServerBits[] = { + { "running", SERVER_RUNNING }, + { "master", SERVER_MASTER }, + { "slave", SERVER_SLAVE }, + { "synced", SERVER_JOINED }, + { "ndb", SERVER_NDB }, + { "maintenance", SERVER_MAINT }, + { "maint", SERVER_MAINT }, + { NULL, 0 } +}; + +/** + * Map the server status bit + * + * @param str String representation + * @return bit value or 0 on error + */ +unsigned int +server_map_status(char *str) +{ +int i; + + for (i = 0; ServerBits[i].str; i++) + if (!strcasecmp(str, ServerBits[i].str)) + return ServerBits[i].bit; + return 0; +} diff --git a/server/include/server.h b/server/include/server.h index b3d43c98f..08d2a76ff 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -208,4 +208,5 @@ extern DCB *server_get_persistent(SERVER *, char *, const char *); extern void server_update_address(SERVER *, char *); extern void server_update_port(SERVER *, unsigned short); extern RESULTSET *serverGetList(); +extern unsigned int server_map_status(char *str); #endif diff --git a/server/modules/include/maxinfo.h b/server/modules/include/maxinfo.h index 040433161..f845c3a3d 100644 --- a/server/modules/include/maxinfo.h +++ b/server/modules/include/maxinfo.h @@ -73,7 +73,10 @@ typedef enum MAXOP_LITERAL, MAXOP_PREDICATE, MAXOP_LIKE, - MAXOP_EQUAL + MAXOP_EQUAL, + MAXOP_FLUSH, + MAXOP_SET, + MAXOP_CLEAR } MAXINFO_OPERATOR; /** @@ -109,6 +112,9 @@ typedef struct maxinfo_tree { #define LT_FROM 7 #define LT_STAR 8 #define LT_VARIABLE 9 +#define LT_FLUSH 10 +#define LT_SET 11 +#define LT_CLEAR 12 /** diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index d51f81d0d..3b8e1a2d7 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -54,7 +54,10 @@ static void exec_select(DCB *dcb, MAXINFO_TREE *tree); static void exec_show_variables(DCB *dcb, MAXINFO_TREE *filter); static void exec_show_status(DCB *dcb, MAXINFO_TREE *filter); static int maxinfo_pattern_match(char *pattern, char *str); - +static void exec_flush(DCB *dcb, MAXINFO_TREE *tree); +static void exec_set(DCB *dcb, MAXINFO_TREE *tree); +static void exec_clear(DCB *dcb, MAXINFO_TREE *tree); +void maxinfo_send_ok(DCB *dcb); /** * Execute a parse tree and return the result set or runtime error * @@ -72,6 +75,17 @@ maxinfo_execute(DCB *dcb, MAXINFO_TREE *tree) case MAXOP_SELECT: exec_select(dcb, tree); break; + + case MAXOP_FLUSH: + exec_flush(dcb, tree); + break; + case MAXOP_SET: + exec_set(dcb, tree); + break; + case MAXOP_CLEAR: + exec_clear(dcb, tree); + break; + case MAXOP_TABLE: case MAXOP_COLUMNS: case MAXOP_LITERAL: @@ -274,6 +288,221 @@ char errmsg[120]; LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, errmsg))); } +/** + * Flush all logs to disk and rotate them. + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +void exec_flush_logs(DCB *dcb, MAXINFO_TREE *tree) +{ + skygw_log_rotate(LE); + skygw_log_rotate(LM); + skygw_log_rotate(LT); + skygw_log_rotate(LD); + maxinfo_send_ok(dcb); +} + +/** + * The table of flush commands that are supported + */ +static struct +{ + char *name; + void (*func)(DCB *, MAXINFO_TREE *); +} flush_commands[] = { + { "logs", exec_flush_logs}, + { NULL, NULL} +}; + +/** + * Execute a flush command parse tree and return the result set or runtime error + * + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +static void +exec_flush(DCB *dcb, MAXINFO_TREE *tree) +{ + int i; + char errmsg[120]; + + for (i = 0; flush_commands[i].name; i++) + { + if (strcasecmp(flush_commands[i].name, tree->value) == 0) + { + (*flush_commands[i].func)(dcb, tree->right); + return; + } + } + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Unsupported flush command '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + skygw_log_write(LE, errmsg); +} + +/** + * Set the server status. + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_set_server(DCB *dcb, MAXINFO_TREE *tree) +{ + SERVER* server = server_find_by_unique_name(tree->value); + char errmsg[120]; + + if (server) + { + int status = server_map_status(tree->right->value); + if (status != 0) + { + server_set_status(server, status); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->right->value) > 80) // Prevent buffer overrun + { + tree->right->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->right->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * The table of set commands that are supported + */ +static struct +{ + char *name; + void (*func)(DCB *, MAXINFO_TREE *); +} set_commands[] = { + { "server", exec_set_server}, + { NULL, NULL} +}; + +/** + * Execute a set command parse tree and return the result set or runtime error + * + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +static void +exec_set(DCB *dcb, MAXINFO_TREE *tree) +{ + int i; + char errmsg[120]; + + for (i = 0; set_commands[i].name; i++) + { + if (strcasecmp(set_commands[i].name, tree->value) == 0) + { + (*set_commands[i].func)(dcb, tree->right); + return; + } + } + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Unsupported set command '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + skygw_log_write(LE, errmsg); +} + +/** + * Clear the server status. + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_clear_server(DCB *dcb, MAXINFO_TREE *tree) +{ + SERVER* server = server_find_by_unique_name(tree->value); + char errmsg[120]; + + if (server) + { + int status = server_map_status(tree->right->value); + if (status != 0) + { + server_clear_status(server, status); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->right->value) > 80) // Prevent buffer overrun + { + tree->right->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->right->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * The table of clear commands that are supported + */ +static struct +{ + char *name; + void (*func)(DCB *, MAXINFO_TREE *); +} clear_commands[] = { + { "server", exec_clear_server}, + { NULL, NULL} +}; + +/** + * Execute a clear command parse tree and return the result set or runtime error + * + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +static void +exec_clear(DCB *dcb, MAXINFO_TREE *tree) +{ + int i; + char errmsg[120]; + + for (i = 0; clear_commands[i].name; i++) + { + if (strcasecmp(clear_commands[i].name, tree->value) == 0) + { + (*clear_commands[i].func)(dcb, tree->right); + return; + } + } + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Unsupported clear command '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + skygw_log_write(LE, errmsg); +} + /** * Return the current MaxScale version * @@ -764,3 +993,25 @@ extern char *strcasestr(); return rval; } } + +/** + * Send an OK packet to the client. + * @param dcb The DCB that connects to the client + */ +void maxinfo_send_ok(DCB *dcb) +{ + static const char ok_packet[] ={ + 0x07, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00 + }; + + GWBUF* buffer = gwbuf_alloc(sizeof(ok_packet)); + + if (buffer) + { + memcpy(buffer->start, ok_packet, sizeof(ok_packet)); + dcb->func.write(dcb, buffer); + } +} \ No newline at end of file diff --git a/server/modules/routing/maxinfo/maxinfo_parse.c b/server/modules/routing/maxinfo/maxinfo_parse.c index bdef7ef26..fe5719d3b 100644 --- a/server/modules/routing/maxinfo/maxinfo_parse.c +++ b/server/modules/routing/maxinfo/maxinfo_parse.c @@ -50,7 +50,8 @@ static void free_tree(MAXINFO_TREE *); static char *fetch_token(char *, int *, char **); static MAXINFO_TREE *parse_column_list(char **sql); static MAXINFO_TREE *parse_table_name(char **sql); - +MAXINFO_TREE* maxinfo_parse_literals(MAXINFO_TREE *tree, int min_args, char *ptr, + PARSE_ERROR *parse_error); /** * Parse a SQL subset for the maxinfo plugin and return a parse tree @@ -111,6 +112,23 @@ MAXINFO_TREE *col, *table; table = parse_table_name(&ptr); return make_tree_node(MAXOP_SELECT, NULL, col, table); #endif + case LT_FLUSH: + free(text); // not needed + ptr = fetch_token(ptr, &token, &text); + return make_tree_node(MAXOP_FLUSH, text, NULL, NULL); + + case LT_SET: + free(text); // not needed + ptr = fetch_token(ptr, &token, &text); + tree = make_tree_node(MAXOP_SET, text, NULL, NULL); + return maxinfo_parse_literals(tree, 2, ptr, parse_error); + + case LT_CLEAR: + free(text); // not needed + ptr = fetch_token(ptr, &token, &text); + tree = make_tree_node(MAXOP_CLEAR, text, NULL, NULL); + return maxinfo_parse_literals(tree, 2, ptr, parse_error); + break; default: *parse_error = PARSE_SYNTAX_ERROR; return NULL; @@ -242,6 +260,9 @@ static struct { { "=", LT_EQUAL }, { ",", LT_COMMA }, { "*", LT_STAR }, + { "flush", LT_FLUSH }, + { "set", LT_SET }, + { "clear", LT_CLEAR }, { NULL, 0 } }; @@ -322,3 +343,36 @@ int i; *token = LT_STRING; return s2; } + +/** + * Parse the remaining arguments as literals. + * @param tree Previous head of the parse tree + * @param min_args Minimum required number of arguments + * @param ptr Pointer to client command + * @param parse_error Pointer to parsing error to fill + * @return Parsed tree or NULL if parsing failed + */ +MAXINFO_TREE* maxinfo_parse_literals(MAXINFO_TREE *tree, int min_args, char *ptr, + PARSE_ERROR *parse_error) +{ + int token; + MAXINFO_TREE* node = tree; + char *text; + for(int i = 0; i < min_args; i++) + { + if((ptr = fetch_token(ptr, &token, &text)) == NULL || + (node->right = make_tree_node(MAXOP_LITERAL, text, NULL, NULL)) == NULL) + { + *parse_error = PARSE_SYNTAX_ERROR; + free_tree(tree); + if(ptr) + { + free(text); + } + return NULL; + } + node = node->right; + } + + return tree; +} From 9ab532696030a4eb24a7662571caa038f085d3f5 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 31 Oct 2015 19:07:19 +0200 Subject: [PATCH 135/179] Fix to MXS-438: https://mariadb.atlassian.net/browse/MXS-438 Maxinfo now supports the shutdown command which shuts down a service, monitor or MaxScale itself and the restart command which restarts a stopped monitor or service. --- server/core/server.c | 5 + server/include/server.h | 1 + server/modules/include/maxinfo.h | 6 +- server/modules/routing/debugcmd.c | 34 --- server/modules/routing/maxinfo/maxinfo_exec.c | 238 ++++++++++++++++++ .../modules/routing/maxinfo/maxinfo_parse.c | 75 ++++-- 6 files changed, 310 insertions(+), 49 deletions(-) diff --git a/server/core/server.c b/server/core/server.c index 7ade3b499..11633594c 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -82,6 +82,7 @@ SERVER *server; server->rlag = -2; server->master_id = -1; server->depth = -1; + spinlock_init(&server->lock); server->persistent = NULL; server->persistmax = 0; spinlock_init(&server->persistlock); @@ -663,6 +664,7 @@ char *status = NULL; void server_set_status(SERVER *server, int bit) { + spinlock_acquire(&server->lock); server->status |= bit; /** clear error logged flag before the next failure */ @@ -670,6 +672,7 @@ server_set_status(SERVER *server, int bit) { server->master_err_is_logged = false; } + spinlock_release(&server->lock); } /** @@ -681,7 +684,9 @@ server_set_status(SERVER *server, int bit) void server_clear_status(SERVER *server, int bit) { + spinlock_acquire(&server->lock); server->status &= ~bit; + spinlock_release(&server->lock); } /** diff --git a/server/include/server.h b/server/include/server.h index 08d2a76ff..030e034ba 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -81,6 +81,7 @@ typedef struct server { #if defined(SS_DEBUG) skygw_chk_t server_chk_top; #endif + SPINLOCK lock; /**< Common access lock */ char *unique_name; /**< Unique name for the server */ char *name; /**< Server name/IP address*/ unsigned short port; /**< Port to listen on */ diff --git a/server/modules/include/maxinfo.h b/server/modules/include/maxinfo.h index f845c3a3d..5f7cb6493 100644 --- a/server/modules/include/maxinfo.h +++ b/server/modules/include/maxinfo.h @@ -76,7 +76,9 @@ typedef enum MAXOP_EQUAL, MAXOP_FLUSH, MAXOP_SET, - MAXOP_CLEAR + MAXOP_CLEAR, + MAXOP_SHUTDOWN, + MAXOP_RESTART } MAXINFO_OPERATOR; /** @@ -115,6 +117,8 @@ typedef struct maxinfo_tree { #define LT_FLUSH 10 #define LT_SET 11 #define LT_CLEAR 12 +#define LT_SHUTDOWN 13 +#define LT_RESTART 14 /** diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 73411dc83..414692e76 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -1092,40 +1092,6 @@ restart_service(DCB *dcb, SERVICE *service) serviceRestart(service); } -static struct { - char *str; - unsigned int bit; -} ServerBits[] = { - { "running", SERVER_RUNNING }, - { "master", SERVER_MASTER }, - { "slave", SERVER_SLAVE }, - { "synced", SERVER_JOINED }, - { "ndb", SERVER_NDB }, - { "maintenance", SERVER_MAINT }, - { "maint", SERVER_MAINT }, - { NULL, 0 } -}; -/** - * Map the server status bit - * - * @param str String representation - * @return bit value or 0 on error - */ -static unsigned int -server_map_status(char *str) -{ - int i; - - for (i = 0; ServerBits[i].str; i++) - { - if (!strcasecmp(str, ServerBits[i].str)) - { - return ServerBits[i].bit; - } - } - return 0; -} - /** * Set the status bit of a server * diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index 3b8e1a2d7..3c2b0849d 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -57,6 +57,8 @@ static int maxinfo_pattern_match(char *pattern, char *str); static void exec_flush(DCB *dcb, MAXINFO_TREE *tree); static void exec_set(DCB *dcb, MAXINFO_TREE *tree); static void exec_clear(DCB *dcb, MAXINFO_TREE *tree); +static void exec_shutdown(DCB *dcb, MAXINFO_TREE *tree); +static void exec_restart(DCB *dcb, MAXINFO_TREE *tree); void maxinfo_send_ok(DCB *dcb); /** * Execute a parse tree and return the result set or runtime error @@ -85,6 +87,12 @@ maxinfo_execute(DCB *dcb, MAXINFO_TREE *tree) case MAXOP_CLEAR: exec_clear(dcb, tree); break; + case MAXOP_SHUTDOWN: + exec_shutdown(dcb, tree); + break; + case MAXOP_RESTART: + exec_restart(dcb, tree); + break; case MAXOP_TABLE: case MAXOP_COLUMNS: @@ -503,6 +511,236 @@ exec_clear(DCB *dcb, MAXINFO_TREE *tree) skygw_log_write(LE, errmsg); } +extern void shutdown_server(); + +/** + * MaxScale shutdown + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_shutdown_maxscale(DCB *dcb, MAXINFO_TREE *tree) +{ + shutdown_server(); + maxinfo_send_ok(dcb); +} + +/** + * Stop a monitor + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_shutdown_monitor(DCB *dcb, MAXINFO_TREE *tree) +{ + char errmsg[120]; + if (tree && tree->value) + { + MONITOR* monitor = monitor_find(tree->value); + if (monitor) + { + monitorStop(monitor); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + sprintf(errmsg, "Missing argument for 'SHUTDOWN MONITOR'"); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * Stop a service + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_shutdown_service(DCB *dcb, MAXINFO_TREE *tree) +{ + char errmsg[120]; + if (tree && tree->value) + { + SERVICE* service = service_find(tree->value); + if (service) + { + serviceStop(service); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + sprintf(errmsg, "Missing argument for 'SHUTDOWN SERVICE'"); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * The table of shutdown commands that are supported + */ +static struct +{ + char *name; + void (*func)(DCB *, MAXINFO_TREE *); +} shutdown_commands[] = { + { "maxscale", exec_shutdown_maxscale}, + { "monitor", exec_shutdown_monitor}, + { "service", exec_shutdown_service}, + { NULL, NULL} +}; + +/** + * Execute a shutdown command parse tree and return OK or runtime error + * + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +static void +exec_shutdown(DCB *dcb, MAXINFO_TREE *tree) +{ + int i; + char errmsg[120]; + + for (i = 0; shutdown_commands[i].name; i++) + { + if (strcasecmp(shutdown_commands[i].name, tree->value) == 0) + { + (*shutdown_commands[i].func)(dcb, tree->right); + return; + } + } + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Unsupported shutdown command '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + skygw_log_write(LE, errmsg); +} + +/** + * Restart a monitor + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_restart_monitor(DCB *dcb, MAXINFO_TREE *tree) +{ + char errmsg[120]; + if (tree && tree->value) + { + MONITOR* monitor = monitor_find(tree->value); + if (monitor) + { + monitorStart(monitor, NULL); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + sprintf(errmsg, "Missing argument for 'RESTART MONITOR'"); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * Restart a service + * @param dcb Client DCB + * @param tree Parse tree + */ +void exec_restart_service(DCB *dcb, MAXINFO_TREE *tree) +{ + char errmsg[120]; + if (tree && tree->value) + { + SERVICE* service = service_find(tree->value); + if (service) + { + serviceRestart(service); + maxinfo_send_ok(dcb); + } + else + { + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Invalid argument '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + } + } + else + { + sprintf(errmsg, "Missing argument for 'RESTART SERVICE'"); + maxinfo_send_error(dcb, 0, errmsg); + } +} + +/** + * The table of restart commands that are supported + */ +static struct +{ + char *name; + void (*func)(DCB *, MAXINFO_TREE *); +} restart_commands[] = { + { "monitor", exec_restart_monitor}, + { "service", exec_restart_service}, + { NULL, NULL} +}; + +/** + * Execute a restart command parse tree and return OK or runtime error + * + * @param dcb The DCB that connects to the client + * @param tree The parse tree for the query + */ +static void +exec_restart(DCB *dcb, MAXINFO_TREE *tree) +{ + int i; + char errmsg[120]; + + for (i = 0; restart_commands[i].name; i++) + { + if (strcasecmp(restart_commands[i].name, tree->value) == 0) + { + (*restart_commands[i].func)(dcb, tree->right); + return; + } + } + if (strlen(tree->value) > 80) // Prevent buffer overrun + { + tree->value[80] = 0; + } + sprintf(errmsg, "Unsupported restart command '%s'", tree->value); + maxinfo_send_error(dcb, 0, errmsg); + skygw_log_write(LE, errmsg); +} + /** * Return the current MaxScale version * diff --git a/server/modules/routing/maxinfo/maxinfo_parse.c b/server/modules/routing/maxinfo/maxinfo_parse.c index fe5719d3b..e63d6b2cf 100644 --- a/server/modules/routing/maxinfo/maxinfo_parse.c +++ b/server/modules/routing/maxinfo/maxinfo_parse.c @@ -117,6 +117,50 @@ MAXINFO_TREE *col, *table; ptr = fetch_token(ptr, &token, &text); return make_tree_node(MAXOP_FLUSH, text, NULL, NULL); + case LT_SHUTDOWN: + free(text); + ptr = fetch_token(ptr, &token, &text); + tree = make_tree_node(MAXOP_SHUTDOWN, text, NULL, NULL); + + if ((ptr = fetch_token(ptr, &token, &text)) == NULL) + { + /** Possibly SHUTDOWN MAXSCALE */ + return tree; + } + tree->right = make_tree_node(MAXOP_LITERAL, text, NULL, NULL); + + if ((ptr = fetch_token(ptr, &token, &text)) != NULL) + { + /** Unknown token after SHUTDOWN MONITOR|SERVICE */ + *parse_error = PARSE_SYNTAX_ERROR; + free_tree(tree); + return NULL; + } + return tree; + + case LT_RESTART: + free(text); + ptr = fetch_token(ptr, &token, &text); + tree = make_tree_node(MAXOP_RESTART, text, NULL, NULL); + + if ((ptr = fetch_token(ptr, &token, &text)) == NULL) + { + /** Missing token for RESTART MONITOR|SERVICE */ + *parse_error = PARSE_SYNTAX_ERROR; + free_tree(tree); + return NULL; + } + tree->right = make_tree_node(MAXOP_LITERAL, text, NULL, NULL); + + if ((ptr = fetch_token(ptr, &token, &text)) != NULL) + { + /** Unknown token after RESTART MONITOR|SERVICE */ + *parse_error = PARSE_SYNTAX_ERROR; + free_tree(tree); + return NULL; + } + return tree; + case LT_SET: free(text); // not needed ptr = fetch_token(ptr, &token, &text); @@ -249,21 +293,24 @@ free_tree(MAXINFO_TREE *tree) /** * The set of keywords known to the tokeniser */ -static struct { - char *text; - int token; +static struct +{ + char *text; + int token; } keywords[] = { - { "show", LT_SHOW }, - { "select", LT_SELECT }, - { "from", LT_FROM }, - { "like", LT_LIKE }, - { "=", LT_EQUAL }, - { ",", LT_COMMA }, - { "*", LT_STAR }, - { "flush", LT_FLUSH }, - { "set", LT_SET }, - { "clear", LT_CLEAR }, - { NULL, 0 } + { "show", LT_SHOW}, + { "select", LT_SELECT}, + { "from", LT_FROM}, + { "like", LT_LIKE}, + { "=", LT_EQUAL}, + { ",", LT_COMMA}, + { "*", LT_STAR}, + { "flush", LT_FLUSH}, + { "set", LT_SET}, + { "clear", LT_CLEAR}, + { "shutdown", LT_SHUTDOWN}, + { "restart", LT_RESTART}, + { NULL, 0} }; /** From d56843835c8ea06438cc7f60f56d5d13b2cc6c12 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 16:00:00 +0200 Subject: [PATCH 136/179] Cleaned up externcmd_allocate and externcmd_free --- server/core/externcmd.c | 69 +++++++++++++++++++------------------- server/include/externcmd.h | 3 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/server/core/externcmd.c b/server/core/externcmd.c index b422529d4..820821e3c 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -82,36 +82,33 @@ int tokenize_arguments(char* argstr, char** argv) */ EXTERNCMD* externcmd_allocate(char* argstr) { - EXTERNCMD* cmd; + EXTERNCMD* cmd = NULL; - if(argstr == NULL) - return NULL; - - if((cmd = (EXTERNCMD*)malloc(sizeof(EXTERNCMD))) != NULL) + if (argstr && (cmd = (EXTERNCMD*) malloc(sizeof(EXTERNCMD))) && + (cmd->argv = malloc(sizeof(char*) * MAXSCALE_EXTCMD_ARG_MAX))) { - if(tokenize_arguments(argstr,cmd->parameters) == -1) - { - free(cmd); - return NULL; - } - if(access(cmd->parameters[0],F_OK) != 0) - { - skygw_log_write(LE, - "Error: Cannot find file: %s", - cmd->parameters[0]); - externcmd_free(cmd); - return NULL; - } - - if(access(cmd->parameters[0],X_OK) != 0) - { - skygw_log_write(LE, - "Error: Cannot execute file '%s'. Missing execution permissions.", - cmd->parameters[0]); - externcmd_free(cmd); - return NULL; - } - skygw_log_write(LT, "Executing script %s.", cmd->parameters[0]); + if (tokenize_arguments(argstr, cmd->argv) == 0) + { + if (access(cmd->argv[0], X_OK) != 0) + { + if (access(cmd->argv[0], F_OK) != 0) + { + skygw_log_write(LE, "Error: Cannot find file: %s", cmd->argv[0]); + } + else + { + skygw_log_write(LE, "Error: Cannot execute file '%s'. Missing " + "execution permissions.", cmd->argv[0]); + } + externcmd_free(cmd); + cmd = NULL; + } + } + else + { + externcmd_free(cmd); + cmd = NULL; + } } return cmd; } @@ -122,13 +119,15 @@ EXTERNCMD* externcmd_allocate(char* argstr) */ void externcmd_free(EXTERNCMD* cmd) { - int i; - - for(i = 0;cmd->parameters[i] != NULL;i++) + if (cmd) { - free(cmd->parameters[i]); + for (int i = 0; cmd->argv[i]; i++) + { + free(cmd->argv[i]); + } + free(cmd->argv); + free(cmd); } - free(cmd); } /** @@ -147,13 +146,13 @@ int externcmd_execute(EXTERNCMD* cmd) { char errbuf[STRERROR_BUFLEN]; skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s', fork failed: [%d] %s", - cmd->parameters[0],errno,strerror_r(errno, errbuf, sizeof(errbuf))); + cmd->argv[0],errno,strerror_r(errno, errbuf, sizeof(errbuf))); rval = -1; } else if(pid == 0) { /** Child process, execute command */ - execvp(cmd->parameters[0],cmd->parameters); + execvp(cmd->argv[0],cmd->argv); _exit(1); } else diff --git a/server/include/externcmd.h b/server/include/externcmd.h index 1ab44f908..e1214c178 100644 --- a/server/include/externcmd.h +++ b/server/include/externcmd.h @@ -9,7 +9,8 @@ #define MAXSCALE_EXTCMD_ARG_MAX 256 typedef struct extern_cmd_t{ - char* parameters[MAXSCALE_EXTCMD_ARG_MAX]; /*< Command arguments */ + char** argv; /*< Argument vector for the command, first being the actual command + * being executed. */ int n_exec; /*< Number of times executed */ pid_t child; /*< PID of the child process */ }EXTERNCMD; From 466224b316f2a06ebee2cfeb7760a4f841f22fe4 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 16:07:52 +0200 Subject: [PATCH 137/179] Moved common monitor code to externcmd.c File existence and permission checks are now done in externcmd_can_execute --- server/core/externcmd.c | 81 +++++++++++++++++++++++--- server/include/externcmd.h | 1 + server/modules/monitor/galeramon.c | 35 +++-------- server/modules/monitor/mmmon.c | 34 +++-------- server/modules/monitor/mysql_mon.c | 38 ++++-------- server/modules/monitor/ndbclustermon.c | 32 +++------- 6 files changed, 113 insertions(+), 108 deletions(-) diff --git a/server/core/externcmd.c b/server/core/externcmd.c index 820821e3c..c8bf92a8f 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -93,11 +93,11 @@ EXTERNCMD* externcmd_allocate(char* argstr) { if (access(cmd->argv[0], F_OK) != 0) { - skygw_log_write(LE, "Error: Cannot find file: %s", cmd->argv[0]); + skygw_log_write(LE, "Cannot find file: %s", cmd->argv[0]); } else { - skygw_log_write(LE, "Error: Cannot execute file '%s'. Missing " + skygw_log_write(LE, "Cannot execute file '%s'. Missing " "execution permissions.", cmd->argv[0]); } externcmd_free(cmd); @@ -145,23 +145,88 @@ int externcmd_execute(EXTERNCMD* cmd) if(pid < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LOGFILE_ERROR,"Error: Failed to execute command '%s', fork failed: [%d] %s", - cmd->argv[0],errno,strerror_r(errno, errbuf, sizeof(errbuf))); + skygw_log_write(LOGFILE_ERROR, "Failed to execute command '%s', fork failed: [%d] %s", + cmd->argv[0], errno, strerror_r(errno, errbuf, sizeof(errbuf))); rval = -1; } else if(pid == 0) { /** Child process, execute command */ execvp(cmd->argv[0],cmd->argv); - _exit(1); + _exit(1); } else { - cmd->child = pid; - cmd->n_exec++; - LOGIF(LD,skygw_log_write(LD,"[monitor_exec_cmd] Forked child process %d : %s.",pid,cmd)); + cmd->child = pid; + cmd->n_exec++; + LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd)); + } + return rval; +} + +/** + * Get the name of the command being executed. + * + * This copies the command being executed into a new string. + * @param str Command string, optionally with arguments + * @return Command part of the string if arguments were defined + */ +char* get_command(const char* str) +{ + char* rval = NULL; + const char* start = str; + + while (*start && isspace(*start)) + { + start++; + } + + const char* end = start; + + while (*end && !isspace(*end)) + { + end++; + } + + size_t len = end - start; + + if (len > 0 && (rval = malloc(len + 1))) + { + memcpy(rval, start, len); + rval[len] = '\0'; } return rval; } +/** + * Check if a command can be executed. + * + * Checks if the file being executed exists and if the current user has execution + * permissions on the file. + * @param argstr Command to check. Can contain arguments for the command. + * @return True if the file was found and the use has execution permissions to it. + */ +bool externcmd_can_execute(const char* argstr) +{ + bool rval = false; + char *command = get_command(argstr); + + if (command) + { + if (access(command, X_OK) == 0) + { + rval = true; + } + else if (access(command, F_OK) == 0) + { + skygw_log_write(LE, "The executable cannot be executed: %s", command); + } + else + { + skygw_log_write(LE, "The executable cannot be found: %s", command); + } + free(command); + } + return rval; +} diff --git a/server/include/externcmd.h b/server/include/externcmd.h index e1214c178..ab74e8ff7 100644 --- a/server/include/externcmd.h +++ b/server/include/externcmd.h @@ -18,4 +18,5 @@ typedef struct extern_cmd_t{ EXTERNCMD* externcmd_allocate(char* argstr); void externcmd_free(EXTERNCMD* cmd); int externcmd_execute(EXTERNCMD* cmd); +bool externcmd_can_execute(char* argstr); #endif diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 4b78f30e2..4df951430 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -152,32 +152,15 @@ startMonitor(void *arg,void* opt) handle->use_priority = config_truth_value(params->value); else if(!strcmp(params->name,"script")) { - if(handle->script) - { - free(handle->script); - handle->script = NULL; - } - - if(access(params->value,X_OK) == 0) - { - handle->script = strdup(params->value); - } - else - { - script_error = true; - if(access(params->value,F_OK) == 0) - { - skygw_log_write(LE, - "Error: The file cannot be executed: %s", - params->value); - } - else - { - skygw_log_write(LE, - "Error: The file cannot be found: %s", - params->value); - } - } + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } } else if(!strcmp(params->name,"events")) { diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 9abccf153..7718f1435 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -135,31 +135,15 @@ startMonitor(void *arg,void* opt) } else if(!strcmp(params->name,"script")) { - if(handle->script) - { - free(handle->script); - } - if(access(params->value,X_OK) == 0) - { - handle->script = strdup(params->value); - } - else - { - script_error = true; - if(access(params->value,F_OK) == 0) - { - skygw_log_write(LE, - "Error: The file cannot be executed: %s", - params->value); - } - else - { - skygw_log_write(LE, - "Error: The file cannot be found: %s", - params->value); - } - handle->script = NULL; - } + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } } else if(!strcmp(params->name,"events")) { diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 6a817c505..c45c7604f 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -166,32 +166,18 @@ startMonitor(void *arg, void* opt) handle->detectStaleMaster = config_truth_value(params->value); else if(!strcmp(params->name,"detect_replication_lag")) handle->replicationHeartbeat = config_truth_value(params->value); - else if(!strcmp(params->name,"script")) - { - if(handle->script) - free(handle->script); - if(access(params->value,X_OK) == 0) - { - handle->script = strdup(params->value); - } - else - { - script_error = true; - if(access(params->value,F_OK) == 0) - { - skygw_log_write(LE, - "Error: The file cannot be executed: %s", - params->value); - } - else - { - skygw_log_write(LE, - "Error: The file cannot be found: %s", - params->value); - } - handle->script = NULL; - } - } + else if (!strcmp(params->name, "script")) + { + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } + } else if(!strcmp(params->name,"events")) { if(mon_parse_event_string((bool*)&handle->events,sizeof(handle->events),params->value) != 0) diff --git a/server/modules/monitor/ndbclustermon.c b/server/modules/monitor/ndbclustermon.c index 02883c925..aabccf60c 100644 --- a/server/modules/monitor/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon.c @@ -127,29 +127,15 @@ startMonitor(void *arg,void* opt) { if(!strcmp(params->name,"script")) { - if(handle->script) - free(handle->script); - if(access(params->value,X_OK) == 0) - { - handle->script = strdup(params->value); - } - else - { - script_error = true; - if(access(params->value,F_OK) == 0) - { - skygw_log_write(LE, - "Error: The file cannot be executed: %s", - params->value); - } - else - { - skygw_log_write(LE, - "Error: The file cannot be found: %s", - params->value); - } - handle->script = NULL; - } + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } } else if(!strcmp(params->name,"events")) { From 2d600868f5ee5d7537d80ce007e6ee6663e38fc9 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 16:52:24 +0200 Subject: [PATCH 138/179] Added argument substitution to monitor scripts --- Documentation/Monitors/Galera-Monitor.md | 41 ++----------- Documentation/Monitors/MM-Monitor.md | 38 +----------- Documentation/Monitors/Monitor-Common.md | 55 +++++++++++++++++ Documentation/Monitors/MySQL-Monitor.md | 39 +----------- Documentation/Monitors/NDB-Cluster-Monitor.md | 47 +-------------- server/core/externcmd.c | 56 ++++++++++++++++-- server/core/server.c | 2 +- server/include/externcmd.h | 6 +- server/include/server.h | 2 + server/modules/monitor/monitor_common.c | 59 +++++++++++-------- 10 files changed, 161 insertions(+), 184 deletions(-) create mode 100644 Documentation/Monitors/Monitor-Common.md diff --git a/Documentation/Monitors/Galera-Monitor.md b/Documentation/Monitors/Galera-Monitor.md index 4f0fc47c1..e91373297 100644 --- a/Documentation/Monitors/Galera-Monitor.md +++ b/Documentation/Monitors/Galera-Monitor.md @@ -81,22 +81,6 @@ This disables the assignment of master and slave roles to the Galera cluster nod ``` disable_master_role_setting=true ``` - -### `script` - -This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in. - -``` -script=/home/user/script.sh -``` - -### `events` - -A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names. - -``` -events=master_down,slave_down -``` ### `use_priority` @@ -106,6 +90,10 @@ Enable interaction with server priorities. This will allow the monitor to determ use_priority=true ``` +### Common Monitor Parameters + +For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document. + ## Interaction with Server Priorities If the `use_priority` option is set and a server is configured with the `priority=` parameter, galeramon will use that as the basis on which the master node is chosen. This requires the `disable_master_role_setting` to be undefined or disabled. The server with the lowest value in `priority` will be chosen as the master node when a replacement Galera node is promoted to a master server inside MaxScale. @@ -135,24 +123,3 @@ priority=2 In this example `node-1` is always used as the master if available. If `node-1` is not available, then the next node with the highest priority rank is used. In this case it would be `node-3`. If both `node-1` and `node-3` were down, then `node-2` would be used. Nodes without priority are considered as having the lowest priority rank and will be used only if all nodes with priority ranks are not available. With priority ranks you can control the order in which MaxScale chooses the master node. This will allow for a controlled failure and replacement of nodes. - -## Script events - -Here is a table of all possible event types and their descriptions. - -Event Name|Description -----------|---------- -master_down|A Master server has gone down -master_up|A Master server has come up -slave_down|A Slave server has gone down -slave_up|A Slave server has come up -server_down|A server with no assigned role has gone down -server_up|A server with no assigned role has come up -synced_down|A synced Galera node has come up -synced_up|A synced Galera node has gone down -lost_master|A server lost Master status -lost_slave|A server lost Slave status -lost_synced|A Galera node lost synced status -new_master|A new Master was detected -new_slave|A new Slave was detected -new_synced|A new synced Galera node was detected diff --git a/Documentation/Monitors/MM-Monitor.md b/Documentation/Monitors/MM-Monitor.md index c2bd5a566..a90d2bf71 100644 --- a/Documentation/Monitors/MM-Monitor.md +++ b/Documentation/Monitors/MM-Monitor.md @@ -67,41 +67,7 @@ This is a situation which can happen if all slave servers are unreachable or the ``` detect_stale_master=true ``` - -### `script` -This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in. +### Common Monitor Parameters -``` -script=/home/user/script.sh -``` - -This script will be called with the following command line arguments. - -``` - --event= --initiator= --nodelist= -``` -### `events` - -A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names. - -``` -events=master_down,slave_down -``` - -## Script events - -Here is a table of all possible event types and their descriptions. - -Event Name|Description -----------|---------- -master_down|A Master server has gone down -master_up|A Master server has come up -slave_down|A Slave server has gone down -slave_up|A Slave server has come up -server_down|A server with no assigned role has gone down -server_up|A server with no assigned role has come up -lost_master|A server lost Master status -lost_slave|A server lost Slave status -new_master|A new Master was detected -new_slave|A new Slave was detected +For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document. diff --git a/Documentation/Monitors/Monitor-Common.md b/Documentation/Monitors/Monitor-Common.md new file mode 100644 index 000000000..1d27dc419 --- /dev/null +++ b/Documentation/Monitors/Monitor-Common.md @@ -0,0 +1,55 @@ +# Common Monitor Parameters + +This document lists optional parameters that all current monitors support. + +## Parameters + +### `script` + +This command will be executed when a server changes its state. The parameter should be an absolute path to a command or the command should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in. + +``` +script=/home/user/myscript.sh initiator=$INITIATOR event=$EVENT live_nodes=$NODELIST +``` + +The following substitutions will be made to the parameter value: + +* `$INITIATOR` will be replaced with the IP and port of the server who initiated the event +* `$EVENT` will be replaced with the name of the event +* `$NODELIST` will be replaced with a list of server IPs and ports that are running + +For example, the previous example will be executed as: + +``` +/home/user/myscript.sh initiator=192.168.0.10:3306 event=master_down live_nodes=192.168.0.201:3306,192.168.0.121:3306 +``` + +### `events` + +A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names. + +``` +events=master_down,slave_down +``` + +## Script events + +Here is a table of all possible event types and their descriptions that the monitors can be called with. + +Event Name|Description +----------|---------- +master_down|A Master server has gone down +master_up|A Master server has come up +slave_down|A Slave server has gone down +slave_up|A Slave server has come up +server_down|A server with no assigned role has gone down +server_up|A server with no assigned role has come up +ndb_down|A MySQL Cluster node has gone down +ndb_up|A MySQL Cluster node has come up +lost_master|A server lost Master status +lost_slave|A server lost Slave status +lost_ndb|A MySQL Cluster node lost node membership +new_master|A new Master was detected +new_slave|A new Slave was detected +new_ndb|A new MySQL Cluster node was found + diff --git a/Documentation/Monitors/MySQL-Monitor.md b/Documentation/Monitors/MySQL-Monitor.md index d56082021..f32af7fde 100644 --- a/Documentation/Monitors/MySQL-Monitor.md +++ b/Documentation/Monitors/MySQL-Monitor.md @@ -83,27 +83,6 @@ This is a situation which can happen if all slave servers are unreachable or the ``` detect_stale_master=true ``` - -### `script` - -This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in. - -``` -script=/home/user/script.sh -``` - -This script will be called with the following command line arguments. - -``` - --event= --initiator= --nodelist= -``` -### `events` - -A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names. - -``` -events=master_down,slave_down -``` ### `mysql51_replication` @@ -113,23 +92,9 @@ Enable support for MySQL 5.1 replication monitoring. This is needed if a MySQL s mysql51_replication=true ``` -## Script events - -Here is a table of all possible event types and their descriptions. - -Event Name|Description -----------|---------- -master_down|A Master server has gone down -master_up|A Master server has come up -slave_down|A Slave server has gone down -slave_up|A Slave server has come up -server_down|A server with no assigned role has gone down -server_up|A server with no assigned role has come up -lost_master|A server lost Master status -lost_slave|A server lost Slave status -new_master|A new Master was detected -new_slave|A new Slave was detected +### Common Monitor Parameters +For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document. ## Example 1 - Monitor script diff --git a/Documentation/Monitors/NDB-Cluster-Monitor.md b/Documentation/Monitors/NDB-Cluster-Monitor.md index a87ff35a8..806c7858f 100644 --- a/Documentation/Monitors/NDB-Cluster-Monitor.md +++ b/Documentation/Monitors/NDB-Cluster-Monitor.md @@ -54,49 +54,6 @@ This parameter controls the timeout for reading from a monitored server. It is i backend_read_timeout=2 ``` -## MySQL Cluster Monitor optional parameters - -These are optional parameters specific to the MySQL Cluster Monitor. - -### `script` - -This script will be executed when a server changes its state. The parameter should be an absolute path to the script or it should be in the executable path. The user which is used to run MaxScale should have execution rights to the file itself and the directory it resides in. - -``` -script=/home/user/script.sh -``` - -This script will be called with the following command line arguments. - -``` - --event= --initiator= --nodelist= -``` -### `events` - -A list of event names which cause the script to be executed. If this option is not defined, all events cause the script to be executed. The list must contain a comma separated list of event names. - -``` -events=master_down,slave_down -``` - -## Script events - -Here is a table of all possible event types and their descriptions that the MySQL Cluster monitor can be called with. - -Event Name|Description -----------|---------- -master_down|A Master server has gone down -master_up|A Master server has come up -slave_down|A Slave server has gone down -slave_up|A Slave server has come up -server_down|A server with no assigned role has gone down -server_up|A server with no assigned role has come up -ndb_down|A MySQL Cluster node has gone down -ndb_up|A MySQL Cluster node has come up -lost_master|A server lost Master status -lost_slave|A server lost Slave status -lost_ndb|A MySQL Cluster node lost node membership -new_master|A new Master was detected -new_slave|A new Slave was detected -new_ndb|A new MySQL Cluster node was found +### Common Monitor Parameters +For a list of optional parameters that all monitors support, read the [Monitor Common](Monitor-Common.md) document. diff --git a/server/core/externcmd.c b/server/core/externcmd.c index c8bf92a8f..413854ba9 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -139,20 +139,20 @@ int externcmd_execute(EXTERNCMD* cmd) { int rval = 0; pid_t pid; - + pid = fork(); - if(pid < 0) + if (pid < 0) { char errbuf[STRERROR_BUFLEN]; skygw_log_write(LOGFILE_ERROR, "Failed to execute command '%s', fork failed: [%d] %s", cmd->argv[0], errno, strerror_r(errno, errbuf, sizeof(errbuf))); rval = -1; } - else if(pid == 0) + else if (pid == 0) { /** Child process, execute command */ - execvp(cmd->argv[0],cmd->argv); + execvp(cmd->argv[0], cmd->argv); _exit(1); } else @@ -161,6 +161,54 @@ int externcmd_execute(EXTERNCMD* cmd) cmd->n_exec++; LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd)); } + + return rval; +} + +/** + * Substitute all occurrences of @c match with @c replace in the arguments for @c cmd. + * @param cmd External command + * @param match Match string + * @param replace Replacement string + * @return true if replacement was successful, false on error + */ +bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* match, const char* replace) +{ + int err; + bool rval = true; + size_t errpos; + pcre2_code *re = pcre2_compile((PCRE2_SPTR) match, PCRE2_ZERO_TERMINATED, 0, &err, &errpos, NULL); + if (re) + { + for (int i = 0; cmd->argv[i] && rval; i++) + { + size_t size = strlen(cmd->argv[i]); + char* dest = malloc(size); + if (dest) + { + mxs_pcre2_result_t rc = mxs_pcre2_substitute(re, cmd->argv[i], replace, &dest, &size); + switch (rc) + { + case MXS_PCRE2_ERROR: + free(dest); + rval = false; + break; + case MXS_PCRE2_MATCH: + free(cmd->argv[i]); + cmd->argv[i] = dest; + break; + case MXS_PCRE2_NOMATCH: + free(dest); + break; + } + } + } + } + else + { + rval = false; + LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd)); + } return rval; } diff --git a/server/core/server.c b/server/core/server.c index 11633594c..063ed6452 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -74,7 +74,7 @@ SERVER *server; server->server_chk_top = CHK_NUM_SERVER; server->server_chk_tail = CHK_NUM_SERVER; #endif - server->name = strdup(servname); + server->name = strndup(servname, MAX_SERVER_NAME_LEN); server->protocol = strdup(protocol); server->port = port; server->status = SERVER_RUNNING; diff --git a/server/include/externcmd.h b/server/include/externcmd.h index ab74e8ff7..3e50d99a8 100644 --- a/server/include/externcmd.h +++ b/server/include/externcmd.h @@ -6,6 +6,8 @@ #include #include #include +#include + #define MAXSCALE_EXTCMD_ARG_MAX 256 typedef struct extern_cmd_t{ @@ -15,8 +17,10 @@ typedef struct extern_cmd_t{ pid_t child; /*< PID of the child process */ }EXTERNCMD; +char* externcmd_extract_command(const char* argstr); EXTERNCMD* externcmd_allocate(char* argstr); void externcmd_free(EXTERNCMD* cmd); int externcmd_execute(EXTERNCMD* cmd); -bool externcmd_can_execute(char* argstr); +bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* re, const char* replace); +bool externcmd_can_execute(const char* argstr); #endif diff --git a/server/include/server.h b/server/include/server.h index 030e034ba..263522959 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -49,6 +49,8 @@ * @endverbatim */ +#define MAX_SERVER_NAME_LEN 1024 + /** * The server parameters used for weighting routing decissions * diff --git a/server/modules/monitor/monitor_common.c b/server/modules/monitor/monitor_common.c index c5db84fa7..c3180d188 100644 --- a/server/modules/monitor/monitor_common.c +++ b/server/modules/monitor/monitor_common.c @@ -17,6 +17,7 @@ */ #include +#include monitor_event_t mon_name_to_event(char* tok); @@ -225,23 +226,32 @@ case NEW_DONOR_EVENT: } -void mon_append_node_names(MONITOR_SERVERS* start,char* str, int len) +/** + * Create a list of running servers + * @param start Monitored servers + * @param dest Destination where the string is formed + * @param len Length of @c dest + */ +void mon_append_node_names(MONITOR_SERVERS* start, char* dest, int len) { MONITOR_SERVERS* ptr = start; bool first = true; - int slen = strlen(str); - char arr[256]; - while(ptr && slen < len) + int slen = strlen(dest); + char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port + while (ptr && slen < len) { - if(!first) - { - strncat(str,",",len); - } - first = false; - sprintf(arr,"%s:%d",ptr->server->name,ptr->server->port); - strncat(str,arr,len); - ptr = ptr->next; - slen = strlen(str); + if(SERVER_IS_RUNNING(ptr->server)) + { + if (!first) + { + strncat(dest, ",", len); + } + first = false; + snprintf(arr, sizeof(arr), "%s:%d", ptr->server->name, ptr->server->port); + strncat(dest, arr, len); + slen = strlen(dest); + } + ptr = ptr->next; } } @@ -302,23 +312,26 @@ bool mon_print_fail_status( */ void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) { - char argstr[PATH_MAX + MON_ARG_MAX + 1]; - EXTERNCMD* cmd; + char nodelist[PATH_MAX + MON_ARG_MAX + 1] = {'\0'}; + char event[strlen(mon_get_event_name(ptr))]; + char initiator[strlen(ptr->server->name) + 24]; // Extra space for port - snprintf(argstr, PATH_MAX + MON_ARG_MAX, - "%s --event=%s --initiator=%s:%d --nodelist=", - script, - mon_get_event_name(ptr), - ptr->server->name, - ptr->server->port); + snprintf(initiator, sizeof(initiator), "%s:%d", ptr->server->name, ptr->server->port); + snprintf(event, sizeof(event), "%s", mon_get_event_name(ptr)); + mon_append_node_names(mon->databases, nodelist, PATH_MAX + MON_ARG_MAX); - mon_append_node_names(mon->databases, argstr, PATH_MAX + MON_ARG_MAX); - if ((cmd = externcmd_allocate(argstr)) == NULL) + EXTERNCMD* cmd = externcmd_allocate(script); + + if (cmd == NULL) { skygw_log_write(LE, "Failed to initialize script: %s", script); return; } + externcmd_substitute_arg(cmd, "[$]INITIATOR", initiator); + externcmd_substitute_arg(cmd, "[$]EVENT", event); + externcmd_substitute_arg(cmd, "[$]NODELIST", nodelist); + if (externcmd_execute(cmd)) { skygw_log_write(LOGFILE_ERROR, From ba9da9ae3d74546fe63023ff21c3f7e0f25003c3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 21:26:10 +0200 Subject: [PATCH 139/179] Fixed invalid EXTERNCMD allocation externcmd_allocate now returns either a valid EXTERNCMD or NULL. --- server/core/externcmd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/server/core/externcmd.c b/server/core/externcmd.c index 413854ba9..644c6c2cf 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -82,11 +82,12 @@ int tokenize_arguments(char* argstr, char** argv) */ EXTERNCMD* externcmd_allocate(char* argstr) { - EXTERNCMD* cmd = NULL; + EXTERNCMD* cmd = (EXTERNCMD*) malloc(sizeof(EXTERNCMD)); + char** argv = (char**) malloc(sizeof(char*) * MAXSCALE_EXTCMD_ARG_MAX); - if (argstr && (cmd = (EXTERNCMD*) malloc(sizeof(EXTERNCMD))) && - (cmd->argv = malloc(sizeof(char*) * MAXSCALE_EXTCMD_ARG_MAX))) + if (argstr && cmd && argv) { + cmd->argv = argv; if (tokenize_arguments(argstr, cmd->argv) == 0) { if (access(cmd->argv[0], X_OK) != 0) @@ -110,6 +111,12 @@ EXTERNCMD* externcmd_allocate(char* argstr) cmd = NULL; } } + else + { + free(cmd); + free(argv); + cmd = NULL; + } return cmd; } From e37ba0a63d8140b7b99c3a9c8332128fe842958b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 21:38:37 +0200 Subject: [PATCH 140/179] Fixed build failures due to conflicts Due to an odd rebase, a conflict was left in externcmd.c --- server/core/externcmd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server/core/externcmd.c b/server/core/externcmd.c index 644c6c2cf..ee6e2d28a 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -214,7 +214,6 @@ bool externcmd_substitute_arg(EXTERNCMD* cmd, const char* match, const char* rep else { rval = false; - LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd)); } return rval; } From 3cfd1ee4e8cd735456b43adbdc4c59a5fa5440db Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 11 Nov 2015 21:39:52 +0200 Subject: [PATCH 141/179] Log: Logging is now done by priority and not logfile. The native way for logging is now by syslog priority and not by logfile id. In practice that means that there's a function - mxs_log_message - that takes a syslog priority. The new logging macros (MXS_ERROR and friends) call that directly and the old ones as well after having the logfile id translated into the equivalent priority. What is enabled or not is still by logfile id and hence the priority is internally translated into a logfile id when checking whether something really should be logged or not. --- log_manager/log_manager.cc | 466 +++++++++++++++++++++---------------- log_manager/log_manager.h | 56 ++--- 2 files changed, 288 insertions(+), 234 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 94be58b40..7ae102a0d 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -49,6 +49,16 @@ static const char LOGFILE_NAME_SUFFIX[] = ".log"; extern char *program_invocation_name; extern char *program_invocation_short_name; +/** + * LOG_FLUSH_NO Do not flush after writing. + * LOG_FLUSH_YES Flush after writing. + */ +enum log_flush +{ + LOG_FLUSH_NO = 0, + LOG_FLUSH_YES = 1 +}; + #if defined(SS_DEBUG) static int write_index; static int block_start_index; @@ -284,11 +294,11 @@ static bool logmanager_init_nomutex(const char* ident, static void logmanager_done_nomutex(void); static bool logmanager_is_valid_id(logfile_id_t id); -static int logmanager_write_log(logfile_id_t id, - enum log_flush flush, - size_t prefix_len, - size_t len, - const char* str); +static int logmanager_write_log(int priority, + enum log_flush flush, + size_t prefix_len, + size_t len, + const char* str); static blockbuf_t* blockbuf_init(); static void blockbuf_node_done(void* bb_data); @@ -577,7 +587,7 @@ static bool logmanager_is_valid_id(logfile_id_t id) { const char ERRSTR[] = "Invalid logfile id argument."; - int err = logmanager_write_log(LOGFILE_ERROR, + int err = logmanager_write_log(LOG_ERR, LOG_FLUSH_YES, 0, sizeof(ERRSTR), ERRSTR); @@ -595,7 +605,7 @@ static bool logmanager_is_valid_id(logfile_id_t id) * * Parameters: * - * @param id logfile object identifier + * @param priority Syslog priority * @param flush indicates whether log string must be written to disk * immediately * @param rotate if set, closes currently open log file and opens a @@ -607,11 +617,11 @@ static bool logmanager_is_valid_id(logfile_id_t id) * @return 0 if succeed, -1 otherwise * */ -static int logmanager_write_log(logfile_id_t id, - enum log_flush flush, - size_t prefix_len, - size_t str_len, - const char* str) +static int logmanager_write_log(int priority, + enum log_flush flush, + size_t prefix_len, + size_t str_len, + const char* str) { logfile_t* lf; char* wp; @@ -629,7 +639,7 @@ static int logmanager_write_log(logfile_id_t id, int do_syslog = log_config.do_syslog; assert(str); - assert(logmanager_is_valid_id(id)); + assert((priority & ~LOG_PRIMASK) == 0); CHK_LOGMANAGER(lm); // All messages are now logged to the error log file. @@ -646,7 +656,7 @@ static int logmanager_write_log(logfile_id_t id, * If session id is stored to tls_log_info structure, allocate * room for session id too. */ - if (id == LOGFILE_TRACE && tls_log_info.li_sesid != 0) + if ((priority == LOG_INFO) && (tls_log_info.li_sesid != 0)) { sesid_str_len = 5 * sizeof(char) + get_decimal_len(tls_log_info.li_sesid); } @@ -765,16 +775,16 @@ static int logmanager_write_log(logfile_id_t id, /** write to syslog */ if (do_syslog) { - // Strip away the timestamp and the prefix (e.g. "[Error]: "). + // Strip away the timestamp and the prefix (e.g. "error : "). const char *message = wp + timestamp_len + prefix_len; - switch (id) + switch (priority) { - case LOGFILE_ERROR: + case LOG_ERR: syslog(LOG_ERR, "%s", message); break; - case LOGFILE_MESSAGE: + case LOG_NOTICE: syslog(LOG_NOTICE, "%s", message); break; @@ -1272,7 +1282,7 @@ int skygw_log_get_augmentation() /** * Helper for skygw_log_write and friends. * - * @param id The id of the log file. + * @param int The syslog priority. * @param file The name of the file where the logging was made. * @param int The line where the logging was made. * @param function The function where the logging was made. @@ -1284,7 +1294,7 @@ int skygw_log_get_augmentation() * @return 0 if the logging to at least one log succeeded. */ -static int log_write(logfile_id_t id, +static int log_write(int priority, const char* file, int line, const char* function, @@ -1299,7 +1309,7 @@ static int log_write(logfile_id_t id, { CHK_LOGMANAGER(lm); - rv = logmanager_write_log(id, flush, prefix_len, len, str); + rv = logmanager_write_log(priority, flush, prefix_len, len, str); logmanager_unregister(); } @@ -1307,188 +1317,6 @@ static int log_write(logfile_id_t id, return rv; } -typedef struct log_prefix -{ - const char* text; // The prefix, e.g. "[Error]: " - int len; // The length of the prefix without the trailing NULL. -} log_prefix_t; - -const char PREFIX_ERROR[] = "[Error] : "; -const char PREFIX_NOTICE[] = "[Notice]: "; -const char PREFIX_INFO[] = "[Info] : "; -const char PREFIX_DEBUG[] = "[Debug] : "; - -/** - * Returns the most "severe" file id. - * - * @param ids A single id or a bitmask of ids. - * @return A single id - */ -static logfile_id_t logfile_ids_to_id(logfile_id_t ids) -{ - // The id can be a bitmask, hence we choose the most "severe" one. - if (ids & LOGFILE_ERROR) - { - return LOGFILE_ERROR; - } - else if (ids & LOGFILE_MESSAGE) - { - return LOGFILE_MESSAGE; - } - else if (ids & LOGFILE_TRACE) - { - return LOGFILE_TRACE; - } - else if (ids & LOGFILE_DEBUG) - { - return LOGFILE_DEBUG; - } - else - { - assert(!true); - return LOGFILE_ERROR; - } -} - -/** - * Returns the prefix to be used for a specific logfile id. - * - * @param id A logfile id (not a mask) - * @return The corresponding prefix. - */ -static log_prefix_t logfile_id_to_prefix(logfile_id_t id) -{ - log_prefix_t prefix; - - switch (id) - { - case LOGFILE_ERROR: - prefix.text = PREFIX_ERROR; - prefix.len = sizeof(PREFIX_ERROR); - break; - - case LOGFILE_MESSAGE: - prefix.text = PREFIX_NOTICE; - prefix.len = sizeof(PREFIX_NOTICE); - break; - - case LOGFILE_TRACE: - prefix.text = PREFIX_INFO; - prefix.len = sizeof(PREFIX_INFO); - break; - - case LOGFILE_DEBUG: - prefix.text = PREFIX_DEBUG; - prefix.len = sizeof(PREFIX_DEBUG); - break; - - default: - assert(!true); - prefix.text = PREFIX_ERROR; - prefix.len = sizeof(PREFIX_ERROR); - break; - } - - --prefix.len; // Remove trailing NULL. - - return prefix; -} - -int skygw_log_write_context(logfile_id_t id, - enum log_flush flush, - const char* file, - int line, - const char* function, - const char* str, - ...) -{ - int err = 0; - - id = logfile_ids_to_id(id); // Pick the most severe one. - - if (LOG_IS_ENABLED(id)) - { - va_list valist; - - /** - * Find out the length of log string (to be formatted str). - */ - va_start(valist, str); - int message_len = vsnprintf(NULL, 0, str, valist); - va_end(valist); - - if (message_len >= 0) - { - log_prefix_t prefix = logfile_id_to_prefix(id); - - static const char FORMAT_FUNCTION[] = "(%s): "; - - int augmentation_len = 0; - - switch (log_augmentation) - { - case LOG_AUGMENT_WITH_FUNCTION: - augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0 - augmentation_len -= 2; // Remove the %s - augmentation_len += strlen(function); - break; - - default: - break; - } - - int buffer_len = prefix.len + augmentation_len + message_len + 1; // Trailing NULL - - if (buffer_len > MAX_LOGSTRLEN) - { - message_len -= (buffer_len - MAX_LOGSTRLEN); - buffer_len = MAX_LOGSTRLEN; - - assert(prefix.len + augmentation_len + message_len + 1 == buffer_len); - } - - char buffer[buffer_len]; - - char *prefix_text = buffer; - char *augmentation_text = buffer + prefix.len; - char *message_text = buffer + prefix.len + augmentation_len; - - strcpy(prefix_text, prefix.text); - - if (augmentation_len) - { - int len = 0; - - switch (log_augmentation) - { - case LOG_AUGMENT_WITH_FUNCTION: - len = sprintf(augmentation_text, FORMAT_FUNCTION, function); - break; - - default: - assert(!true); - } - - assert(len == augmentation_len); - } - - va_start(valist, str); - vsnprintf(message_text, message_len + 1, str, valist); - va_end(valist); - - err = log_write(id, file, line, function, prefix.len, buffer_len, buffer, flush); - - if (err != 0) - { - fprintf(stderr, "skygw_log_write failed.\n"); - } - } - } - - return err; -} - - int skygw_log_flush(logfile_id_t id) { int err = -1; @@ -3000,3 +2828,235 @@ int mxs_log_disable_priority(int priority) return rv; } + +typedef struct log_prefix +{ + const char* text; // The prefix, e.g. "error: " + int len; // The length of the prefix without the trailing NULL. +} log_prefix_t; + +static const char PREFIX_EMERG[] = "emerg : "; +static const char PREFIX_ALERT[] = "alert : "; +static const char PREFIX_CRIT[] = "crit : "; +static const char PREFIX_ERROR[] = "error : "; +static const char PREFIX_WARNING[] = "warning: "; +static const char PREFIX_NOTICE[] = "notice : "; +static const char PREFIX_INFO[] = "info : "; +static const char PREFIX_DEBUG[] = "debug : "; + +static logfile_id_t priority_to_id(int priority) +{ + assert((priority & ~LOG_PRIMASK) == 0); + + switch (priority) + { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + case LOG_WARNING: + return LOGFILE_ERROR; + + case LOG_NOTICE: + return LOGFILE_MESSAGE; + + case LOG_INFO: + return LOGFILE_TRACE; + + case LOG_DEBUG: + return LOGFILE_DEBUG; + + default: + // Can't happen! + assert(!true); + return LOGFILE_ERROR; + } +} + +static log_prefix_t priority_to_prefix(int priority) +{ + assert((priority & ~LOG_PRIMASK) == 0); + + log_prefix_t prefix; + + switch (priority) + { + case LOG_EMERG: + prefix.text = PREFIX_EMERG; + prefix.len = sizeof(PREFIX_EMERG); + break; + + case LOG_ALERT: + prefix.text = PREFIX_ALERT; + prefix.len = sizeof(PREFIX_ALERT); + break; + + case LOG_CRIT: + prefix.text = PREFIX_CRIT; + prefix.len = sizeof(PREFIX_CRIT); + break; + + case LOG_ERR: + prefix.text = PREFIX_ERROR; + prefix.len = sizeof(PREFIX_ERROR); + break; + + case LOG_WARNING: + prefix.text = PREFIX_WARNING; + prefix.len = sizeof(PREFIX_WARNING); + break; + + case LOG_NOTICE: + prefix.text = PREFIX_NOTICE; + prefix.len = sizeof(PREFIX_NOTICE); + break; + + case LOG_INFO: + prefix.text = PREFIX_INFO; + prefix.len = sizeof(PREFIX_INFO); + break; + + case LOG_DEBUG: + prefix.text = PREFIX_DEBUG; + prefix.len = sizeof(PREFIX_DEBUG); + break; + + default: + assert(!true); + prefix.text = PREFIX_ERROR; + prefix.len = sizeof(PREFIX_ERROR); + break; + } + + --prefix.len; // Remove trailing NULL. + + return prefix; +} + +static enum log_flush priority_to_flush(int priority) +{ + assert((priority & ~LOG_PRIMASK) == 0); + + switch (priority) + { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + return LOG_FLUSH_YES; + + default: + assert(!true); + case LOG_WARNING: + case LOG_NOTICE: + case LOG_INFO: + case LOG_DEBUG: + return LOG_FLUSH_NO; + } +} + +/** + * Log a message of a particular priority. + * + * @param priority One of the syslog constants: LOG_ERR, LOG_WARNING, ... + * @param file The name of the file where the message was logged. + * @param line The line where the message was logged. + * @param function The function where the message was logged. + * @param format The printf format of the following arguments. + * @param ... Optional arguments according to the format. + */ +int mxs_log_message(int priority, + const char* file, int line, const char* function, + const char* format, ...) +{ + int err = 0; + + assert((priority & ~LOG_PRIMASK) == 0); + + if ((priority & ~LOG_PRIMASK) == 0) // Check that the priority is ok, + { + logfile_id_t id = priority_to_id(priority); + + if (LOG_IS_ENABLED(id)) + { + va_list valist; + + /** + * Find out the length of log string (to be formatted str). + */ + va_start(valist, format); + int message_len = vsnprintf(NULL, 0, format, valist); + va_end(valist); + + if (message_len >= 0) + { + log_prefix_t prefix = priority_to_prefix(priority); + + static const char FORMAT_FUNCTION[] = "(%s): "; + + int augmentation_len = 0; + + switch (log_augmentation) + { + case LOG_AUGMENT_WITH_FUNCTION: + augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0 + augmentation_len -= 2; // Remove the %s + augmentation_len += strlen(function); + break; + + default: + break; + } + + int buffer_len = prefix.len + augmentation_len + message_len + 1; // Trailing NULL + + if (buffer_len > MAX_LOGSTRLEN) + { + message_len -= (buffer_len - MAX_LOGSTRLEN); + buffer_len = MAX_LOGSTRLEN; + + assert(prefix.len + augmentation_len + message_len + 1 == buffer_len); + } + + char buffer[buffer_len]; + + char *prefix_text = buffer; + char *augmentation_text = buffer + prefix.len; + char *message_text = buffer + prefix.len + augmentation_len; + + strcpy(prefix_text, prefix.text); + + if (augmentation_len) + { + int len = 0; + + switch (log_augmentation) + { + case LOG_AUGMENT_WITH_FUNCTION: + len = sprintf(augmentation_text, FORMAT_FUNCTION, function); + break; + + default: + assert(!true); + } + + assert(len == augmentation_len); + } + + va_start(valist, format); + vsnprintf(message_text, message_len + 1, format, valist); + va_end(valist); + + enum log_flush flush = priority_to_flush(priority); + + err = log_write(priority, file, line, function, prefix.len, buffer_len, buffer, flush); + } + } + } + else + { + MXS_WARNING("Invalid syslog priority: %d", priority); + } + + return err; +} diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index e273d4a1d..76eb14b35 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -18,6 +18,8 @@ #if !defined(LOG_MANAGER_H) # define LOG_MANAGER_H +#include + /* * We need a common.h file that is included by every component. */ @@ -130,16 +132,6 @@ typedef enum LOG_AUGMENTATION_MASK = (LOG_AUGMENT_WITH_FUNCTION) } log_augmentation_t; -/** - * LOG_FLUSH_NO Do not flush after writing. - * LOG_FLUSH_YES Flush after writing. - */ -enum log_flush -{ - LOG_FLUSH_NO = 0, - LOG_FLUSH_YES = 1 -}; - EXTERN_C_BLOCK_BEGIN extern int lm_enabled_logfiles_bitmask; @@ -151,6 +143,10 @@ int mxs_log_rotate(); int mxs_log_enable_priority(int priority); int mxs_log_disable_priority(int priority); +int mxs_log_message(int priority, + const char* file, int line, const char* function, + const char* format, ...); + bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t target); @@ -161,10 +157,6 @@ void skygw_logmanager_exit(void); * free private write buffer list */ void skygw_log_done(void); -int skygw_log_write_context(logfile_id_t id, - enum log_flush flush, - const char* file, int line, const char* function, - const char* format, ...); int skygw_log_flush(logfile_id_t id); void skygw_log_sync_all(void); int skygw_log_rotate(logfile_id_t id); @@ -175,11 +167,19 @@ void skygw_set_highp(int); void logmanager_enable_syslog(int); void logmanager_enable_maxscalelog(int); -#define skygw_log_write(id, format, ...)\ - skygw_log_write_context(id, LOG_FLUSH_NO, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) +inline int mxs_log_id_to_priority(logfile_id_t id) +{ + if (id & LOGFILE_ERROR) return LOG_ERR; + if (id & LOGFILE_MESSAGE) return LOG_NOTICE; + if (id & LOGFILE_TRACE) return LOG_INFO; + if (id & LOGFILE_DEBUG) return LOG_DEBUG; + return LOG_ERR; +} -#define skygw_log_write_flush(id, format, ...)\ - skygw_log_write_context(id, LOG_FLUSH_YES, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) +#define skygw_log_write(id, format, ...)\ + mxs_log_message(mxs_log_id_to_priority(id), __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) + +#define skygw_log_write_flush(id, format, ...) skygw_log_write(id, format, ##__VA_ARGS__) /** * What augmentation if any should a logged message be augmented with. @@ -194,14 +194,8 @@ EXTERN_C_BLOCK_END /** * Helper, not to be called directly. */ -#define MXS_MESSAGE_FLUSH(id, format, ...)\ - do { if (LOG_IS_ENABLED(id)) { skygw_log_write_flush(id, format, ##__VA_ARGS__); } } while (false) - -/** - * Helper, not to be called directly. - */ -#define MXS_MESSAGE(id, format, ...)\ - do { if (LOG_IS_ENABLED(id)) { skygw_log_write(id, format, ##__VA_ARGS__); } } while (false) +#define MXS_LOG_MESSAGE(priority, format, ...)\ + mxs_log_message(priority, __FILE__, __LINE__, __func__, format, ##__VA_ARGS__) /** * Log an error, warning, notice, info, or debug message. @@ -209,10 +203,10 @@ EXTERN_C_BLOCK_END * @param format The printf format of the message. * @param ... Arguments, depending on the format. */ -#define MXS_ERROR(format, ...) MXS_MESSAGE_FLUSH(LOGFILE_ERROR, format, ##__VA_ARGS__) -#define MXS_WARNING(format, ...) MXS_MESSAGE(LOGFILE_ERROR, format, ##__VA_ARGS__) -#define MXS_NOTICE(format, ...) MXS_MESSAGE(LOGFILE_MESSAGE, format, ##__VA_ARGS__) -#define MXS_INFO(format, ...) MXS_MESSAGE(LOGFILE_TRACE, format, ##__VA_ARGS__) -#define MXS_DEBUG(format, ...) MXS_MESSAGE(LOGFILE_DEBUG, format, ##__VA_ARGS__) +#define MXS_ERROR(format, ...) MXS_LOG_MESSAGE(LOG_ERR, format, ##__VA_ARGS__) +#define MXS_WARNING(format, ...) MXS_LOG_MESSAGE(LOG_WARNING, format, ##__VA_ARGS__) +#define MXS_NOTICE(format, ...) MXS_LOG_MESSAGE(LOG_NOTICE, format, ##__VA_ARGS__) +#define MXS_INFO(format, ...) MXS_LOG_MESSAGE(LOG_INFO, format, ##__VA_ARGS__) +#define MXS_DEBUG(format, ...) MXS_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__) #endif /** LOG_MANAGER_H */ From 0705f38bb929efc171b0648ed586e6e75d0cefe8 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 12 Nov 2015 09:42:24 +0200 Subject: [PATCH 142/179] Fix to MXS-464: https://mariadb.atlassian.net/browse/MXS-464 The ownership change for the /var folders is now done recursively. --- etc/init.d/maxscale.in | 8 ++++---- etc/postinst.in | 8 ++++---- etc/ubuntu/init.d/maxscale.in | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/etc/init.d/maxscale.in b/etc/init.d/maxscale.in index ea31e6c19..97d574632 100755 --- a/etc/init.d/maxscale.in +++ b/etc/init.d/maxscale.in @@ -81,10 +81,10 @@ start() { mkdir -p @MAXSCALE_VARDIR@/run/maxscale fi - chown maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale chmod 0755 @MAXSCALE_VARDIR@/log/maxscale chmod 0755 @MAXSCALE_VARDIR@/lib/maxscale chmod 0755 @MAXSCALE_VARDIR@/cache/maxscale diff --git a/etc/postinst.in b/etc/postinst.in index 93cc768ec..63d6de1f7 100755 --- a/etc/postinst.in +++ b/etc/postinst.in @@ -21,10 +21,10 @@ then fi # Change the owner of the directories to maxscale:maxscale -chown maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale -chown maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale -chown maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale -chown maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale +chown -R maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale +chown -R maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale +chown -R maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale +chown -R maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale chmod 0755 @MAXSCALE_VARDIR@/log/maxscale chmod 0755 @MAXSCALE_VARDIR@/lib/maxscale chmod 0755 @MAXSCALE_VARDIR@/cache/maxscale diff --git a/etc/ubuntu/init.d/maxscale.in b/etc/ubuntu/init.d/maxscale.in index a6985b4ba..341faefb6 100755 --- a/etc/ubuntu/init.d/maxscale.in +++ b/etc/ubuntu/init.d/maxscale.in @@ -81,10 +81,10 @@ start() { mkdir -p @MAXSCALE_VARDIR@/run/maxscale fi - chown maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale - chown maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/log/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/lib/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/cache/maxscale + chown -R maxscale:maxscale @MAXSCALE_VARDIR@/run/maxscale chmod 0755 @MAXSCALE_VARDIR@/log/maxscale chmod 0755 @MAXSCALE_VARDIR@/lib/maxscale chmod 0755 @MAXSCALE_VARDIR@/cache/maxscale From bdfd72404bbe2348bbd89422d986df76d7a8ece1 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 12 Nov 2015 09:15:56 +0200 Subject: [PATCH 143/179] Log: skygw_log_rotate replaced with mxs_log_rotate. With only one log-file no arguments are needed. The maxadmin command 'flush log' still accepts all the previous arguments, but warns about them being deprecated. --- log_manager/log_manager.cc | 64 +++++++------------ log_manager/log_manager.h | 1 - server/core/gateway.c | 5 +- server/modules/routing/debugcmd.c | 48 +++++++++----- server/modules/routing/maxinfo/maxinfo_exec.c | 7 +- 5 files changed, 57 insertions(+), 68 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 7ae102a0d..cf3653f90 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1349,47 +1349,6 @@ int skygw_log_flush(logfile_id_t id) return err; } -/** - * Replace current logfile with new file with increased sequence number on - * its name. - */ -int skygw_log_rotate(logfile_id_t id) -{ - int err = -1; - - if (id == LOGFILE_ERROR) - { - if (logmanager_register(false)) - { - CHK_LOGMANAGER(lm); - - logfile_t *lf = logmanager_get_logfile(lm); - CHK_LOGFILE(lf); - - MXS_NOTICE("Log rotation is called for %s.", lf->lf_full_file_name); - - logfile_rotate(lf); - err = 0; - - logmanager_unregister(); - } - else - { - ss_dfprintf(stderr, "Can't register to logmanager, rotating failed.\n"); - } - } - else - { - // We'll pretend everything went ok. - err = 0; - } - - return err; -} - - - - /** * @node Register as a logging client to logmanager. * @@ -2717,7 +2676,28 @@ int mxs_log_flush() */ int mxs_log_rotate() { - return skygw_log_rotate(LOGFILE_ERROR); + int err = -1; + + if (logmanager_register(false)) + { + CHK_LOGMANAGER(lm); + + logfile_t *lf = logmanager_get_logfile(lm); + CHK_LOGFILE(lf); + + MXS_NOTICE("Log rotation is called for %s.", lf->lf_full_file_name); + + logfile_rotate(lf); + err = 0; + + logmanager_unregister(); + } + else + { + ss_dfprintf(stderr, "Can't register to logmanager, rotating failed.\n"); + } + + return err; } static bool convert_priority_to_file(int priority, logfile_id_t* idp, const char** textp) diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 76eb14b35..be52d7675 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -159,7 +159,6 @@ void skygw_logmanager_exit(void); void skygw_log_done(void); int skygw_log_flush(logfile_id_t id); void skygw_log_sync_all(void); -int skygw_log_rotate(logfile_id_t id); int skygw_log_enable(logfile_id_t id); int skygw_log_disable(logfile_id_t id); void skygw_log_sync_all(void); diff --git a/server/core/gateway.c b/server/core/gateway.c index 29e6cfaa8..051387071 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -307,10 +307,7 @@ static void sigusr1_handler (int i) LOGIF(LM, (skygw_log_write( LOGFILE_MESSAGE, "Log file flush following reception of SIGUSR1\n"))); - skygw_log_rotate(LOGFILE_ERROR); - skygw_log_rotate(LOGFILE_MESSAGE); - skygw_log_rotate(LOGFILE_TRACE); - skygw_log_rotate(LOGFILE_DEBUG); + mxs_log_rotate(); } static void sigterm_handler (int i) { diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 414692e76..137f9e7bd 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -613,29 +613,48 @@ struct subcommand removeoptions[] = { static void flushlog(DCB *pdcb, char *logname) { - if (logname == NULL) + bool unrecognized = false; + bool deprecated = false; + + if (!strcasecmp(logname, "error")) { - } - else if (!strcasecmp(logname, "error")) - { - skygw_log_rotate(LOGFILE_ERROR); + deprecated = true; } else if (!strcasecmp(logname, "message")) { - skygw_log_rotate(LOGFILE_MESSAGE); + deprecated = true; } else if (!strcasecmp(logname, "trace")) { - skygw_log_rotate(LOGFILE_TRACE); + deprecated = true; } else if (!strcasecmp(logname, "debug")) { - skygw_log_rotate(LOGFILE_DEBUG); + deprecated = true; + } + else if (!strcasecmp(logname, "maxscale")) + { + ; // nop } else { - dcb_printf(pdcb, "Unexpected logfile name, expected " - "error, message, trace or debug.\n"); + unrecognized = true; + } + + if (unrecognized) + { + dcb_printf(pdcb, "Unexpected logfile name '%s', expected: 'maxscale'.\n", logname); + } + else + { + mxs_log_rotate(); + + if (deprecated) + { + dcb_printf(pdcb, + "'%s' is deprecated, currently there is only one log 'maxscale', " + "which was rotated.\n", logname); + } } } @@ -647,10 +666,7 @@ flushlog(DCB *pdcb, char *logname) static void flushlogs(DCB *pdcb) { - skygw_log_rotate(LOGFILE_ERROR); - skygw_log_rotate(LOGFILE_MESSAGE); - skygw_log_rotate(LOGFILE_TRACE); - skygw_log_rotate(LOGFILE_DEBUG); + mxs_log_rotate(); } @@ -670,8 +686,8 @@ struct subcommand flushoptions[] = { "logs", 0, flushlogs, - "Flush the content of all log files, close that logs, rename them and open a new log files", - "Flush the content of all log files, close that logs, rename them and open a new log files", + "Flush the content of all log files, close those logs, rename them and open a new log files", + "Flush the content of all log files, close those logs, rename them and open a new log files", {0, 0, 0} }, { diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index 3c2b0849d..b3c59c1dd 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -303,10 +303,7 @@ char errmsg[120]; */ void exec_flush_logs(DCB *dcb, MAXINFO_TREE *tree) { - skygw_log_rotate(LE); - skygw_log_rotate(LM); - skygw_log_rotate(LT); - skygw_log_rotate(LD); + mxs_log_rotate(); maxinfo_send_ok(dcb); } @@ -1252,4 +1249,4 @@ void maxinfo_send_ok(DCB *dcb) memcpy(buffer->start, ok_packet, sizeof(ok_packet)); dcb->func.write(dcb, buffer); } -} \ No newline at end of file +} From 5efd56457394287d2f17e425daa90267560cdcdd Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 12 Nov 2015 11:57:29 +0200 Subject: [PATCH 144/179] Fix to MXS-288: https://mariadb.atlassian.net/browse/MXS-288 Added MySQL 5.7 authentication The change to the mysql.user table in MySQL 5.7 caused MaxScale to stop working with it. This commit adds functionality that checks which version of the user data query should be made. It also moves common code related to server version strings to server.c --- server/core/dbusers.c | 103 ++++++++++++++++++++----- server/core/server.c | 21 +++++ server/include/server.h | 1 + server/modules/monitor/galeramon.c | 9 +-- server/modules/monitor/mmmon.c | 9 +-- server/modules/monitor/mysql_mon.c | 7 +- server/modules/monitor/ndbclustermon.c | 9 +-- 7 files changed, 120 insertions(+), 39 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 2dc434329..a4e48afa0 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -90,12 +90,28 @@ ON user.user=db.user AND user.host=db.host \ WHERE user.user IS NOT NULL" MYSQL_USERS_WITH_DB_ORDER +#define LOAD_MYSQL57_USERS_WITH_DB_QUERY "SELECT \ + user.user AS user, \ + user.host AS host, \ + user.authentication_string AS password, \ + concat(user.user,user.host,user.authentication_string,user.Select_priv,IFNULL(db,'')) AS userdata, \ + user.Select_priv AS anydb, \ + db.db AS db \ + FROM mysql.user LEFT JOIN mysql.db \ + ON user.user=db.user AND user.host=db.host \ + WHERE user.user IS NOT NULL" MYSQL_USERS_WITH_DB_ORDER + #define MYSQL_USERS_WITH_DB_COUNT "SELECT COUNT(1) AS nusers_db FROM (" LOAD_MYSQL_USERS_WITH_DB_QUERY ") AS tbl_count" +#define MYSQL57_USERS_WITH_DB_COUNT "SELECT COUNT(1) AS nusers_db FROM (" LOAD_MYSQL57_USERS_WITH_DB_QUERY ") AS tbl_count" #define LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT "SELECT * \ FROM (" LOAD_MYSQL_USERS_WITH_DB_QUERY ") AS t1 \ WHERE user NOT IN ('root')" MYSQL_USERS_WITH_DB_ORDER +#define LOAD_MYSQL57_USERS_WITH_DB_QUERY_NO_ROOT "SELECT * \ + FROM (" LOAD_MYSQL57_USERS_WITH_DB_QUERY ") AS t1 \ + WHERE user NOT IN ('root')" MYSQL_USERS_WITH_DB_ORDER + #define LOAD_MYSQL_DATABASE_NAMES "SELECT * \ FROM ( (SELECT COUNT(1) AS ndbs \ FROM INFORMATION_SCHEMA.SCHEMATA) AS tbl1, \ @@ -133,6 +149,39 @@ int add_wildcard_users(USERS *users, static int gw_mysql_set_timeouts(MYSQL* handle); +/** + * Get the user data query. + * @param server_version Server version string + * @param include_root Include root user + * @return Users query + */ +const char* get_mysql_users_query(char* server_version, bool include_root) +{ + const char* rval; + if (strstr(server_version, "5.7.")) + { + rval = include_root ? LOAD_MYSQL57_USERS_WITH_DB_QUERY : + LOAD_MYSQL57_USERS_WITH_DB_QUERY_NO_ROOT; + } + else + { + rval = include_root ? LOAD_MYSQL_USERS_WITH_DB_QUERY : + LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT; + } + return rval; +} + +/** + * Get the user count query. + * @param server_version Server version string + * @return User vount query + * */ +const char* get_mysq_users_db_count_query(char* server_version) +{ + return strstr(server_version, "5.7.") ? + MYSQL57_USERS_WITH_DB_COUNT : MYSQL_USERS_WITH_DB_COUNT; +} + /** * Check if the IP address of the user matches the one in the grant. This assumes * that the grant has one or more single-character wildcards in it. @@ -651,7 +700,8 @@ getAllUsers(SERVICE *service, USERS *users) char *dpwd = NULL; int total_users = 0; SERVER_REF *server; - char *users_query, *tmp; + const char *users_query; + char *tmp; unsigned char hash[SHA_DIGEST_LENGTH]=""; char *users_data = NULL; char *final_data = NULL; @@ -825,9 +875,19 @@ getAllUsers(SERVICE *service, USERS *users) mysql_close(con); goto cleanup; } - + + if (server->server->server_string == NULL) + { + const char *server_string = mysql_get_server_info(con); + if (!server_set_version_string(server->server, server_string)) + { + mysql_close(con); + goto cleanup; + } + } /** Count users. Start with users and db grants for users */ - if (mysql_query(con, MYSQL_USERS_WITH_DB_COUNT)) { + const char *user_with_db_count = get_mysq_users_db_count_query(server->server->server_string); + if (mysql_query(con, user_with_db_count)) { if (mysql_errno(con) != ER_TABLEACCESS_DENIED_ERROR) { /* This is an error we cannot handle, return */ LOGIF(LE, (skygw_log_write_flush( @@ -883,13 +943,10 @@ getAllUsers(SERVICE *service, USERS *users) mysql_close(con); goto cleanup; } - - if(service->enable_root) { - /* enable_root for MySQL protocol module means load the root user credentials from backend databases */ - users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY; - } else { - users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT; - } + + users_query = get_mysql_users_query(server->server->server_string, + service->enable_root); + /* send first the query that fetches users and db grants */ if (mysql_query(con, users_query)) { @@ -1197,7 +1254,7 @@ getUsers(SERVICE *service, USERS *users) char *dpwd; int total_users = 0; SERVER_REF *server; - char *users_query; + const char *users_query; unsigned char hash[SHA_DIGEST_LENGTH]=""; char *users_data = NULL; int nusers = 0; @@ -1343,10 +1400,21 @@ getUsers(SERVICE *service, USERS *users) service->name))); mysql_close(con); return -1; - } + } + if (server->server->server_string == NULL) + { + const char *server_string = mysql_get_server_info(con); + if (!server_set_version_string(server->server, server_string)) + { + mysql_close(con); + return -1; + } + } + + const char *user_with_db_count = get_mysq_users_db_count_query(server->server->server_string); /** Count users. Start with users and db grants for users */ - if (mysql_query(con, MYSQL_USERS_WITH_DB_COUNT)) { + if (mysql_query(con, user_with_db_count)) { if (mysql_errno(con) != ER_TABLEACCESS_DENIED_ERROR) { /* This is an error we cannot handle, return */ LOGIF(LE, (skygw_log_write_flush( @@ -1403,13 +1471,8 @@ getUsers(SERVICE *service, USERS *users) return -1; } - if(service->enable_root) { - /* enable_root for MySQL protocol module means load the root user credentials from backend databases */ - users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY; - } else { - users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT; - } - + users_query = get_mysql_users_query(server->server->server_string, + service->enable_root); /* send first the query that fetches users and db grants */ if (mysql_query(con, users_query)) { /* diff --git a/server/core/server.c b/server/core/server.c index 063ed6452..5d5a42f6e 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -942,3 +942,24 @@ int i; return ServerBits[i].bit; return 0; } + +/** + * Set the version string of the server. + * @param server Server to update + * @param string Version string + * @return True if the assignment of the version string was successful, false if + * memory allocation failed. + */ +bool server_set_version_string(SERVER* server, const char* string) +{ + bool rval = true; + spinlock_acquire(&server->lock); + free(server->server_string); + if ((server->server_string = strdup(string)) == NULL) + { + MXS_ERROR("Memory allocation failed."); + rval = false; + } + spinlock_release(&server->lock); + return rval; +} diff --git a/server/include/server.h b/server/include/server.h index 263522959..84151ccad 100644 --- a/server/include/server.h +++ b/server/include/server.h @@ -212,4 +212,5 @@ extern void server_update_address(SERVER *, char *); extern void server_update_port(SERVER *, unsigned short); extern RESULTSET *serverGetList(); extern unsigned int server_map_status(char *str); +extern bool server_set_version_string(SERVER* server, const char* string); #endif diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 4df951430..e81339832 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -308,11 +308,10 @@ char *server_string; /* get server version string */ server_string = (char *)mysql_get_server_info(database->con); - if (server_string) { - database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1); - if (database->server->server_string) - strcpy(database->server->server_string, server_string); - } + if (server_string) + { + server_set_version_string(database->server, server_string); + } /* Check if the the Galera FSM shows this node is joined to the cluster */ if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0 diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 7718f1435..2339a69a9 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -295,11 +295,10 @@ char *server_string; /* get server version string */ server_string = (char *)mysql_get_server_info(database->con); - if (server_string) { - database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1); - if (database->server->server_string) - strcpy(database->server->server_string, server_string); - } + if (server_string) + { + server_set_version_string(database->server, server_string); + } /* get server_id form current node */ if (mysql_query(database->con, "SELECT @@server_id") == 0 diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index c45c7604f..bd8e3e54f 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -643,10 +643,9 @@ monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) /* get server version string */ server_string = (char *)mysql_get_server_info(database->con); - if (server_string) { - database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1); - if (database->server->server_string) - strcpy(database->server->server_string, server_string); + if (server_string) + { + server_set_version_string(database->server, server_string); } /* get server_id form current node */ diff --git a/server/modules/monitor/ndbclustermon.c b/server/modules/monitor/ndbclustermon.c index aabccf60c..ea9de889f 100644 --- a/server/modules/monitor/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon.c @@ -263,11 +263,10 @@ char *server_string; /* get server version string */ server_string = (char *)mysql_get_server_info(database->con); - if (server_string) { - database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1); - if (database->server->server_string) - strcpy(database->server->server_string, server_string); - } + if (server_string) + { + server_set_version_string(database->server, server_string); + } /* Check if the the SQL node is able to contact one or more data nodes */ if (mysql_query(database->con, "SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'") == 0 From 680345d374740c176352bc289e6aa29ed1595455 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 12 Nov 2015 14:58:11 +0200 Subject: [PATCH 145/179] Whitespace cleanup of config.c - Tabs replaced with spaces. - Allman indentation style --- server/core/config.c | 4235 ++++++++++++++++++++++-------------------- 1 file changed, 2178 insertions(+), 2057 deletions(-) diff --git a/server/core/config.c b/server/core/config.c index a1497adc8..8927def5d 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -22,27 +22,27 @@ * @verbatim * Revision History * - * Date Who Description - * 21/06/13 Mark Riddoch Initial implementation - * 08/07/13 Mark Riddoch Addition on monitor module support - * 23/07/13 Mark Riddoch Addition on default monitor password - * 06/02/14 Massimiliano Pinto Added support for enable/disable root user in services - * 14/02/14 Massimiliano Pinto Added enable_root_user in the service_params list - * 11/03/14 Massimiliano Pinto Added Unix socket support - * 11/05/14 Massimiliano Pinto Added version_string support to service - * 19/05/14 Mark Riddoch Added unique names from section headers - * 29/05/14 Mark Riddoch Addition of filter definition - * 23/05/14 Massimiliano Pinto Added automatic set of maxscale-id: first listening ipv4_raw + port + pid - * 28/05/14 Massimiliano Pinto Added detect_replication_lag parameter - * 28/08/14 Massimiliano Pinto Added detect_stale_master parameter - * 09/09/14 Massimiliano Pinto Added localhost_match_wildcard_host parameter - * 12/09/14 Mark Riddoch Addition of checks on servers list and - * internal router suppression of messages - * 30/10/14 Massimiliano Pinto Added disable_master_failback parameter - * 07/11/14 Massimiliano Pinto Addition of monitor timeouts for connect/read/write - * 20/02/15 Markus Mäkelä Added connection_timeout parameter for services - * 05/03/15 Massimiliano Pinto Added notification_feedback support - * 20/04/15 Guillaume Lefranc Added available_when_donor parameter + * Date Who Description + * 21/06/13 Mark Riddoch Initial implementation + * 08/07/13 Mark Riddoch Addition on monitor module support + * 23/07/13 Mark Riddoch Addition on default monitor password + * 06/02/14 Massimiliano Pinto Added support for enable/disable root user in services + * 14/02/14 Massimiliano Pinto Added enable_root_user in the service_params list + * 11/03/14 Massimiliano Pinto Added Unix socket support + * 11/05/14 Massimiliano Pinto Added version_string support to service + * 19/05/14 Mark Riddoch Added unique names from section headers + * 29/05/14 Mark Riddoch Addition of filter definition + * 23/05/14 Massimiliano Pinto Added automatic set of maxscale-id: first listening ipv4_raw + port + pid + * 28/05/14 Massimiliano Pinto Added detect_replication_lag parameter + * 28/08/14 Massimiliano Pinto Added detect_stale_master parameter + * 09/09/14 Massimiliano Pinto Added localhost_match_wildcard_host parameter + * 12/09/14 Mark Riddoch Addition of checks on servers list and + * internal router suppression of messages + * 30/10/14 Massimiliano Pinto Added disable_master_failback parameter + * 07/11/14 Massimiliano Pinto Addition of monitor timeouts for connect/read/write + * 20/02/15 Markus Mäkelä Added connection_timeout parameter for services + * 05/03/15 Massimiliano Pinto Added notification_feedback support + * 20/04/15 Guillaume Lefranc Added available_when_donor parameter * 22/04/15 Martin Brampton Added disable_master_role_setting parameter * * @endverbatim @@ -83,50 +83,54 @@ #define MAXSCALE_PCRE_BUFSZ 24 extern int setipaddress(struct in_addr *, char *); -static int process_config_context(CONFIG_CONTEXT *); -static int process_config_update(CONFIG_CONTEXT *); -static void free_config_context(CONFIG_CONTEXT *); -static char *config_get_value(CONFIG_PARAMETER *, const char *); -static const char *config_get_value_string(CONFIG_PARAMETER *, const char *); -static int handle_global_item(const char *, const char *); -static int handle_feedback_item(const char *, const char *); -static void global_defaults(); -static void feedback_defaults(); -static void check_config_objects(CONFIG_CONTEXT *context); +static int process_config_context(CONFIG_CONTEXT *); +static int process_config_update(CONFIG_CONTEXT *); +static void free_config_context(CONFIG_CONTEXT *); +static char *config_get_value(CONFIG_PARAMETER *, const char *); +static const char *config_get_value_string(CONFIG_PARAMETER *, const char *); +static int handle_global_item(const char *, const char *); +static int handle_feedback_item(const char *, const char *); +static void global_defaults(); +static void feedback_defaults(); +static void check_config_objects(CONFIG_CONTEXT *context); static int maxscale_getline(char** dest, int* size, FILE* file); -int config_truth_value(char *str); -bool isInternalService(char *router); -int config_get_ifaddr(unsigned char *output); -int config_get_release_string(char* release); -FEEDBACK_CONF * config_get_feedback_data(); -void config_add_param(CONFIG_CONTEXT*,char*,char*); +int config_truth_value(char *str); +bool isInternalService(char *router); +int config_get_ifaddr(unsigned char *output); +int config_get_release_string(char* release); +FEEDBACK_CONF *config_get_feedback_data(); +void config_add_param(CONFIG_CONTEXT*, char*, char*); bool config_has_duplicate_sections(const char* config); -static char *config_file = NULL; -static GATEWAY_CONF gateway; -static FEEDBACK_CONF feedback; -char *version_string = NULL; +static char *config_file = NULL; +static GATEWAY_CONF gateway; +static FEEDBACK_CONF feedback; +char *version_string = NULL; /** * Trim whitespace from the front and rear of a string * - * @param str String to trim - * @return Trimmed string, changes are done in situ + * @param str String to trim + * @return Trimmed string, changes are done in situ */ static char * trim(char *str) { -char *ptr; + char *ptr; - while (isspace(*str)) - str++; + while (isspace(*str)) + { + str++; + } - /* Point to last character of the string */ - ptr = str + strlen(str) - 1; - while (ptr > str && isspace(*ptr)) - *ptr-- = 0; + /* Point to last character of the string */ + ptr = str + strlen(str) - 1; + while (ptr > str && isspace(*ptr)) + { + *ptr-- = 0; + } - return str; + return str; } /** @@ -139,35 +143,36 @@ char* config_clean_string_list(char* str) { char *tmp; - if((tmp = malloc(sizeof(char)*(strlen(str) + 1))) != NULL) + if ((tmp = malloc(sizeof(char) * (strlen(str) + 1))) != NULL) { char *ptr; int match[MAXSCALE_PCRE_BUFSZ]; pcre* re; const char *re_err; - int err_offset,rval; - + int err_offset, rval; tmp[0] = '\0'; - if((re = pcre_compile("\\s*+([^,]*[^,\\s])",0,&re_err,&err_offset,NULL)) == NULL) + if ((re = pcre_compile("\\s*+([^,]*[^,\\s])", 0, &re_err, &err_offset, NULL)) == NULL) { - skygw_log_write(LE,"[%s] Error: Regular expression compilation failed at %d: %s", - __FUNCTION__,err_offset,re_err); + skygw_log_write(LE, "[%s] Error: Regular expression compilation failed at %d: %s", + __FUNCTION__, err_offset, re_err); free(tmp); return NULL; } ptr = str; - while((rval = pcre_exec(re,NULL,ptr,strlen(ptr),0,0,(int*)&match,MAXSCALE_PCRE_BUFSZ)) > 1) + while ((rval = pcre_exec(re, NULL, ptr, strlen(ptr), 0, 0, (int*)&match, MAXSCALE_PCRE_BUFSZ)) > 1) { const char* substr; - pcre_get_substring(ptr,(int*)&match,rval,1,&substr); - if(strlen(tmp) > 0) - strcat(tmp,","); - strcat(tmp,substr); + pcre_get_substring(ptr, (int*)&match, rval, 1, &substr); + if (strlen(tmp) > 0) + { + strcat(tmp, ","); + } + strcat(tmp, substr); pcre_free_substring(substr); ptr = &ptr[match[1]]; } @@ -175,7 +180,7 @@ char* config_clean_string_list(char* str) } else { - skygw_log_write(LE,"[%s] Error: Memory allocation failed.",__FUNCTION__); + skygw_log_write(LE, "[%s] Error: Memory allocation failed.", __FUNCTION__); } return tmp; @@ -183,173 +188,192 @@ char* config_clean_string_list(char* str) /** * Config item handler for the ini file reader * - * @param userdata The config context element - * @param section The config file section - * @param name The Parameter name - * @param value The Parameter value + * @param userdata The config context element + * @param section The config file section + * @param name The Parameter name + * @param value The Parameter value * @return zero on error */ static int handler(void *userdata, const char *section, const char *name, const char *value) { -CONFIG_CONTEXT *cntxt = (CONFIG_CONTEXT *)userdata; -CONFIG_CONTEXT *ptr = cntxt; -CONFIG_PARAMETER *param, *p1; + CONFIG_CONTEXT *cntxt = (CONFIG_CONTEXT *)userdata; + CONFIG_CONTEXT *ptr = cntxt; + CONFIG_PARAMETER *param, *p1; - if (strcmp(section, "gateway") == 0 || strcasecmp(section, "MaxScale") == 0) - { - return handle_global_item(name, value); - } + if (strcmp(section, "gateway") == 0 || strcasecmp(section, "MaxScale") == 0) + { + return handle_global_item(name, value); + } - if (strcasecmp(section, "feedback") == 0) - { - return handle_feedback_item(name, value); - } + if (strcasecmp(section, "feedback") == 0) + { + return handle_feedback_item(name, value); + } - /* - * If we already have some parameters for the object - * add the parameters to that object. If not create - * a new object. - */ - while (ptr && strcmp(ptr->object, section) != 0) - ptr = ptr->next; - if (!ptr) - { - if ((ptr = (CONFIG_CONTEXT *)malloc(sizeof(CONFIG_CONTEXT))) == NULL) - return 0; - ptr->object = strdup(section); - ptr->parameters = NULL; - ptr->next = cntxt->next; - ptr->element = NULL; - cntxt->next = ptr; - } - /* Check to see if the parameter already exists for the section */ - p1 = ptr->parameters; - while (p1) - { - if (!strcmp(p1->name, name)) - { - char *tmp; - int paramlen = strlen(p1->value) + strlen(value) + 2; + /* + * If we already have some parameters for the object + * add the parameters to that object. If not create + * a new object. + */ + while (ptr && strcmp(ptr->object, section) != 0) + { + ptr = ptr->next; + } - if((tmp = realloc(p1->value,sizeof(char) * (paramlen))) == NULL) - { - skygw_log_write(LE,"[%s] Error: Memory allocation failed.",__FUNCTION__); - return 0; - } - strcat(tmp,","); - strcat(tmp,value); - if((p1->value = config_clean_string_list(tmp)) == NULL) - { - p1->value = tmp; - skygw_log_write(LE,"[%s] Error: Cleaning configuration parameter failed.",__FUNCTION__); - return 0; - } - free(tmp); - return 1; - } - p1 = p1->next; - } + if (!ptr) + { + if ((ptr = (CONFIG_CONTEXT *)malloc(sizeof(CONFIG_CONTEXT))) == NULL) + { + return 0; + } + ptr->object = strdup(section); + ptr->parameters = NULL; + ptr->next = cntxt->next; + ptr->element = NULL; + cntxt->next = ptr; + } + /* Check to see if the parameter already exists for the section */ + p1 = ptr->parameters; + while (p1) + { + if (!strcmp(p1->name, name)) + { + char *tmp; + int paramlen = strlen(p1->value) + strlen(value) + 2; - if ((param = (CONFIG_PARAMETER *)malloc(sizeof(CONFIG_PARAMETER))) == NULL) - return 0; - param->name = strdup(name); - param->value = strdup(value); - param->next = ptr->parameters; - ptr->parameters = param; + if ((tmp = realloc(p1->value, sizeof(char) * (paramlen))) == NULL) + { + skygw_log_write(LE, "[%s] Error: Memory allocation failed.", __FUNCTION__); + return 0; + } + strcat(tmp, ","); + strcat(tmp, value); + if ((p1->value = config_clean_string_list(tmp)) == NULL) + { + p1->value = tmp; + skygw_log_write(LE, "[%s] Error: Cleaning configuration parameter failed.", __FUNCTION__); + return 0; + } + free(tmp); + return 1; + } + p1 = p1->next; + } - return 1; + if ((param = (CONFIG_PARAMETER *)malloc(sizeof(CONFIG_PARAMETER))) == NULL) + { + return 0; + } + + param->name = strdup(name); + param->value = strdup(value); + param->next = ptr->parameters; + ptr->parameters = param; + + return 1; } /** * Load the configuration file for the MaxScale * - * @param file The filename of the configuration file + * @param file The filename of the configuration file * @return A zero return indicates a fatal error reading the configuration */ int config_load(char *file) { -CONFIG_CONTEXT config; -int rval, ini_rval; + CONFIG_CONTEXT config; + int rval, ini_rval; if (config_has_duplicate_sections(file)) { return 0; } - MYSQL *conn; - conn = mysql_init(NULL); - if (conn) { - if (mysql_real_connect(conn, NULL, NULL, NULL, NULL, 0, NULL, 0)) { - char *ptr,*tmp; - - tmp = (char *)mysql_get_server_info(conn); - unsigned int server_version = mysql_get_server_version(conn); - - if(version_string) - free(version_string); - - if((version_string = malloc(strlen(tmp) + strlen("5.5.5-") + 1)) == NULL) - return 0; - - if (server_version >= 100000) - { - strcpy(version_string,"5.5.5-"); - strcat(version_string,tmp); - } - else - { - strcpy(version_string,tmp); - } - - ptr = strstr(version_string, "-embedded"); - if (ptr) { - *ptr = '\0'; - } - - - } - mysql_close(conn); - } - - global_defaults(); - feedback_defaults(); - - config.object = ""; - config.next = NULL; - - if (( ini_rval = ini_parse(file, handler, &config)) != 0) + MYSQL *conn; + conn = mysql_init(NULL); + if (conn) + { + if (mysql_real_connect(conn, NULL, NULL, NULL, NULL, 0, NULL, 0)) { - char errorbuffer[1024 + 1]; + char *ptr, *tmp; - if (ini_rval > 0) - snprintf(errorbuffer, sizeof(errorbuffer), - "Error: Failed to parse configuration file. Error on line %d.", ini_rval); - else if(ini_rval == -1) - snprintf(errorbuffer, sizeof(errorbuffer), - "Error: Failed to parse configuration file. Failed to open file."); + tmp = (char *)mysql_get_server_info(conn); + unsigned int server_version = mysql_get_server_version(conn); + + if (version_string) + { + free(version_string); + } + + if ((version_string = malloc(strlen(tmp) + strlen("5.5.5-") + 1)) == NULL) + { + return 0; + } + + if (server_version >= 100000) + { + strcpy(version_string, "5.5.5-"); + strcat(version_string, tmp); + } else - snprintf(errorbuffer, sizeof(errorbuffer), - "Error: Failed to parse configuration file. Memory allocation failed."); + { + strcpy(version_string, tmp); + } - skygw_log_write(LE, errorbuffer); - return 0; + ptr = strstr(version_string, "-embedded"); + if (ptr) + { + *ptr = '\0'; + } + } + mysql_close(conn); + } + + global_defaults(); + feedback_defaults(); + + config.object = ""; + config.next = NULL; + + if ((ini_rval = ini_parse(file, handler, &config)) != 0) + { + char errorbuffer[1024 + 1]; + + if (ini_rval > 0) + { + snprintf(errorbuffer, sizeof(errorbuffer), + "Error: Failed to parse configuration file. Error on line %d.", ini_rval); + } + else if(ini_rval == -1) + { + snprintf(errorbuffer, sizeof(errorbuffer), + "Error: Failed to parse configuration file. Failed to open file."); + } + else + { + snprintf(errorbuffer, sizeof(errorbuffer), + "Error: Failed to parse configuration file. Memory allocation failed."); } - config_file = file; + skygw_log_write(LE, errorbuffer); + return 0; + } - check_config_objects(config.next); - rval = process_config_context(config.next); - free_config_context(config.next); + config_file = file; + + check_config_objects(config.next); + rval = process_config_context(config.next); + free_config_context(config.next); /** Start all monitors */ - if(rval) + if (rval) { monitorStartAll(); } - return rval; + return rval; } /** @@ -360,147 +384,129 @@ int rval, ini_rval; int config_reload() { -CONFIG_CONTEXT config; -int rval; + CONFIG_CONTEXT config; + int rval; - if (!config_file) - return 0; + if (!config_file) + { + return 0; + } if (config_has_duplicate_sections(config_file)) { return 0; } - if (gateway.version_string) - free(gateway.version_string); + if (gateway.version_string) + { + free(gateway.version_string); + } - global_defaults(); + global_defaults(); - config.object = ""; - config.next = NULL; + config.object = ""; + config.next = NULL; - if (ini_parse(config_file, handler, &config) < 0) - return 0; + if (ini_parse(config_file, handler, &config) < 0) + { + return 0; + } - rval = process_config_update(config.next); - free_config_context(config.next); + rval = process_config_update(config.next); + free_config_context(config.next); - return rval; + return rval; } /** * Process a configuration context and turn it into the set of object * we need. * - * @param context The configuration data + * @param context The configuration data * @return A zero result indicates a fatal error */ -static int +static int process_config_context(CONFIG_CONTEXT *context) { CONFIG_CONTEXT *obj; int error_count = 0; HASHTABLE* monitorhash; - if((monitorhash = hashtable_alloc(5,simple_str_hash,strcmp)) == NULL) + if ((monitorhash = hashtable_alloc(5, simple_str_hash, strcmp)) == NULL) { - skygw_log_write(LOGFILE_ERROR,"Error: Failed to allocate ,monitor configuration check hashtable."); + skygw_log_write(LOGFILE_ERROR, "Error: Failed to allocate, monitor configuration check hashtable."); return 0; } - hashtable_memory_fns(monitorhash,(HASHMEMORYFN)strdup,NULL,(HASHMEMORYFN)free,NULL); + hashtable_memory_fns(monitorhash, (HASHMEMORYFN)strdup, NULL, (HASHMEMORYFN)free, NULL); /** - * Process the data and create the services and servers defined - * in the data. - */ - obj = context; - while (obj) - { - char *type = config_get_value(obj->parameters, "type"); - if (type == NULL) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object '%s' has no type.", - obj->object))); - error_count++; - } - else if (!strcmp(type, "service")) - { - char *router = config_get_value(obj->parameters, - "router"); - if (router) - { - char* max_slave_conn_str; - char* max_slave_rlag_str; - char *user; - char *auth; - char *enable_root_user; - char *connection_timeout; - char *auth_all_servers; - char *optimize_wildcard; - char *strip_db_esc; - char *weightby; - char *version_string; - char *subservices; - char *ssl,*ssl_cert,*ssl_key,*ssl_ca_cert,*ssl_version; - char* ssl_cert_verify_depth; - bool is_rwsplit = false; - bool is_schemarouter = false; - char *allow_localhost_match_wildcard_host; + * Process the data and create the services and servers defined + * in the data. + */ + obj = context; + while (obj) + { + char *type = config_get_value(obj->parameters, "type"); + if (type == NULL) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Configuration object '%s' has no type.", + obj->object))); + error_count++; + } + else if (!strcmp(type, "service")) + { + char *router = config_get_value(obj->parameters, "router"); + if (router) + { + char* max_slave_conn_str; + char* max_slave_rlag_str; + char *user; + char *auth; + char *enable_root_user; + char *connection_timeout; + char *auth_all_servers; + char *optimize_wildcard; + char *strip_db_esc; + char *weightby; + char *version_string; + char *subservices; + char *ssl, *ssl_cert, *ssl_key, *ssl_ca_cert, *ssl_version; + char* ssl_cert_verify_depth; + bool is_rwsplit = false; + bool is_schemarouter = false; + char *allow_localhost_match_wildcard_host; - obj->element = service_alloc(obj->object, router); - user = config_get_value(obj->parameters, "user"); - auth = config_get_value(obj->parameters, "passwd"); - subservices = config_get_value(obj->parameters, "subservices"); - ssl = config_get_value(obj->parameters, "ssl"); - ssl_cert = config_get_value(obj->parameters, "ssl_cert"); - ssl_key = config_get_value(obj->parameters, "ssl_key"); - ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert"); - ssl_version = config_get_value(obj->parameters, "ssl_version"); - ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth"); - enable_root_user = config_get_value( - obj->parameters, - "enable_root_user"); + obj->element = service_alloc(obj->object, router); + user = config_get_value(obj->parameters, "user"); + auth = config_get_value(obj->parameters, "passwd"); + subservices = config_get_value(obj->parameters, "subservices"); + ssl = config_get_value(obj->parameters, "ssl"); + ssl_cert = config_get_value(obj->parameters, "ssl_cert"); + ssl_key = config_get_value(obj->parameters, "ssl_key"); + ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert"); + ssl_version = config_get_value(obj->parameters, "ssl_version"); + ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth"); + enable_root_user = config_get_value(obj->parameters, "enable_root_user"); + connection_timeout = config_get_value(obj->parameters, "connection_timeout"); + optimize_wildcard = config_get_value(obj->parameters, "optimize_wildcard"); + auth_all_servers = config_get_value(obj->parameters, "auth_all_servers"); + strip_db_esc = config_get_value(obj->parameters, "strip_db_esc"); + allow_localhost_match_wildcard_host = config_get_value(obj->parameters, + "localhost_match_wildcard_host"); + weightby = config_get_value(obj->parameters, "weightby"); - connection_timeout = - config_get_value( - obj->parameters, - "connection_timeout"); + version_string = config_get_value(obj->parameters, "version_string"); - optimize_wildcard = - config_get_value( - obj->parameters, - "optimize_wildcard"); - - auth_all_servers = - config_get_value( - obj->parameters, - "auth_all_servers"); - - strip_db_esc = - config_get_value( - obj->parameters, - "strip_db_esc"); - - allow_localhost_match_wildcard_host = - config_get_value(obj->parameters, - "localhost_match_wildcard_host"); - - weightby = config_get_value(obj->parameters, "weightby"); - - version_string = config_get_value(obj->parameters, - "version_string"); - - if(subservices) - { - service_set_param_value(obj->element, - obj->parameters, - subservices, - 1,STRING_TYPE); - } - char *log_auth_warnings = config_get_value(obj->parameters, - "log_auth_warnings"); + if (subservices) + { + service_set_param_value(obj->element, + obj->parameters, + subservices, + 1, STRING_TYPE); + } + char *log_auth_warnings = config_get_value(obj->parameters, "log_auth_warnings"); int truthval; if (log_auth_warnings && (truthval = config_truth_value(log_auth_warnings)) != -1) { @@ -508,963 +514,992 @@ process_config_context(CONFIG_CONTEXT *context) } CONFIG_PARAMETER* param; - if((param = config_get_param(obj->parameters, "ignore_databases"))) + if ((param = config_get_param(obj->parameters, "ignore_databases"))) { service_set_param_value(obj->element, param, param->value, 0, STRING_TYPE); } - if((param = config_get_param(obj->parameters, "ignore_databases_regex"))) + if ((param = config_get_param(obj->parameters, "ignore_databases_regex"))) { service_set_param_value(obj->element, param, param->value, 0, STRING_TYPE); } - /** flag for rwsplit-specific parameters */ - if (strncmp(router, "readwritesplit", strlen("readwritesplit")+1) == 0) - { - is_rwsplit = true; - } + /** flag for rwsplit-specific parameters */ + if (strncmp(router, "readwritesplit", strlen("readwritesplit")+1) == 0) + { + is_rwsplit = true; + } - allow_localhost_match_wildcard_host = - config_get_value(obj->parameters, "localhost_match_wildcard_host"); + allow_localhost_match_wildcard_host = + config_get_value(obj->parameters, "localhost_match_wildcard_host"); - if (obj->element == NULL) /*< if module load failed */ + if (obj->element == NULL) /*< if module load failed */ + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Reading configuration " + "for router service '%s' failed. " + "Router %s is not loaded.", + obj->object, + obj->object))); + obj = obj->next; + continue; /*< process next obj */ + } + + if (version_string) { + /** Add the 5.5.5- string to the start of the version string if + * the version string starts with "10.". + * This mimics MariaDB 10.0 replication which adds 5.5.5- for backwards compatibility. */ + if (strncmp(version_string, "10.", 3) == 0) + { + ((SERVICE *)(obj->element))->version_string = + malloc((strlen(version_string) + strlen("5.5.5-") + 1) * sizeof(char)); + strcpy(((SERVICE *)(obj->element))->version_string, "5.5.5-"); + strcat(((SERVICE *)(obj->element))->version_string, version_string); + } + else + { + ((SERVICE *)(obj->element))->version_string = strdup(version_string); + } + } + else + { + if (gateway.version_string) + ((SERVICE *)(obj->element))->version_string = strdup(gateway.version_string); + } + + max_slave_conn_str = config_get_value(obj->parameters, "max_slave_connections"); + max_slave_rlag_str = config_get_value(obj->parameters, "max_slave_replication_lag"); + + if (ssl) + { + if (ssl_cert == NULL) + { + error_count++; + skygw_log_write(LE, "Error: Server certificate missing for service '%s'." + "Please provide the path to the server certificate by adding " + "the ssl_cert= parameter", obj->object); + } + + if (ssl_ca_cert == NULL) + { + error_count++; + skygw_log_write(LE, "Error: CA Certificate missing for service '%s'." + "Please provide the path to the certificate authority " + "certificate by adding the ssl_ca_cert= parameter", + obj->object); + } + + if (ssl_key == NULL) + { + error_count++; + skygw_log_write(LE, "Error: Server private key missing for service '%s'. " + "Please provide the path to the server certificate key by " + "adding the ssl_key= parameter", + obj->object); + } + + if (access(ssl_ca_cert, F_OK) != 0) + { + skygw_log_write(LE, "Error: Certificate authority file for service '%s' " + "not found: %s", + obj->object, ssl_ca_cert); + error_count++; + } + + if (access(ssl_cert, F_OK) != 0) + { + skygw_log_write(LE, "Error: Server certificate file for service '%s' not found: %s", + obj->object, + ssl_cert); + error_count++; + } + + if (access(ssl_key, F_OK) != 0) + { + skygw_log_write(LE, "Error: Server private key file for service '%s' not found: %s", + obj->object, + ssl_key); + error_count++; + } + + if (error_count == 0) + { + if (serviceSetSSL(obj->element, ssl) != 0) + { + skygw_log_write(LE, "Error: Unknown parameter for service '%s': %s", + obj->object, ssl); + error_count++; + } + else + { + serviceSetCertificates(obj->element, ssl_cert, ssl_key, ssl_ca_cert); + if (ssl_version) + { + if (serviceSetSSLVersion(obj->element, ssl_version) != 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Reading configuration " - "for router service '%s' failed. " - "Router %s is not loaded.", - obj->object, - obj->object))); - obj = obj->next; - continue; /*< process next obj */ + skygw_log_write(LE, "Error: Unknown parameter value for " + "'ssl_version' for service '%s': %s", + obj->object, ssl_version); + error_count++; } - - if (version_string) { - - /** Add the 5.5.5- string to the start of the version string if - * the version string starts with "10.". - * This mimics MariaDB 10.0 replication which adds 5.5.5- for backwards compatibility. */ - if(strncmp(version_string,"10.",3) == 0) - { - ((SERVICE *)(obj->element))->version_string = malloc((strlen(version_string) + - strlen("5.5.5-") + 1) * sizeof(char)); - strcpy(((SERVICE *)(obj->element))->version_string,"5.5.5-"); - strcat(((SERVICE *)(obj->element))->version_string,version_string); - } - else - { - ((SERVICE *)(obj->element))->version_string = strdup(version_string); - } - } else { - if (gateway.version_string) - ((SERVICE *)(obj->element))->version_string = strdup(gateway.version_string); - } - max_slave_conn_str = - config_get_value(obj->parameters, - "max_slave_connections"); - - max_slave_rlag_str = - config_get_value(obj->parameters, - "max_slave_replication_lag"); - - if(ssl) - { - if(ssl_cert == NULL) - { - error_count++; - skygw_log_write(LE,"Error: Server certificate missing for service '%s'." - "Please provide the path to the server certificate by adding the ssl_cert= parameter", - obj->object); - } - if(ssl_ca_cert == NULL) - { - error_count++; - skygw_log_write(LE,"Error: CA Certificate missing for service '%s'." - "Please provide the path to the certificate authority certificate by adding the ssl_ca_cert= parameter", - obj->object); - } - if(ssl_key == NULL) - { - error_count++; - skygw_log_write(LE,"Error: Server private key missing for service '%s'. " - "Please provide the path to the server certificate key by adding the ssl_key= parameter" - ,obj->object); - } - - if(access(ssl_ca_cert,F_OK) != 0) - { - skygw_log_write(LE,"Error: Certificate authority file for service '%s' not found: %s", - obj->object, - ssl_ca_cert); - error_count++; - } - if(access(ssl_cert,F_OK) != 0) - { - skygw_log_write(LE,"Error: Server certificate file for service '%s' not found: %s", - obj->object, - ssl_cert); - error_count++; - } - if(access(ssl_key,F_OK) != 0) - { - skygw_log_write(LE,"Error: Server private key file for service '%s' not found: %s", - obj->object, - ssl_key); - error_count++; - } - - if(error_count == 0) - { - if(serviceSetSSL(obj->element,ssl) != 0) - { - skygw_log_write(LE,"Error: Unknown parameter for service '%s': %s",obj->object,ssl); - error_count++; - } - else - { - serviceSetCertificates(obj->element,ssl_cert,ssl_key,ssl_ca_cert); - if(ssl_version) - { - if(serviceSetSSLVersion(obj->element,ssl_version) != 0) - { - skygw_log_write(LE,"Error: Unknown parameter value for 'ssl_version' for service '%s': %s",obj->object,ssl_version); - error_count++; - } - } - if(ssl_cert_verify_depth) - { - if(serviceSetSSLVerifyDepth(obj->element,atoi(ssl_cert_verify_depth)) != 0) - { - skygw_log_write(LE,"Error: Invalid parameter value for 'ssl_cert_verify_depth' for service '%s': %s",obj->object,ssl_cert_verify_depth); - error_count++; - } - } - } - } - - } + } + if (ssl_cert_verify_depth) + { + if (serviceSetSSLVerifyDepth(obj->element, atoi(ssl_cert_verify_depth)) != 0) + { + skygw_log_write(LE, "Error: Invalid parameter value for " + "'ssl_cert_verify_depth' for service '%s': %s", + obj->object, ssl_cert_verify_depth); + error_count++; + } + } + } + } + } serviceSetRetryOnFailure(obj->element, config_get_value(obj->parameters, "retry_on_failure")); if (enable_root_user) - serviceEnableRootUser( - obj->element, - config_truth_value(enable_root_user)); + { + serviceEnableRootUser(obj->element, config_truth_value(enable_root_user)); + } - if (connection_timeout) - serviceSetTimeout( - obj->element, - atoi(connection_timeout)); + if (connection_timeout) + { + serviceSetTimeout(obj->element, atoi(connection_timeout)); + } - if(auth_all_servers) - serviceAuthAllServers(obj->element, - config_truth_value(auth_all_servers)); + if(auth_all_servers) + { + serviceAuthAllServers(obj->element, config_truth_value(auth_all_servers)); + } - if(optimize_wildcard) - serviceOptimizeWildcard(obj->element, - config_truth_value(optimize_wildcard)); + if(optimize_wildcard) + { + serviceOptimizeWildcard(obj->element, config_truth_value(optimize_wildcard)); + } - if(strip_db_esc) - serviceStripDbEsc(obj->element, - config_truth_value(strip_db_esc)); + if(strip_db_esc) + { + serviceStripDbEsc(obj->element, config_truth_value(strip_db_esc)); + } - if (weightby) - serviceWeightBy(obj->element, weightby); + if (weightby) + { + serviceWeightBy(obj->element, weightby); + } - if (allow_localhost_match_wildcard_host) - serviceEnableLocalhostMatchWildcardHost( - obj->element, - config_truth_value(allow_localhost_match_wildcard_host)); + if (allow_localhost_match_wildcard_host) + { + serviceEnableLocalhostMatchWildcardHost( + obj->element, + config_truth_value(allow_localhost_match_wildcard_host)); + } - if (!auth) - auth = config_get_value(obj->parameters, - "auth"); + if (!auth) + { + auth = config_get_value(obj->parameters, "auth"); + } - if (obj->element && user && auth) - { - serviceSetUser(obj->element, - user, - auth); - } - else if (user && auth == NULL) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Service '%s' has a " - "user defined but no " - "corresponding password.", - obj->object))); - } - /** Read, validate and set max_slave_connections */ - if (max_slave_conn_str != NULL) - { - CONFIG_PARAMETER* param; - bool succp; - - param = config_get_param(obj->parameters, - "max_slave_connections"); - - if (param == NULL) - { - succp = false; - } - else - { - succp = service_set_param_value( - obj->element, - param, - max_slave_conn_str, - COUNT_ATMOST, - (COUNT_TYPE|PERCENT_TYPE)); - } - - if (!succp) - { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is either for slave connection " - "count or\n\t%% for specifying the " - "maximum percentage of available the " - "slaves that will be connected.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); - } - } - /** Read, validate and set max_slave_replication_lag */ - if (max_slave_rlag_str != NULL) - { - CONFIG_PARAMETER* param; - bool succp; - - param = config_get_param( - obj->parameters, - "max_slave_replication_lag"); - - if (param == NULL) - { - succp = false; - } - else - { - succp = service_set_param_value( - obj->element, - param, - max_slave_rlag_str, - COUNT_ATMOST, - COUNT_TYPE); - } - - if (!succp) - { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is for maximum " - "slave replication lag.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); - } - } - /** Parameters for rwsplit router only */ - if (is_rwsplit) - { - CONFIG_PARAMETER* param; - char* use_sql_variables_in; - bool succp; - - use_sql_variables_in = - config_get_value(obj->parameters, - "use_sql_variables_in"); - - if (use_sql_variables_in != NULL) - { - param = config_get_param( - obj->parameters, - "use_sql_variables_in"); - - if (param == NULL) - { - succp = false; - } - else - { - succp = service_set_param_value(obj->element, - param, - use_sql_variables_in, - COUNT_NONE, - SQLVAR_TARGET_TYPE); - } - - if (!succp) - { - if(param){ - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is [master|all] for " - "use sql variables in.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); - }else{ - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : parameter was NULL"))); - - } - } - } - } /*< if (rw_split) */ - } /*< if (router) */ - else - { - obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No router defined for service " - "'%s'\n", - obj->object))); - error_count++; - } - } - else if (!strcmp(type, "server")) - { - char *address; - char *port; - char *protocol; - char *monuser; - char *monpw; + if (obj->element && user && auth) + { + serviceSetUser(obj->element, user, auth); + } + else if (user && auth == NULL) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Service '%s' has a " + "user defined but no " + "corresponding password.", + obj->object))); + } + /** Read, validate and set max_slave_connections */ + if (max_slave_conn_str != NULL) + { + CONFIG_PARAMETER* param; + bool succp; - address = config_get_value(obj->parameters, "address"); - port = config_get_value(obj->parameters, "port"); - protocol = config_get_value(obj->parameters, "protocol"); - monuser = config_get_value(obj->parameters, - "monitoruser"); - monpw = config_get_value(obj->parameters, "monitorpw"); + param = config_get_param(obj->parameters, "max_slave_connections"); - if (address && port && protocol) - { - obj->element = server_alloc(address, - protocol, - atoi(port)); - server_set_unique_name(obj->element, obj->object); - } - else - { - obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' is missing a " - "required configuration parameter. A " - "server must " - "have address, port and protocol " - "defined.", - obj->object))); - error_count++; - } - if (obj->element && monuser && monpw) - serverAddMonUser(obj->element, monuser, monpw); - else if (monuser && monpw == NULL) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' has a monitoruser" - "defined but no corresponding password.", - obj->object))); - } - if (obj->element) - { - SERVER *server = obj->element; - server->persistpoolmax = strtol(config_get_value_string(obj->parameters, "persistpoolmax"), NULL, 0); - server->persistmaxtime = strtol(config_get_value_string(obj->parameters, "persistmaxtime"), NULL, 0); - CONFIG_PARAMETER *params = obj->parameters; - while (params) - { - if (strcmp(params->name, "address") - && strcmp(params->name, "port") - && strcmp(params->name, - "protocol") - && strcmp(params->name, - "monitoruser") - && strcmp(params->name, - "monitorpw") - && strcmp(params->name, - "type") - && strcmp(params->name, - "persistpoolmax") - && strcmp(params->name, - "persistmaxtime") - ) - { - serverAddParameter(obj->element, - params->name, - params->value); - } - params = params->next; - } - } - } - else if (!strcmp(type, "filter")) - { - char *module = config_get_value(obj->parameters, - "module"); - char *options = config_get_value(obj->parameters, - "options"); + if (param == NULL) + { + succp = false; + } + else + { + succp = service_set_param_value( + obj->element, + param, + max_slave_conn_str, + COUNT_ATMOST, + (COUNT_TYPE|PERCENT_TYPE)); + } - if (module) - { - obj->element = filter_alloc(obj->object, module); - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Filter '%s' has no module " - "defined defined to load.", - obj->object))); - error_count++; - } - if (obj->element && options) - { - char *lasts; - char *s = strtok_r(options, ",", &lasts); - while (s) - { - filterAddOption(obj->element, s); - s = strtok_r(NULL, ",", &lasts); - } - } - if (obj->element) - { - CONFIG_PARAMETER *params = obj->parameters; - while (params) - { - if (strcmp(params->name, "module") - && strcmp(params->name, - "options")) - { - filterAddParameter(obj->element, - params->name, - params->value); - } - params = params->next; - } - } - } - obj = obj->next; - } + if (!succp) + { + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "* Warning : invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is either for slave connection " + "count or\n\t%% for specifying the " + "maximum percentage of available the " + "slaves that will be connected.", + ((SERVICE*)obj->element)->name, + param->name, + param->value))); + } + } + /** Read, validate and set max_slave_replication_lag */ + if (max_slave_rlag_str != NULL) + { + CONFIG_PARAMETER* param; + bool succp; - /* - * Now we have the services we can add the servers to the services - * add the protocols to the services - */ - obj = context; - while (obj) - { - char *type = config_get_value(obj->parameters, "type"); - if (type == NULL) - ; - else if (!strcmp(type, "service")) - { - char *servers; - char *roptions; - char *router; - char *filters = config_get_value(obj->parameters, - "filters"); - servers = config_get_value(obj->parameters, "servers"); - roptions = config_get_value(obj->parameters, - "router_options"); - router = config_get_value(obj->parameters, "router"); - if (servers && obj->element) - { - char *lasts; - char *s = strtok_r(servers, ",", &lasts); - while (s) - { - CONFIG_CONTEXT *obj1 = context; - int found = 0; - while (obj1) - { - if (strcmp(trim(s), obj1->object) == 0 && - obj->element && obj1->element) - { - found = 1; - serviceAddBackend( - obj->element, - obj1->element); - } - obj1 = obj1->next; - } - if (!found) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " - "server '%s' that is " - "configured as part of " - "service '%s'.", - s, obj->object))); - } - s = strtok_r(NULL, ",", &lasts); - } - } - else if (servers == NULL && !isInternalService(router)) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning: The service '%s' is missing a " - "definition of the servers that provide " - "the service.", - obj->object))); - } - if (roptions && obj->element) - { - char *lasts; - char *s = strtok_r(roptions, ",", &lasts); - while (s) - { - serviceAddRouterOption(obj->element, s); - s = strtok_r(NULL, ",", &lasts); - } - } - if (filters && obj->element) - { - serviceSetFilters(obj->element, filters); - } - } - else if (!strcmp(type, "listener")) - { - char *service; - char *address; - char *port; - char *protocol; - char *socket; - struct sockaddr_in serv_addr; + param = config_get_param( + obj->parameters, + "max_slave_replication_lag"); - service = config_get_value(obj->parameters, "service"); - port = config_get_value(obj->parameters, "port"); - address = config_get_value(obj->parameters, "address"); - protocol = config_get_value(obj->parameters, "protocol"); - socket = config_get_value(obj->parameters, "socket"); + if (param == NULL) + { + succp = false; + } + else + { + succp = service_set_param_value( + obj->element, + param, + max_slave_rlag_str, + COUNT_ATMOST, + COUNT_TYPE); + } - /* if id is not set, do it now */ - if (gateway.id == 0) { - setipaddress(&serv_addr.sin_addr, (address == NULL) ? "0.0.0.0" : address); - gateway.id = (unsigned long) (serv_addr.sin_addr.s_addr + (port != NULL ? atoi(port) : 0 + getpid())); - } + if (!succp) + { + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "* Warning : invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is for maximum " + "slave replication lag.", + ((SERVICE*)obj->element)->name, + param->name, + param->value))); + } + } + /** Parameters for rwsplit router only */ + if (is_rwsplit) + { + CONFIG_PARAMETER* param; + char* use_sql_variables_in; + bool succp; - if(service && protocol && (socket || port)) - { - if (socket) - { - CONFIG_CONTEXT *ptr = context; - while (ptr && strcmp(ptr->object, service) != 0) - ptr = ptr->next; - if (ptr && ptr->element) - { - serviceAddProtocol(ptr->element, - protocol, - socket, - 0); - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s', " - "service '%s' not found. " - "Listener will not execute for socket %s.", - obj->object, service, socket))); - error_count++; - } - } + use_sql_variables_in = + config_get_value(obj->parameters, "use_sql_variables_in"); - if (port) - { - CONFIG_CONTEXT *ptr = context; - while (ptr && strcmp(ptr->object, service) != 0) - ptr = ptr->next; - if (ptr && ptr->element) - { - serviceAddProtocol(ptr->element, - protocol, - address, - atoi(port)); - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s', " - "service '%s' not found. " - "Listener will not execute.", - obj->object, service))); - error_count++; - } - } - } - else - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s' is missing a " - "required " - "parameter. A Listener must have a " - "service, port and protocol defined.", - obj->object))); - error_count++; - } - } - else if (!strcmp(type, "monitor")) - { - char *module; - char *servers; - char *user; - char *passwd; - unsigned long interval = 0; - int connect_timeout = 0; - int read_timeout = 0; - int write_timeout = 0; + if (use_sql_variables_in != NULL) + { + param = config_get_param(obj->parameters, + "use_sql_variables_in"); - module = config_get_value(obj->parameters, "module"); - servers = config_get_value(obj->parameters, "servers"); - user = config_get_value(obj->parameters, "user"); - passwd = config_get_value(obj->parameters, "passwd"); - if (config_get_value(obj->parameters, "monitor_interval")) { - interval = strtoul(config_get_value(obj->parameters, "monitor_interval"), NULL, 10); - } + if (param == NULL) + { + succp = false; + } + else + { + succp = service_set_param_value(obj->element, + param, + use_sql_variables_in, + COUNT_NONE, + SQLVAR_TARGET_TYPE); + } - if (config_get_value(obj->parameters, "backend_connect_timeout")) { - connect_timeout = atoi(config_get_value(obj->parameters, "backend_connect_timeout")); - } - if (config_get_value(obj->parameters, "backend_read_timeout")) { - read_timeout = atoi(config_get_value(obj->parameters, "backend_read_timeout")); - } - if (config_get_value(obj->parameters, "backend_write_timeout")) { - write_timeout = atoi(config_get_value(obj->parameters, "backend_write_timeout")); - } - - if (module) - { - obj->element = monitor_alloc(obj->object, module); - if (servers && obj->element) - { - char *s, *lasts; + if (!succp) + { + if(param) + { + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "* Warning : invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is [master|all] for " + "use sql variables in.", + ((SERVICE*)obj->element)->name, + param->name, + param->value))); + } + else + { + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "Error : parameter was NULL"))); + } + } + } + } /*< if (rw_split) */ + } /*< if (router) */ + else + { + obj->element = NULL; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : No router defined for service " + "'%s'\n", + obj->object))); + error_count++; + } + } + else if (!strcmp(type, "server")) + { + char *address; + char *port; + char *protocol; + char *monuser; + char *monpw; - /* if id is not set, compute it now with pid only */ - if (gateway.id == 0) { - gateway.id = getpid(); - } + address = config_get_value(obj->parameters, "address"); + port = config_get_value(obj->parameters, "port"); + protocol = config_get_value(obj->parameters, "protocol"); + monuser = config_get_value(obj->parameters, "monitoruser"); + monpw = config_get_value(obj->parameters, "monitorpw"); + + if (address && port && protocol) + { + obj->element = server_alloc(address, + protocol, + atoi(port)); + server_set_unique_name(obj->element, obj->object); + } + else + { + obj->element = NULL; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Server '%s' is missing a " + "required configuration parameter. A " + "server must " + "have address, port and protocol " + "defined.", + obj->object))); + error_count++; + } + + if (obj->element && monuser && monpw) + { + serverAddMonUser(obj->element, monuser, monpw); + } + else if (monuser && monpw == NULL) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Server '%s' has a monitoruser" + "defined but no corresponding password.", + obj->object))); + } + + if (obj->element) + { + SERVER *server = obj->element; + server->persistpoolmax = strtol(config_get_value_string(obj->parameters, + "persistpoolmax"), NULL, 0); + server->persistmaxtime = strtol(config_get_value_string(obj->parameters, + "persistmaxtime"), NULL, 0); + CONFIG_PARAMETER *params = obj->parameters; + + while (params) + { + if (strcmp(params->name, "address") + && strcmp(params->name, "port") + && strcmp(params->name, "protocol") + && strcmp(params->name, "monitoruser") + && strcmp(params->name, "monitorpw") + && strcmp(params->name, "type") + && strcmp(params->name, "persistpoolmax") + && strcmp(params->name, "persistmaxtime")) + { + serverAddParameter(obj->element, params->name, params->value); + } + params = params->next; + } + } + } + else if (!strcmp(type, "filter")) + { + char *module = config_get_value(obj->parameters, "module"); + char *options = config_get_value(obj->parameters, "options"); + + if (module) + { + obj->element = filter_alloc(obj->object, module); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Filter '%s' has no module " + "defined defined to load.", + obj->object))); + error_count++; + } + + if (obj->element && options) + { + char *lasts; + char *s = strtok_r(options, ",", &lasts); + while (s) + { + filterAddOption(obj->element, s); + s = strtok_r(NULL, ",", &lasts); + } + } + + if (obj->element) + { + CONFIG_PARAMETER *params = obj->parameters; + while (params) + { + if (strcmp(params->name, "module") && strcmp(params->name, "options")) + { + filterAddParameter(obj->element, + params->name, + params->value); + } + params = params->next; + } + } + } + obj = obj->next; + } + + /* + * Now we have the services we can add the servers to the services + * add the protocols to the services + */ + obj = context; + while (obj) + { + char *type = config_get_value(obj->parameters, "type"); + if (type == NULL) + { + ; + } + else if (!strcmp(type, "service")) + { + char *servers; + char *roptions; + char *router; + char *filters = config_get_value(obj->parameters, "filters"); + servers = config_get_value(obj->parameters, "servers"); + roptions = config_get_value(obj->parameters, "router_options"); + router = config_get_value(obj->parameters, "router"); + if (servers && obj->element) + { + char *lasts; + char *s = strtok_r(servers, ",", &lasts); + while (s) + { + CONFIG_CONTEXT *obj1 = context; + int found = 0; + while (obj1) + { + if (strcmp(trim(s), obj1->object) == 0 && obj->element && obj1->element) + { + found = 1; + serviceAddBackend(obj->element, obj1->element); + } + obj1 = obj1->next; + } + + if (!found) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Unable to find " + "server '%s' that is " + "configured as part of " + "service '%s'.", + s, obj->object))); + } + s = strtok_r(NULL, ",", &lasts); + } + } + else if (servers == NULL && !isInternalService(router)) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Warning: The service '%s' is missing a " + "definition of the servers that provide " + "the service.", + obj->object))); + } + + if (roptions && obj->element) + { + char *lasts; + char *s = strtok_r(roptions, ",", &lasts); + while (s) + { + serviceAddRouterOption(obj->element, s); + s = strtok_r(NULL, ",", &lasts); + } + } + + if (filters && obj->element) + { + serviceSetFilters(obj->element, filters); + } + } + else if (!strcmp(type, "listener")) + { + char *service; + char *address; + char *port; + char *protocol; + char *socket; + struct sockaddr_in serv_addr; + + service = config_get_value(obj->parameters, "service"); + port = config_get_value(obj->parameters, "port"); + address = config_get_value(obj->parameters, "address"); + protocol = config_get_value(obj->parameters, "protocol"); + socket = config_get_value(obj->parameters, "socket"); + + /* if id is not set, do it now */ + if (gateway.id == 0) + { + setipaddress(&serv_addr.sin_addr, (address == NULL) ? "0.0.0.0" : address); + gateway.id = (unsigned long) (serv_addr.sin_addr.s_addr + + (port != NULL ? atoi(port) : 0 + getpid())); + } + + if (service && protocol && (socket || port)) + { + if (socket) + { + CONFIG_CONTEXT *ptr = context; + while (ptr && strcmp(ptr->object, service) != 0) + { + ptr = ptr->next; + } + + if (ptr && ptr->element) + { + serviceAddProtocol(ptr->element, protocol, socket, 0); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Listener '%s', " + "service '%s' not found. " + "Listener will not execute for socket %s.", + obj->object, service, socket))); + error_count++; + } + } + + if (port) + { + CONFIG_CONTEXT *ptr = context; + while (ptr && strcmp(ptr->object, service) != 0) + { + ptr = ptr->next; + } + + if (ptr && ptr->element) + { + serviceAddProtocol(ptr->element, protocol, address, atoi(port)); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Listener '%s', " + "service '%s' not found. " + "Listener will not execute.", + obj->object, service))); + error_count++; + } + } + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Listener '%s' is missing a " + "required " + "parameter. A Listener must have a " + "service, port and protocol defined.", + obj->object))); + error_count++; + } + } + else if (!strcmp(type, "monitor")) + { + char *module; + char *servers; + char *user; + char *passwd; + unsigned long interval = 0; + int connect_timeout = 0; + int read_timeout = 0; + int write_timeout = 0; + + module = config_get_value(obj->parameters, "module"); + servers = config_get_value(obj->parameters, "servers"); + user = config_get_value(obj->parameters, "user"); + passwd = config_get_value(obj->parameters, "passwd"); + if (config_get_value(obj->parameters, "monitor_interval")) + { + interval = strtoul(config_get_value(obj->parameters, "monitor_interval"), NULL, 10); + } + + if (config_get_value(obj->parameters, "backend_connect_timeout")) + { + connect_timeout = atoi(config_get_value(obj->parameters, "backend_connect_timeout")); + } + if (config_get_value(obj->parameters, "backend_read_timeout")) + { + read_timeout = atoi(config_get_value(obj->parameters, "backend_read_timeout")); + } + if (config_get_value(obj->parameters, "backend_write_timeout")) + { + write_timeout = atoi(config_get_value(obj->parameters, "backend_write_timeout")); + } + + if (module) + { + obj->element = monitor_alloc(obj->object, module); + if (servers && obj->element) + { + char *s, *lasts; + + /* if id is not set, compute it now with pid only */ + if (gateway.id == 0) + { + gateway.id = getpid(); + } monitorAddParameters(obj->element, obj->parameters); - /* set monitor interval */ - if (interval > 0) - monitorSetInterval(obj->element, interval); - else - skygw_log_write(LOGFILE_ERROR,"Warning: Monitor '%s' " - "missing monitor_interval parameter, " - "default value of 10000 miliseconds.",obj->object); + /* set monitor interval */ + if (interval > 0) + { + monitorSetInterval(obj->element, interval); + } + else + { + skygw_log_write(LOGFILE_ERROR, "Warning: Monitor '%s' " + "missing monitor_interval parameter, " + "default value of 10000 miliseconds.", obj->object); + } - /* set timeouts */ - if (connect_timeout > 0) - monitorSetNetworkTimeout(obj->element, MONITOR_CONNECT_TIMEOUT, connect_timeout); - if (read_timeout > 0) - monitorSetNetworkTimeout(obj->element, MONITOR_READ_TIMEOUT, read_timeout); - if (write_timeout > 0) - monitorSetNetworkTimeout(obj->element, MONITOR_WRITE_TIMEOUT, write_timeout); + /* set timeouts */ + if (connect_timeout > 0) + { + monitorSetNetworkTimeout(obj->element, MONITOR_CONNECT_TIMEOUT, connect_timeout); + } + if (read_timeout > 0) + { + monitorSetNetworkTimeout(obj->element, MONITOR_READ_TIMEOUT, read_timeout); + } + if (write_timeout > 0) + { + monitorSetNetworkTimeout(obj->element, MONITOR_WRITE_TIMEOUT, write_timeout); + } - /* get the servers to monitor */ - s = strtok_r(servers, ",", &lasts); - while (s) - { - CONFIG_CONTEXT *obj1 = context; - int found = 0; - while (obj1) - { - if (strcmp(trim(s), obj1->object) == 0 && - obj->element && obj1->element) - { - found = 1; - if(hashtable_add(monitorhash,obj1->object,"") == 0) - { - skygw_log_write(LOGFILE_ERROR, - "Warning: Multiple monitors are monitoring server [%s]. " - "This will cause undefined behavior.", - obj1->object); - } - monitorAddServer( - obj->element, - obj1->element); - } - obj1 = obj1->next; - } - if (!found) - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " - "server '%s' that is " - "configured in the " - "monitor '%s'.", - s, obj->object))); + /* get the servers to monitor */ + s = strtok_r(servers, ",", &lasts); + while (s) + { + CONFIG_CONTEXT *obj1 = context; + int found = 0; + while (obj1) + { + if (strcmp(trim(s), obj1->object) == 0 && obj->element && obj1->element) + { + found = 1; + if (hashtable_add(monitorhash, obj1->object, "") == 0) + { + skygw_log_write(LOGFILE_ERROR, + "Warning: Multiple monitors are monitoring server [%s]. " + "This will cause undefined behavior.", + obj1->object); + } + monitorAddServer(obj->element, obj1->element); + } + obj1 = obj1->next; + } + if (!found) + { + LOGIF(LE, + (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Unable to find " + "server '%s' that is " + "configured in the " + "monitor '%s'.", + s, obj->object))); + } - s = strtok_r(NULL, ",", &lasts); - } - } - if (obj->element && user && passwd) - { - monitorAddUser(obj->element, - user, - passwd); - check_monitor_permissions(obj->element); - } - else if (obj->element && user) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, "Error: " - "Monitor '%s' defines a " - "username with no password.", - obj->object))); - error_count++; - } - } - else - { - obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor '%s' is missing a " - "require module parameter.", - obj->object))); - error_count++; - } - } - else if (strcmp(type, "server") != 0 - && strcmp(type, "filter") != 0) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object '%s' has an " - "invalid type specified.", - obj->object))); - error_count++; - } + s = strtok_r(NULL, ",", &lasts); + } + } - obj = obj->next; - } /*< while */ + if (obj->element && user && passwd) + { + monitorAddUser(obj->element, user, passwd); + check_monitor_permissions(obj->element); + } + else if (obj->element && user) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, "Error: " + "Monitor '%s' defines a " + "username with no password.", + obj->object))); + error_count++; + } + } + else + { + obj->element = NULL; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Monitor '%s' is missing a " + "require module parameter.", + obj->object))); + error_count++; + } + } + else if (strcmp(type, "server") != 0 && strcmp(type, "filter") != 0) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Configuration object '%s' has an " + "invalid type specified.", + obj->object))); + error_count++; + } - /** TODO: consistency check function */ + obj = obj->next; + } /*< while */ - hashtable_free(monitorhash); - /** - * error_count += consistency_checks(); - */ + /** TODO: consistency check function */ - if (error_count) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : %d errors where encountered processing the " - "configuration file '%s'.", - error_count, - config_file))); - return 0; - } - return 1; + hashtable_free(monitorhash); + /** + * error_count += consistency_checks(); + */ + + if (error_count) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : %d errors where encountered processing the " + "configuration file '%s'.", + error_count, + config_file))); + return 0; + } + + return 1; } /** * Get the value of a config parameter * - * @param params The linked list of config parameters - * @param name The parameter to return + * @param params The linked list of config parameters + * @param name The parameter to return * @return the parameter value or NULL if not found */ static char * config_get_value(CONFIG_PARAMETER *params, const char *name) { - while (params) - { - if (!strcmp(params->name, name)) - return params->value; - params = params->next; - } - return NULL; + while (params) + { + if (!strcmp(params->name, name)) + { + return params->value; + } + + params = params->next; + } + return NULL; } /** * Get the value of a config parameter as a string * - * @param params The linked list of config parameters - * @param name The parameter to return + * @param params The linked list of config parameters + * @param name The parameter to return * @return the parameter value or null string if not found */ static const char * config_get_value_string(CONFIG_PARAMETER *params, const char *name) { - while (params) - { - if (!strcmp(params->name, name)) - return (const char *)params->value; - params = params->next; - } - return ""; + while (params) + { + if (!strcmp(params->name, name)) + { + return (const char *)params->value; + } + + params = params->next; + } + return ""; } CONFIG_PARAMETER* config_get_param( - CONFIG_PARAMETER* params, - const char* name) + CONFIG_PARAMETER* params, + const char* name) { - while (params) + while (params) + { + if (!strcmp(params->name, name)) { - if (!strcmp(params->name, name)) - return params; - params = params->next; + return params; } - return NULL; + + params = params->next; + } + return NULL; } config_param_type_t config_get_paramtype( - CONFIG_PARAMETER* param) + CONFIG_PARAMETER* param) { - return param->qfd_param_type; + return param->qfd_param_type; } bool config_get_valint( - int* val, - CONFIG_PARAMETER* param, - const char* name, /*< if NULL examine current param only */ - config_param_type_t ptype) -{ - bool succp = false;; - - ss_dassert((ptype == COUNT_TYPE || ptype == PERCENT_TYPE) && param != NULL); - - while (param) - { - if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) - { - switch (ptype) { - case COUNT_TYPE: - *val = param->qfd.valcount; - succp = true; - goto return_succp; - - case PERCENT_TYPE: - *val = param->qfd.valpercent; - succp =true; - goto return_succp; + int* val, + CONFIG_PARAMETER* param, + const char* name, /*< if NULL examine current param only */ + config_param_type_t ptype) +{ + bool succp = false;; - default: - goto return_succp; - } - } - param = param->next; + ss_dassert((ptype == COUNT_TYPE || ptype == PERCENT_TYPE) && param != NULL); + + while (param) + { + if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) + { + switch (ptype) { + case COUNT_TYPE: + *val = param->qfd.valcount; + succp = true; + goto return_succp; + + case PERCENT_TYPE: + *val = param->qfd.valpercent; + succp =true; + goto return_succp; + + default: + goto return_succp; + } } + param = param->next; + } return_succp: - return succp; + return succp; } bool config_get_valbool( - bool* val, - CONFIG_PARAMETER* param, - const char* name, - config_param_type_t ptype) + bool* val, + CONFIG_PARAMETER* param, + const char* name, + config_param_type_t ptype) { - bool succp; - - ss_dassert(ptype == BOOL_TYPE); - ss_dassert(param != NULL); - - if (ptype != BOOL_TYPE || param == NULL) - { - succp = false; - goto return_succp; - } - - while (param) - { - if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) - { - *val = param->qfd.valbool; - succp = true; - goto return_succp; - } - param = param->next; - } - succp = false; - + bool succp; + + ss_dassert(ptype == BOOL_TYPE); + ss_dassert(param != NULL); + + if (ptype != BOOL_TYPE || param == NULL) + { + succp = false; + goto return_succp; + } + + while (param) + { + if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) + { + *val = param->qfd.valbool; + succp = true; + goto return_succp; + } + param = param->next; + } + succp = false; + return_succp: - return succp; - + return succp; } bool config_get_valtarget( - target_t* val, - CONFIG_PARAMETER* param, - const char* name, - config_param_type_t ptype) + target_t* val, + CONFIG_PARAMETER* param, + const char* name, + config_param_type_t ptype) { - bool succp; - - ss_dassert(ptype == SQLVAR_TARGET_TYPE); - ss_dassert(param != NULL); - - if (ptype != SQLVAR_TARGET_TYPE || param == NULL) - { - succp = false; - goto return_succp; - } - - while (param) - { - if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) - { - *val = param->qfd.valtarget; - succp = true; - goto return_succp; - } - param = param->next; - } - succp = false; - + bool succp; + + ss_dassert(ptype == SQLVAR_TARGET_TYPE); + ss_dassert(param != NULL); + + if (ptype != SQLVAR_TARGET_TYPE || param == NULL) + { + succp = false; + goto return_succp; + } + + while (param) + { + if (name == NULL || !strncmp(param->name, name, MAX_PARAM_LEN)) + { + *val = param->qfd.valtarget; + succp = true; + goto return_succp; + } + param = param->next; + } + succp = false; + return_succp: - return succp; - + return succp; } CONFIG_PARAMETER* config_clone_param( - CONFIG_PARAMETER* param) + CONFIG_PARAMETER* param) { - CONFIG_PARAMETER* p2; - - p2 = (CONFIG_PARAMETER*) malloc(sizeof(CONFIG_PARAMETER)); - - if (p2 == NULL) - { - goto return_p2; - } - memcpy(p2, param, sizeof(CONFIG_PARAMETER)); - p2->name = strndup(param->name, MAX_PARAM_LEN); - p2->value = strndup(param->value, MAX_PARAM_LEN); - - if (param->qfd_param_type == STRING_TYPE) - { - p2->qfd.valstr = strndup(param->qfd.valstr, MAX_PARAM_LEN); - } - + CONFIG_PARAMETER* p2; + + p2 = (CONFIG_PARAMETER*) malloc(sizeof(CONFIG_PARAMETER)); + + if (p2 == NULL) + { + goto return_p2; + } + memcpy(p2, param, sizeof(CONFIG_PARAMETER)); + p2->name = strndup(param->name, MAX_PARAM_LEN); + p2->value = strndup(param->value, MAX_PARAM_LEN); + + if (param->qfd_param_type == STRING_TYPE) + { + p2->qfd.valstr = strndup(param->qfd.valstr, MAX_PARAM_LEN); + } + return_p2: - return p2; + return p2; } /** @@ -1486,22 +1521,22 @@ void free_config_parameter(CONFIG_PARAMETER* p1) /** * Free a config tree * - * @param context The configuration data + * @param context The configuration data */ -static void +static void free_config_context(CONFIG_CONTEXT *context) { -CONFIG_CONTEXT *obj; -CONFIG_PARAMETER *p1, *p2; + CONFIG_CONTEXT *obj; + CONFIG_PARAMETER *p1, *p2; - while (context) - { - free(context->object); - free_config_parameter(context->parameters); - obj = context->next; - free(context); - context = obj; - } + while (context) + { + free(context->object); + free_config_parameter(context->parameters); + obj = context->next; + free(context); + context = obj; + } } /** @@ -1512,7 +1547,7 @@ CONFIG_PARAMETER *p1, *p2; int config_threadcount() { - return gateway.n_threads; + return gateway.n_threads; } /** @@ -1524,7 +1559,7 @@ config_threadcount() unsigned int config_nbpolls() { - return gateway.n_nbpoll; + return gateway.n_nbpoll; } /** @@ -1536,7 +1571,7 @@ config_nbpolls() unsigned int config_pollsleep() { - return gateway.pollsleep; + return gateway.pollsleep; } /** @@ -1547,133 +1582,150 @@ config_pollsleep() FEEDBACK_CONF * config_get_feedback_data() { - return &feedback; + return &feedback; } -static struct { - char *logname; - logfile_id_t logfile; +static struct +{ + char *logname; + logfile_id_t logfile; } lognames[] = { - { "log_messages", LOGFILE_MESSAGE }, - { "log_trace", LOGFILE_TRACE }, - { "log_debug", LOGFILE_DEBUG }, - { NULL, 0 } + { "log_messages", LOGFILE_MESSAGE }, + { "log_trace", LOGFILE_TRACE }, + { "log_debug", LOGFILE_DEBUG }, + { NULL, 0 } }; /** * Configuration handler for items in the global [MaxScale] section * - * @param name The item name - * @param value The item value + * @param name The item name + * @param value The item value * @return 0 on error */ -static int +static int handle_global_item(const char *name, const char *value) { -int i; - if (strcmp(name, "threads") == 0) - { - int thrcount = atoi(value); - if (thrcount > 0) - { - gateway.n_threads = thrcount; - } - else - { - skygw_log_write(LE, "Warning: Invalid value for 'threads': %s.", value); - return 0; - } - } - else if (strcmp(name, "non_blocking_polls") == 0) - { - gateway.n_nbpoll = atoi(value); - } - else if (strcmp(name, "poll_sleep") == 0) - { - gateway.pollsleep = atoi(value); + int i; + if (strcmp(name, "threads") == 0) + { + int thrcount = atoi(value); + if (thrcount > 0) + { + gateway.n_threads = thrcount; } - else if (strcmp(name, "ms_timestamp") == 0) - { - skygw_set_highp(config_truth_value((char*)value)); - } + else + { + skygw_log_write(LE, "Warning: Invalid value for 'threads': %s.", value); + return 0; + } + } + else if (strcmp(name, "non_blocking_polls") == 0) + { + gateway.n_nbpoll = atoi(value); + } + else if (strcmp(name, "poll_sleep") == 0) + { + gateway.pollsleep = atoi(value); + } + else if (strcmp(name, "ms_timestamp") == 0) + { + skygw_set_highp(config_truth_value((char*)value)); + } else if (strcmp(name, "auth_connect_timeout") == 0) - { + { char* endptr; - int intval = strtol(value, &endptr, 0); - if(*endptr == '\0' && intval > 0) + int intval = strtol(value, &endptr, 0); + if (*endptr == '\0' && intval > 0) + { gateway.auth_conn_timeout = intval; - else - skygw_log_write(LE, "Invalid timeout value for 'auth_connect_timeout': %s", value); - } - else if (strcmp(name, "auth_read_timeout") == 0) - { - char* endptr; - int intval = strtol(value, &endptr, 0); - if(*endptr == '\0' && intval > 0) - gateway.auth_read_timeout = intval; - else - skygw_log_write(LE, "Invalid timeout value for 'auth_read_timeout': %s", value); - } - else if (strcmp(name, "auth_write_timeout") == 0) - { - char* endptr; - int intval = strtol(value, &endptr, 0); - if(*endptr == '\0' && intval > 0) - gateway.auth_write_timeout = intval; - else - skygw_log_write(LE, "Invalid timeout value for 'auth_write_timeout': %s", value); - } - else - { - for (i = 0; lognames[i].logname; i++) - { - if (strcasecmp(name, lognames[i].logname) == 0) - { - if (config_truth_value((char*)value)) - skygw_log_enable(lognames[i].logfile); - else - skygw_log_disable(lognames[i].logfile); - } - } } - return 1; + else + { + skygw_log_write(LE, "Invalid timeout value for 'auth_connect_timeout': %s", value); + } + } + else if (strcmp(name, "auth_read_timeout") == 0) + { + char* endptr; + int intval = strtol(value, &endptr, 0); + if (*endptr == '\0' && intval > 0) + { + gateway.auth_read_timeout = intval; + } + else + { + skygw_log_write(LE, "Invalid timeout value for 'auth_read_timeout': %s", value); + } + } + else if (strcmp(name, "auth_write_timeout") == 0) + { + char* endptr; + int intval = strtol(value, &endptr, 0); + if (*endptr == '\0' && intval > 0) + { + gateway.auth_write_timeout = intval; + } + else + { + skygw_log_write(LE, "Invalid timeout value for 'auth_write_timeout': %s", value); + } + } + else + { + for (i = 0; lognames[i].logname; i++) + { + if (strcasecmp(name, lognames[i].logname) == 0) + { + if (config_truth_value((char*)value)) + { + skygw_log_enable(lognames[i].logfile); + } + else + { + skygw_log_disable(lognames[i].logfile); + } + } + } + } + return 1; } /** * Configuration handler for items in the feedback [feedback] section * - * @param name The item name - * @param value The item value + * @param name The item name + * @param value The item value * @return 0 on error */ -static int +static int handle_feedback_item(const char *name, const char *value) { -int i; - if (strcmp(name, "feedback_enable") == 0) - { - feedback.feedback_enable = config_truth_value((char *)value); - } - else if (strcmp(name, "feedback_user_info") == 0) - { - feedback.feedback_user_info = strdup(value); - } - else if (strcmp(name, "feedback_url") == 0) - { - feedback.feedback_url = strdup(value); - } - if (strcmp(name, "feedback_timeout") == 0) - { - feedback.feedback_timeout = atoi(value); - } - if (strcmp(name, "feedback_connect_timeout") == 0) - { - feedback.feedback_connect_timeout = atoi(value); - } - if (strcmp(name, "feedback_frequency") == 0) - { - feedback.feedback_frequency = atoi(value); - } - return 1; + int i; + if (strcmp(name, "feedback_enable") == 0) + { + feedback.feedback_enable = config_truth_value((char *)value); + } + else if (strcmp(name, "feedback_user_info") == 0) + { + feedback.feedback_user_info = strdup(value); + } + else if (strcmp(name, "feedback_url") == 0) + { + feedback.feedback_url = strdup(value); + } + if (strcmp(name, "feedback_timeout") == 0) + { + feedback.feedback_timeout = atoi(value); + } + if (strcmp(name, "feedback_connect_timeout") == 0) + { + feedback.feedback_connect_timeout = atoi(value); + } + if (strcmp(name, "feedback_frequency") == 0) + { + feedback.feedback_frequency = atoi(value); + } + return 1; } /** @@ -1682,37 +1734,50 @@ int i; static void global_defaults() { - uint8_t mac_addr[6]=""; - struct utsname uname_data; - gateway.n_threads = get_processor_count(); - gateway.n_nbpoll = DEFAULT_NBPOLLS; - gateway.pollsleep = DEFAULT_POLLSLEEP; + uint8_t mac_addr[6]=""; + struct utsname uname_data; + gateway.n_threads = get_processor_count(); + gateway.n_nbpoll = DEFAULT_NBPOLLS; + gateway.pollsleep = DEFAULT_POLLSLEEP; gateway.auth_conn_timeout = DEFAULT_AUTH_CONNECT_TIMEOUT; gateway.auth_read_timeout = DEFAULT_AUTH_READ_TIMEOUT; gateway.auth_write_timeout = DEFAULT_AUTH_WRITE_TIMEOUT; - if (version_string != NULL) - gateway.version_string = strdup(version_string); - else - gateway.version_string = NULL; - gateway.id=0; + if (version_string != NULL) + { + gateway.version_string = strdup(version_string); + } + else + { + gateway.version_string = NULL; + } + gateway.id=0; - /* get release string */ - if(!config_get_release_string(gateway.release_string)) - sprintf(gateway.release_string,"undefined"); + /* get release string */ + if (!config_get_release_string(gateway.release_string)) + { + sprintf(gateway.release_string, "undefined"); + } - /* get first mac_address in SHA1 */ - if(config_get_ifaddr(mac_addr)) { - gw_sha1_str(mac_addr, 6, gateway.mac_sha1); - } else { - memset(gateway.mac_sha1, '\0', sizeof(gateway.mac_sha1)); - memcpy(gateway.mac_sha1, "MAC-undef", 9); - } + /* get first mac_address in SHA1 */ + if (config_get_ifaddr(mac_addr)) + { + gw_sha1_str(mac_addr, 6, gateway.mac_sha1); + } + else + { + memset(gateway.mac_sha1, '\0', sizeof(gateway.mac_sha1)); + memcpy(gateway.mac_sha1, "MAC-undef", 9); + } - /* get uname info */ - if (uname(&uname_data)) - strcpy(gateway.sysname, "undefined"); - else - strncpy(gateway.sysname, uname_data.sysname, _SYSNAME_STR_LENGTH); + /* get uname info */ + if (uname(&uname_data)) + { + strcpy(gateway.sysname, "undefined"); + } + else + { + strncpy(gateway.sysname, uname_data.sysname, _SYSNAME_STR_LENGTH); + } } /** @@ -1721,85 +1786,83 @@ global_defaults() static void feedback_defaults() { - feedback.feedback_enable = 0; - feedback.feedback_user_info = NULL; - feedback.feedback_last_action = _NOTIFICATION_SEND_PENDING; - feedback.feedback_timeout = _NOTIFICATION_OPERATION_TIMEOUT; - feedback.feedback_connect_timeout = _NOTIFICATION_CONNECT_TIMEOUT; - feedback.feedback_url = NULL; - feedback.feedback_frequency = 1800; - feedback.release_info = gateway.release_string; - feedback.sysname = gateway.sysname; - feedback.mac_sha1 = gateway.mac_sha1; + feedback.feedback_enable = 0; + feedback.feedback_user_info = NULL; + feedback.feedback_last_action = _NOTIFICATION_SEND_PENDING; + feedback.feedback_timeout = _NOTIFICATION_OPERATION_TIMEOUT; + feedback.feedback_connect_timeout = _NOTIFICATION_CONNECT_TIMEOUT; + feedback.feedback_url = NULL; + feedback.feedback_frequency = 1800; + feedback.release_info = gateway.release_string; + feedback.sysname = gateway.sysname; + feedback.mac_sha1 = gateway.mac_sha1; } /** * Process a configuration context update and turn it into the set of object * we need. * - * @param context The configuration data + * @param context The configuration data */ -static int +static int process_config_update(CONFIG_CONTEXT *context) { -CONFIG_CONTEXT *obj; -SERVICE *service; -SERVER *server; + CONFIG_CONTEXT *obj; + SERVICE *service; + SERVER *server; - /** - * Process the data and create the services and servers defined - * in the data. - */ - obj = context; - while (obj) - { - char *type = config_get_value(obj->parameters, "type"); - if (type == NULL) + /** + * Process the data and create the services and servers defined + * in the data. + */ + obj = context; + while (obj) + { + char *type = config_get_value(obj->parameters, "type"); + if (type == NULL) + { + LOGIF(LE, + (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Configuration object %s has no type.", + obj->object))); + } + else if (!strcmp(type, "service")) + { + char *router = config_get_value(obj->parameters, + "router"); + if (router) + { + if ((service = service_find(obj->object)) != NULL) { - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object %s has no type.", - obj->object))); - } - else if (!strcmp(type, "service")) - { - char *router = config_get_value(obj->parameters, - "router"); - if (router) - { - if ((service = service_find(obj->object)) != NULL) - { - char *user; - char *auth; - char *enable_root_user; + char *user; + char *auth; + char *enable_root_user; - char *connection_timeout; + char *connection_timeout; - char* auth_all_servers; - char* optimize_wildcard; - char* strip_db_esc; - char* max_slave_conn_str; - char* max_slave_rlag_str; - char *version_string; - char *allow_localhost_match_wildcard_host; + char* auth_all_servers; + char* optimize_wildcard; + char* strip_db_esc; + char* max_slave_conn_str; + char* max_slave_rlag_str; + char *version_string; + char *allow_localhost_match_wildcard_host; - enable_root_user = config_get_value(obj->parameters, "enable_root_user"); + enable_root_user = config_get_value(obj->parameters, "enable_root_user"); - connection_timeout = config_get_value(obj->parameters, "connection_timeout"); - user = config_get_value(obj->parameters, - "user"); - auth = config_get_value(obj->parameters, - "passwd"); - - auth_all_servers = config_get_value(obj->parameters, "auth_all_servers"); - optimize_wildcard = config_get_value(obj->parameters, "optimize_wildcard"); - strip_db_esc = config_get_value(obj->parameters, "strip_db_esc"); - version_string = config_get_value(obj->parameters, "version_string"); - allow_localhost_match_wildcard_host = config_get_value(obj->parameters, "localhost_match_wildcard_host"); + connection_timeout = config_get_value(obj->parameters, "connection_timeout"); + user = config_get_value(obj->parameters, "user"); + auth = config_get_value(obj->parameters, "passwd"); - char *log_auth_warnings = config_get_value(obj->parameters, - "log_auth_warnings"); + auth_all_servers = config_get_value(obj->parameters, "auth_all_servers"); + optimize_wildcard = config_get_value(obj->parameters, "optimize_wildcard"); + strip_db_esc = config_get_value(obj->parameters, "strip_db_esc"); + version_string = config_get_value(obj->parameters, "version_string"); + allow_localhost_match_wildcard_host = + config_get_value(obj->parameters, "localhost_match_wildcard_host"); + + char *log_auth_warnings = config_get_value(obj->parameters, "log_auth_warnings"); int truthval; if (log_auth_warnings && (truthval = config_truth_value(log_auth_warnings)) != -1) { @@ -1808,603 +1871,621 @@ SERVER *server; CONFIG_PARAMETER* param; - if((param = config_get_param(obj->parameters, "ignore_databases"))) + if ((param = config_get_param(obj->parameters, "ignore_databases"))) { service_set_param_value(service, param, param->value, 0, STRING_TYPE); } - if((param = config_get_param(obj->parameters, "ignore_databases_regex"))) + if ((param = config_get_param(obj->parameters, "ignore_databases_regex"))) { service_set_param_value(service, param, param->value, 0, STRING_TYPE); } - if (version_string) { - if (service->version_string) { - free(service->version_string); - } - service->version_string = strdup(version_string); - } + if (version_string) + { + if (service->version_string) + { + free(service->version_string); + } + service->version_string = strdup(version_string); + } - if (user && auth) { - service_update(service, router, - user, - auth); - if (enable_root_user) - serviceEnableRootUser(service, config_truth_value(enable_root_user)); + if (user && auth) + { + service_update(service, router, user, auth); + if (enable_root_user) + { + serviceEnableRootUser(service, config_truth_value(enable_root_user)); + } - if (connection_timeout) - serviceSetTimeout(service, config_truth_value(connection_timeout)); + if (connection_timeout) + { + serviceSetTimeout(service, config_truth_value(connection_timeout)); + } + if (auth_all_servers) + { + serviceAuthAllServers(service, config_truth_value(auth_all_servers)); + } + if (optimize_wildcard) + { + serviceOptimizeWildcard(service, config_truth_value(optimize_wildcard)); + } - if(auth_all_servers) - serviceAuthAllServers(service, config_truth_value(auth_all_servers)); - if(optimize_wildcard) - serviceOptimizeWildcard(service, config_truth_value(optimize_wildcard)); - if(strip_db_esc) - serviceStripDbEsc(service, config_truth_value(strip_db_esc)); + if (strip_db_esc) + { + serviceStripDbEsc(service, config_truth_value(strip_db_esc)); + } - if (allow_localhost_match_wildcard_host) - serviceEnableLocalhostMatchWildcardHost( - service, - config_truth_value(allow_localhost_match_wildcard_host)); - - /** Read, validate and set max_slave_connections */ - max_slave_conn_str = - config_get_value( - obj->parameters, - "max_slave_connections"); + if (allow_localhost_match_wildcard_host) + serviceEnableLocalhostMatchWildcardHost( + service, + config_truth_value(allow_localhost_match_wildcard_host)); - if (max_slave_conn_str != NULL) - { - CONFIG_PARAMETER* param; - bool succp; - - param = config_get_param(obj->parameters, - "max_slave_connections"); - - if (param == NULL) - { - succp = false; - } - else - { - succp = service_set_param_value( - service, - param, - max_slave_conn_str, - COUNT_ATMOST, - (PERCENT_TYPE|COUNT_TYPE)); - } - - if (!succp && param != NULL) - { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is either for slave connection " - "count or\n\t%% for specifying the " - "maximum percentage of available the " - "slaves that will be connected.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); - } - } - /** Read, validate and set max_slave_replication_lag */ - max_slave_rlag_str = - config_get_value(obj->parameters, - "max_slave_replication_lag"); - - if (max_slave_rlag_str != NULL) - { - CONFIG_PARAMETER* param; - bool succp; - - param = config_get_param( - obj->parameters, - "max_slave_replication_lag"); - - if (param == NULL) - { - succp = false; - } - else - { - succp = service_set_param_value( - service, - param, - max_slave_rlag_str, - COUNT_ATMOST, - COUNT_TYPE); - } - - if (!succp) - { - if(param){ - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is for maximum " - "slave replication lag.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); - }else{ - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : parameter was NULL"))); - } - } - } - } + /** Read, validate and set max_slave_connections */ + max_slave_conn_str = + config_get_value(obj->parameters, "max_slave_connections"); - obj->element = service; - } - else - { + if (max_slave_conn_str != NULL) + { + CONFIG_PARAMETER* param; + bool succp; + + param = config_get_param(obj->parameters, + "max_slave_connections"); + + if (param == NULL) + { + succp = false; + } + else + { + succp = service_set_param_value( + service, + param, + max_slave_conn_str, + COUNT_ATMOST, + (PERCENT_TYPE|COUNT_TYPE)); + } + + if (!succp && param != NULL) + { + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "* Warning : invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is either for slave connection " + "count or\n\t%% for specifying the " + "maximum percentage of available the " + "slaves that will be connected.", + ((SERVICE*)obj->element)->name, + param->name, + param->value))); + } + } + /** Read, validate and set max_slave_replication_lag */ + max_slave_rlag_str = + config_get_value(obj->parameters, "max_slave_replication_lag"); + + if (max_slave_rlag_str != NULL) + { + CONFIG_PARAMETER* param; + bool succp; + + param = config_get_param(obj->parameters, + "max_slave_replication_lag"); + + if (param == NULL) + { + succp = false; + } + else + { + succp = service_set_param_value(service, + param, + max_slave_rlag_str, + COUNT_ATMOST, + COUNT_TYPE); + } + + if (!succp) + { + if(param){ + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "* Warning : invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is for maximum " + "slave replication lag.", + ((SERVICE*)obj->element)->name, + param->name, + param->value))); + } + else + { + LOGIF(LE, (skygw_log_write( + LOGFILE_ERROR, + "Error : parameter was NULL"))); + } + } + } + } + + obj->element = service; + } + else + { char *user; - char *auth; - char *enable_root_user; - char *connection_timeout; - char *allow_localhost_match_wildcard_host; + char *auth; + char *enable_root_user; + char *connection_timeout; + char *allow_localhost_match_wildcard_host; - enable_root_user = - config_get_value(obj->parameters, - "enable_root_user"); + enable_root_user = config_get_value(obj->parameters, + "enable_root_user"); - connection_timeout = config_get_value(obj->parameters, + connection_timeout = config_get_value(obj->parameters, "connection_timeout"); - allow_localhost_match_wildcard_host = - config_get_value(obj->parameters, "localhost_match_wildcard_host"); - - user = config_get_value(obj->parameters, - "user"); - auth = config_get_value(obj->parameters, - "passwd"); - obj->element = service_alloc(obj->object, - router); - - if (obj->element && user && auth) - { - serviceSetUser(obj->element, - user, - auth); - if (enable_root_user) - serviceEnableRootUser(obj->element, config_truth_value(enable_root_user)); + allow_localhost_match_wildcard_host = + config_get_value(obj->parameters, "localhost_match_wildcard_host"); - if (connection_timeout) - serviceSetTimeout(obj->element, atoi(connection_timeout)); + user = config_get_value(obj->parameters, "user"); + auth = config_get_value(obj->parameters, "passwd"); + obj->element = service_alloc(obj->object, router); - if (allow_localhost_match_wildcard_host) - serviceEnableLocalhostMatchWildcardHost( - obj->element, - config_truth_value(allow_localhost_match_wildcard_host)); - } - } - } - else - { - obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No router defined for service " - "'%s'.", - obj->object))); - } - } - else if (!strcmp(type, "server")) - { - char *address; - char *port; - char *protocol; - char *monuser; - char *monpw; - - address = config_get_value(obj->parameters, "address"); - port = config_get_value(obj->parameters, "port"); - protocol = config_get_value(obj->parameters, "protocol"); - monuser = config_get_value(obj->parameters, - "monitoruser"); - monpw = config_get_value(obj->parameters, "monitorpw"); - - if (address && port && protocol) - { - if ((server = - server_find(address, atoi(port))) != NULL) - { - server_update(server, - protocol, - monuser, - monpw); - obj->element = server; - } - else - { - obj->element = server_alloc(address, - protocol, - atoi(port)); - - server_set_unique_name(obj->element, obj->object); - - if (obj->element && monuser && monpw) - { - serverAddMonUser(obj->element, - monuser, - monpw); - } - } - } - else + if (obj->element && user && auth) + { + serviceSetUser(obj->element, + user, + auth); + if (enable_root_user) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' is missing a " - "required " - "configuration parameter. A server must " - "have address, port and protocol " - "defined.", - obj->object))); + serviceEnableRootUser(obj->element, config_truth_value(enable_root_user)); } - } - obj = obj->next; - } - /* - * Now we have the services we can add the servers to the services - * add the protocols to the services - */ - obj = context; - while (obj) - { - char *type = config_get_value(obj->parameters, "type"); - if (type == NULL) - ; - else if (!strcmp(type, "service")) - { - char *servers; - char *roptions; - char *filters; - - servers = config_get_value(obj->parameters, "servers"); - roptions = config_get_value(obj->parameters, - "router_options"); - filters = config_get_value(obj->parameters, "filters"); - if (servers && obj->element) - { - char *lasts; - char *s = strtok_r(servers, ",", &lasts); - while (s) - { - CONFIG_CONTEXT *obj1 = context; - int found = 0; - while (obj1) - { - if (strcmp(trim(s), obj1->object) == 0 && - obj->element && obj1->element) - { - found = 1; - if (!serviceHasBackend(obj->element, obj1->element)) - { - serviceAddBackend( - obj->element, - obj1->element); - } - } - obj1 = obj1->next; - } - if (!found) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " - "server '%s' that is " - "configured as part of " - "service '%s'.", - s, obj->object))); - } - s = strtok_r(NULL, ",", &lasts); - } - } - if (roptions && obj->element) - { - char *lasts; - char *s = strtok_r(roptions, ",", &lasts); - serviceClearRouterOptions(obj->element); - while (s) - { - serviceAddRouterOption(obj->element, s); - s = strtok_r(NULL, ",", &lasts); - } - } - if (filters && obj->element) - serviceSetFilters(obj->element, filters); - } - else if (!strcmp(type, "listener")) - { - char *service; - char *port; - char *protocol; - char *address; - char *socket; + if (connection_timeout) + { + serviceSetTimeout(obj->element, atoi(connection_timeout)); + } - service = config_get_value(obj->parameters, "service"); - address = config_get_value(obj->parameters, "address"); - port = config_get_value(obj->parameters, "port"); - protocol = config_get_value(obj->parameters, "protocol"); - socket = config_get_value(obj->parameters, "socket"); + if (allow_localhost_match_wildcard_host) + { + serviceEnableLocalhostMatchWildcardHost( + obj->element, + config_truth_value(allow_localhost_match_wildcard_host)); + } + } + } + } + else + { + obj->element = NULL; + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : No router defined for service " + "'%s'.", + obj->object))); + } + } + else if (!strcmp(type, "server")) + { + char *address; + char *port; + char *protocol; + char *monuser; + char *monpw; - if (service && socket && protocol) - { - CONFIG_CONTEXT *ptr = context; - while (ptr && strcmp(ptr->object, service) != 0) - ptr = ptr->next; - - if (ptr && - ptr->element && - serviceHasProtocol(ptr->element, - protocol, - 0) == 0) - { - serviceAddProtocol(ptr->element, - protocol, - socket, - 0); - serviceStartProtocol(ptr->element, - protocol, - 0); - } - } + address = config_get_value(obj->parameters, "address"); + port = config_get_value(obj->parameters, "port"); + protocol = config_get_value(obj->parameters, "protocol"); + monuser = config_get_value(obj->parameters, "monitoruser"); + monpw = config_get_value(obj->parameters, "monitorpw"); - if (service && port && protocol) - { - CONFIG_CONTEXT *ptr = context; - while (ptr && strcmp(ptr->object, service) != 0) - ptr = ptr->next; - - if (ptr && - ptr->element && - serviceHasProtocol(ptr->element, - protocol, - atoi(port)) == 0) - { - serviceAddProtocol(ptr->element, - protocol, - address, - atoi(port)); - serviceStartProtocol(ptr->element, - protocol, - atoi(port)); - } - } - } - else if (strcmp(type, "server") != 0 && - strcmp(type, "monitor") != 0 && - strcmp(type, "filter") != 0) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object %s has an invalid " - "type specified.", - obj->object))); - } - obj = obj->next; - } - return 1; + if (address && port && protocol) + { + if ((server = server_find(address, atoi(port))) != NULL) + { + server_update(server, + protocol, + monuser, + monpw); + obj->element = server; + } + else + { + obj->element = server_alloc(address, + protocol, + atoi(port)); + + server_set_unique_name(obj->element, obj->object); + + if (obj->element && monuser && monpw) + { + serverAddMonUser(obj->element, + monuser, + monpw); + } + } + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Server '%s' is missing a " + "required " + "configuration parameter. A server must " + "have address, port and protocol " + "defined.", + obj->object))); + } + } + obj = obj->next; + } + + /* + * Now we have the services we can add the servers to the services + * add the protocols to the services + */ + obj = context; + while (obj) + { + char *type = config_get_value(obj->parameters, "type"); + if (type == NULL) + { + ; + } + else if (!strcmp(type, "service")) + { + char *servers; + char *roptions; + char *filters; + + servers = config_get_value(obj->parameters, "servers"); + roptions = config_get_value(obj->parameters, "router_options"); + filters = config_get_value(obj->parameters, "filters"); + + if (servers && obj->element) + { + char *lasts; + char *s = strtok_r(servers, ",", &lasts); + while (s) + { + CONFIG_CONTEXT *obj1 = context; + int found = 0; + while (obj1) + { + if (strcmp(trim(s), obj1->object) == 0 && obj->element && obj1->element) + { + found = 1; + if (!serviceHasBackend(obj->element, obj1->element)) + { + serviceAddBackend(obj->element, obj1->element); + } + } + + obj1 = obj1->next; + } + if (!found) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Unable to find " + "server '%s' that is " + "configured as part of " + "service '%s'.", + s, obj->object))); + } + s = strtok_r(NULL, ",", &lasts); + } + } + if (roptions && obj->element) + { + char *lasts; + char *s = strtok_r(roptions, ",", &lasts); + serviceClearRouterOptions(obj->element); + while (s) + { + serviceAddRouterOption(obj->element, s); + s = strtok_r(NULL, ",", &lasts); + } + } + if (filters && obj->element) + { + serviceSetFilters(obj->element, filters); + } + } + else if (!strcmp(type, "listener")) + { + char *service; + char *port; + char *protocol; + char *address; + char *socket; + + service = config_get_value(obj->parameters, "service"); + address = config_get_value(obj->parameters, "address"); + port = config_get_value(obj->parameters, "port"); + protocol = config_get_value(obj->parameters, "protocol"); + socket = config_get_value(obj->parameters, "socket"); + + if (service && socket && protocol) + { + CONFIG_CONTEXT *ptr = context; + while (ptr && strcmp(ptr->object, service) != 0) + { + ptr = ptr->next; + } + + if (ptr && + ptr->element && + serviceHasProtocol(ptr->element, protocol, 0) == 0) + { + serviceAddProtocol(ptr->element, protocol, socket, 0); + serviceStartProtocol(ptr->element, protocol, 0); + } + } + + if (service && port && protocol) + { + CONFIG_CONTEXT *ptr = context; + + while (ptr && strcmp(ptr->object, service) != 0) + { + ptr = ptr->next; + } + + if (ptr && + ptr->element && + serviceHasProtocol(ptr->element, protocol, atoi(port)) == 0) + { + serviceAddProtocol(ptr->element, protocol, address, atoi(port)); + serviceStartProtocol(ptr->element, protocol, atoi(port)); + } + } + } + else if (strcmp(type, "server") != 0 && + strcmp(type, "monitor") != 0 && + strcmp(type, "filter") != 0) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Configuration object %s has an invalid " + "type specified.", + obj->object))); + } + obj = obj->next; + } + + return 1; } static char *service_params[] = - { - "type", - "router", - "router_options", - "servers", - "user", - "passwd", - "enable_root_user", - "connection_timeout", - "auth_all_servers", - "optimize_wildcard", - "strip_db_esc", - "localhost_match_wildcard_host", - "max_slave_connections", - "max_slave_replication_lag", - "use_sql_variables_in", /*< rwsplit only */ - "subservices", - "version_string", - "filters", - "weightby", - "ssl_cert", - "ssl_ca_cert", - "ssl", - "ssl_key", - "ssl_version", - "ssl_cert_verify_depth", - "ignore_databases", - "ignore_databases_regex", - "log_auth_warnings", - NULL - }; +{ + "type", + "router", + "router_options", + "servers", + "user", + "passwd", + "enable_root_user", + "connection_timeout", + "auth_all_servers", + "optimize_wildcard", + "strip_db_esc", + "localhost_match_wildcard_host", + "max_slave_connections", + "max_slave_replication_lag", + "use_sql_variables_in", /*< rwsplit only */ + "subservices", + "version_string", + "filters", + "weightby", + "ssl_cert", + "ssl_ca_cert", + "ssl", + "ssl_key", + "ssl_version", + "ssl_cert_verify_depth", + "ignore_databases", + "ignore_databases_regex", + "log_auth_warnings", + NULL +}; static char *listener_params[] = - { - "type", - "service", - "protocol", - "port", - "address", - "socket", - NULL - }; +{ + "type", + "service", + "protocol", + "port", + "address", + "socket", + NULL +}; static char *monitor_params[] = - { - "type", - "module", - "servers", - "user", - "passwd", - "script", - "events", - "mysql51_replication", - "monitor_interval", - "detect_replication_lag", - "detect_stale_master", - "disable_master_failback", - "backend_connect_timeout", - "backend_read_timeout", - "backend_write_timeout", - "available_when_donor", - "disable_master_role_setting", - NULL - }; +{ + "type", + "module", + "servers", + "user", + "passwd", + "script", + "events", + "mysql51_replication", + "monitor_interval", + "detect_replication_lag", + "detect_stale_master", + "disable_master_failback", + "backend_connect_timeout", + "backend_read_timeout", + "backend_write_timeout", + "available_when_donor", + "disable_master_role_setting", + NULL +}; /** * Check the configuration objects have valid parameters */ static void check_config_objects(CONFIG_CONTEXT *context) { -CONFIG_CONTEXT *obj; -CONFIG_PARAMETER *params; -char *type, **param_set; -int i; + CONFIG_CONTEXT *obj; + CONFIG_PARAMETER *params; + char *type, **param_set; + int i; - /** - * Process the data and create the services and servers defined - * in the data. - */ - obj = context; - while (obj) - { - param_set = NULL; - if (obj->parameters && - (type = config_get_value(obj->parameters, "type"))) - { - if (!strcmp(type, "service")) - param_set = service_params; - else if (!strcmp(type, "listener")) - param_set = listener_params; - else if (!strcmp(type, "monitor")) - param_set = monitor_params; - } - if (param_set != NULL) - { - params = obj->parameters; - while (params) - { - int found = 0; - for (i = 0; param_set[i]; i++) - if (!strcmp(params->name, param_set[i])) - found = 1; - if (found == 0) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unexpected parameter " - "'%s' for object '%s' of type " - "'%s'.", - params->name, - obj->object, - type))); - params = params->next; - } - } - obj = obj->next; - } + /** + * Process the data and create the services and servers defined + * in the data. + */ + obj = context; + while (obj) + { + param_set = NULL; + if (obj->parameters && (type = config_get_value(obj->parameters, "type"))) + { + if (!strcmp(type, "service")) + { + param_set = service_params; + } + else if (!strcmp(type, "listener")) + { + param_set = listener_params; + } + else if (!strcmp(type, "monitor")) + { + param_set = monitor_params; + } + } + + if (param_set != NULL) + { + params = obj->parameters; + while (params) + { + int found = 0; + for (i = 0; param_set[i]; i++) + { + if (!strcmp(params->name, param_set[i])) + { + found = 1; + } + } + + if (found == 0) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Unexpected parameter " + "'%s' for object '%s' of type " + "'%s'.", + params->name, + obj->object, + type))); + } + params = params->next; + } + } + obj = obj->next; + } } /** * Set qualified parameter value to CONFIG_PARAMETER struct. */ -bool config_set_qualified_param( - CONFIG_PARAMETER* param, - void* val, - config_param_type_t type) +bool config_set_qualified_param(CONFIG_PARAMETER* param, + void* val, + config_param_type_t type) { - bool succp; - - switch (type) { - case STRING_TYPE: - param->qfd.valstr = strndup((const char *)val, MAX_PARAM_LEN); - succp = true; - break; + bool succp; - case COUNT_TYPE: - param->qfd.valcount = *(int *)val; - succp = true; - break; - - case PERCENT_TYPE: - param->qfd.valpercent = *(int *)val; - succp = true; - break; - - case BOOL_TYPE: - param->qfd.valbool = *(bool *)val; - succp = true; - break; + switch (type) + { + case STRING_TYPE: + param->qfd.valstr = strndup((const char *)val, MAX_PARAM_LEN); + succp = true; + break; - case SQLVAR_TARGET_TYPE: - param->qfd.valtarget = *(target_t *)val; - succp = true; - break; - default: - succp = false; - break; - } - - if (succp) - { - param->qfd_param_type = type; - } - return succp; + case COUNT_TYPE: + param->qfd.valcount = *(int *)val; + succp = true; + break; + + case PERCENT_TYPE: + param->qfd.valpercent = *(int *)val; + succp = true; + break; + + case BOOL_TYPE: + param->qfd.valbool = *(bool *)val; + succp = true; + break; + + case SQLVAR_TARGET_TYPE: + param->qfd.valtarget = *(target_t *)val; + succp = true; + break; + default: + succp = false; + break; + } + + if (succp) + { + param->qfd_param_type = type; + } + return succp; } /** * Used for boolean settings where values may be 1, yes or true * to enable a setting or -, no, false to disable a setting. * - * @param str String to convert to a boolean - * @return Truth value + * @param str String to convert to a boolean + * @return Truth value */ int config_truth_value(char *str) { - if (strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 || - strcasecmp(str, "yes") == 0 || strcasecmp(str, "1") == 0) - { - return 1; - } - if (strcasecmp(str, "false") == 0 || strcasecmp(str, "off") == 0 || - strcasecmp(str, "no") == 0|| strcasecmp(str, "0") == 0) - { - return 0; - } - skygw_log_write(LOGFILE_ERROR,"Error: Not a boolean value: %s",str); - return -1; + if (strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 || + strcasecmp(str, "yes") == 0 || strcasecmp(str, "1") == 0) + { + return 1; + } + if (strcasecmp(str, "false") == 0 || strcasecmp(str, "off") == 0 || + strcasecmp(str, "no") == 0|| strcasecmp(str, "0") == 0) + { + return 0; + } + skygw_log_write(LOGFILE_ERROR, "Error: Not a boolean value: %s", str); + return -1; } /** * Converts a string into a floating point representation of a percentage value. * For example 75% is converted to 0.75 and -10% is converted to -0.1. - * @param str String to convert - * @return String converted to a floating point percentage + * @param str String to convert + * @return String converted to a floating point percentage */ double config_percentage_value(char *str) { double value = 0; - value = strtod(str,NULL); - if(value != 0) - value /= 100.0; + value = strtod(str, NULL); + if (value != 0) + { + value /= 100.0; + } return value; } -static char *InternalRouters[] = { +static char *InternalRouters[] = +{ "debugcli", "cli", "maxinfo", @@ -2417,251 +2498,292 @@ static char *InternalRouters[] = { * Determine if the router is one of the special internal services that * MaxScale offers. * - * @param router The router name - * @return Non-zero if the router is in the InternalRouters table + * @param router The router name + * @return Non-zero if the router is in the InternalRouters table */ bool isInternalService(char *router) { - if (router) - { - for (int i = 0; InternalRouters[i]; i++) - if (strcmp(router, InternalRouters[i]) == 0) - return true; - } - return false; + if (router) + { + for (int i = 0; InternalRouters[i]; i++) + { + if (strcmp(router, InternalRouters[i]) == 0) + { + return true; + } + } + } + return false; } /** * Get the MAC address of first network interface * * and fill the provided allocated buffer with SHA1 encoding - * @param output Allocated 6 bytes buffer + * @param output Allocated 6 bytes buffer * @return 1 on success, 0 on failure * */ int config_get_ifaddr(unsigned char *output) { - struct ifreq ifr; - struct ifconf ifc; - char buf[1024]; - struct ifreq* it; - struct ifreq* end; - int success = 0; + struct ifreq ifr; + struct ifconf ifc; + char buf[1024]; + struct ifreq* it; + struct ifreq* end; + int success = 0; - int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); - if (sock == -1) { - return 0; - }; + int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sock == -1) + { + return 0; + } - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { - close(sock); - return 0; - } + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) + { + close(sock); + return 0; + } - it = ifc.ifc_req; - end = it + (ifc.ifc_len / sizeof(struct ifreq)); + it = ifc.ifc_req; + end = it + (ifc.ifc_len / sizeof(struct ifreq)); - for (; it != end; ++it) { - strcpy(ifr.ifr_name, it->ifr_name); - if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { - if (! (ifr.ifr_flags & IFF_LOOPBACK)) { /* don't count loopback */ - if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { - success = 1; - break; - } - } - } else { - close(sock); - return 0; - } - } + for (; it != end; ++it) + { + strcpy(ifr.ifr_name, it->ifr_name); - if (success) - memcpy(output, ifr.ifr_hwaddr.sa_data, 6); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) + { + if (!(ifr.ifr_flags & IFF_LOOPBACK)) + { /* don't count loopback */ + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) + { + success = 1; + break; + } + } + } + else + { + close(sock); + return 0; + } + } - return success; + if (success) + { + memcpy(output, ifr.ifr_hwaddr.sa_data, 6); + } + + return success; } /** * Get the linux distribution info * - * @param release The allocated buffer where - * the found distribution is copied into. + * @param release The allocated buffer where + * the found distribution is copied into. * @return 1 on success, 0 on failure * */ int config_get_release_string(char* release) { - const char *masks[]= { - "/etc/*-version", "/etc/*-release", - "/etc/*_version", "/etc/*_release" - }; + const char *masks[] = + { + "/etc/*-version", "/etc/*-release", + "/etc/*_version", "/etc/*_release" + }; - bool have_distribution; - char distribution[_RELEASE_STR_LENGTH]=""; - int fd; - int i; - char *to; + bool have_distribution; + char distribution[_RELEASE_STR_LENGTH]=""; + int fd; + int i; + char *to; - have_distribution= false; + have_distribution= false; - /* get data from lsb-release first */ - if ((fd= open("/etc/lsb-release", O_RDONLY)) != -1) - { - /* LSB-compliant distribution! */ - size_t len= read(fd, (char*)distribution, sizeof(distribution)-1); - close(fd); - if (len != (size_t)-1) - { - distribution[len]= 0; - char *found= strstr(distribution, "DISTRIB_DESCRIPTION="); - if (found) - { - have_distribution = true; - char *end = strstr(found, "\n"); - if (end == NULL) - end = distribution + len; - found += 20; + /* get data from lsb-release first */ + if ((fd = open("/etc/lsb-release", O_RDONLY)) != -1) + { + /* LSB-compliant distribution! */ + size_t len = read(fd, (char*)distribution, sizeof(distribution) - 1); + close(fd); - if (*found == '"' && end[-1] == '"') - { - found++; - end--; - } - *end = 0; + if (len != (size_t)-1) + { + distribution[len]= 0; - to = strcpy(distribution, "lsb: "); - memmove(to, found, end - found + 1 < INT_MAX ? end - found + 1 : INT_MAX); + char *found= strstr(distribution, "DISTRIB_DESCRIPTION="); - strncpy(release, to, _RELEASE_STR_LENGTH); + if (found) + { + have_distribution = true; + char *end = strstr(found, "\n"); + if (end == NULL) + { + end = distribution + len; + } + found += 20; - return 1; - } - } - } + if (*found == '"' && end[-1] == '"') + { + found++; + end--; + } + *end = 0; - /* if not an LSB-compliant distribution */ - for (i= 0; !have_distribution && i < 4; i++) - { - glob_t found; - char *new_to; + to = strcpy(distribution, "lsb: "); + memmove(to, found, end - found + 1 < INT_MAX ? end - found + 1 : INT_MAX); - if (glob(masks[i], GLOB_NOSORT, NULL, &found) == 0) - { - int fd; - int k = 0; - int skipindex = 0; - int startindex = 0; + strncpy(release, to, _RELEASE_STR_LENGTH); - for (k = 0; k< found.gl_pathc; k++) { - if (strcmp(found.gl_pathv[k], "/etc/lsb-release") == 0) { - skipindex = k; - } - } + return 1; + } + } + } - if ( skipindex == 0) - startindex++; + /* if not an LSB-compliant distribution */ + for (i = 0; !have_distribution && i < 4; i++) + { + glob_t found; + char *new_to; - if ((fd= open(found.gl_pathv[startindex], O_RDONLY)) != -1) - { - /* - +5 and -8 below cut the file name part out of the - full pathname that corresponds to the mask as above. - */ - new_to = strncpy(distribution, found.gl_pathv[0] + 5,_RELEASE_STR_LENGTH - 1); - new_to += 8; - *new_to++ = ':'; - *new_to++ = ' '; + if (glob(masks[i], GLOB_NOSORT, NULL, &found) == 0) + { + int fd; + int k = 0; + int skipindex = 0; + int startindex = 0; - size_t to_len= distribution + sizeof(distribution) - 1 - new_to; - size_t len= read(fd, (char*)new_to, to_len); + for (k = 0; k< found.gl_pathc; k++) + { + if (strcmp(found.gl_pathv[k], "/etc/lsb-release") == 0) + { + skipindex = k; + } + } - close(fd); + if (skipindex == 0) + startindex++; - if (len != (size_t)-1) - { - new_to[len]= 0; - char *end= strstr(new_to, "\n"); - if (end) - *end= 0; + if ((fd = open(found.gl_pathv[startindex], O_RDONLY)) != -1) + { + /* + +5 and -8 below cut the file name part out of the + full pathname that corresponds to the mask as above. + */ + new_to = strncpy(distribution, found.gl_pathv[0] + 5, _RELEASE_STR_LENGTH - 1); + new_to += 8; + *new_to++ = ':'; + *new_to++ = ' '; - have_distribution= true; - strncpy(release, new_to, _RELEASE_STR_LENGTH); - } - } - } - globfree(&found); - } + size_t to_len = distribution + sizeof(distribution) - 1 - new_to; + size_t len = read(fd, (char*)new_to, to_len); - if (have_distribution) - return 1; - else - return 0; + close(fd); + + if (len != (size_t)-1) + { + new_to[len]= 0; + char *end= strstr(new_to, "\n"); + if (end) + { + *end= 0; + } + + have_distribution= true; + strncpy(release, new_to, _RELEASE_STR_LENGTH); + } + } + } + globfree(&found); + } + + if (have_distribution) + { + return 1; + } + else + { + return 0; + } } /** * Add the 'send_feedback' task to the task list */ void -config_enable_feedback_task(void) { - FEEDBACK_CONF *cfg = config_get_feedback_data(); - int url_set = 0; - int user_info_set = 0; - int enable_set = cfg->feedback_enable; +config_enable_feedback_task(void) +{ + FEEDBACK_CONF *cfg = config_get_feedback_data(); + int url_set = 0; + int user_info_set = 0; + int enable_set = cfg->feedback_enable; - url_set = cfg->feedback_url != NULL && strlen(cfg->feedback_url); - user_info_set = cfg->feedback_user_info != NULL && strlen(cfg->feedback_user_info); + url_set = cfg->feedback_url != NULL && strlen(cfg->feedback_url); + user_info_set = cfg->feedback_user_info != NULL && strlen(cfg->feedback_user_info); - if (enable_set && url_set && user_info_set) { - /* Add the task to the tasl list */ - if (hktask_add("send_feedback", module_feedback_send, cfg, cfg->feedback_frequency)) { - - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Notification service feedback task started: URL=%s, User-Info=%s, Frequency %u seconds", - cfg->feedback_url, - cfg->feedback_user_info, - cfg->feedback_frequency))); - } - } else { - if (enable_set) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Notification service feedback cannot start: feedback_enable=1 but" - " some required parameters are not set: %s%s%s", - url_set == 0 ? "feedback_url is not set" : "", (user_info_set == 0 && url_set == 0) ? ", " : "", user_info_set == 0 ? "feedback_user_info is not set" : ""))); - } else { - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Notification service feedback is not enabled"))); - } - } + if (enable_set && url_set && user_info_set) + { + /* Add the task to the tasl list */ + if (hktask_add("send_feedback", module_feedback_send, cfg, cfg->feedback_frequency)) + { + LOGIF(LM, (skygw_log_write_flush( + LOGFILE_MESSAGE, + "Notification service feedback task started: URL=%s, User-Info=%s, " + "Frequency %u seconds", + cfg->feedback_url, + cfg->feedback_user_info, + cfg->feedback_frequency))); + } + } + else + { + if (enable_set) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error: Notification service feedback cannot start: feedback_enable=1 but" + " some required parameters are not set: %s%s%s", + url_set == 0 ? "feedback_url is not set" : "", + (user_info_set == 0 && url_set == 0) ? ", " : "", + user_info_set == 0 ? "feedback_user_info is not set" : ""))); + } + else + { + LOGIF(LT, (skygw_log_write_flush( + LOGFILE_TRACE, + "Notification service feedback is not enabled"))); + } + } } /** * Remove the 'send_feedback' task */ void -config_disable_feedback_task(void) { - hktask_remove("send_feedback"); +config_disable_feedback_task(void) +{ + hktask_remove("send_feedback"); } -unsigned long config_get_gateway_id() +unsigned long config_get_gateway_id() { return gateway.id; } -void config_add_param(CONFIG_CONTEXT* obj, char* key,char* value) + +void config_add_param(CONFIG_CONTEXT* obj, char* key, char* value) { CONFIG_PARAMETER* nptr = malloc(sizeof(CONFIG_PARAMETER)); - if(nptr == NULL) + if (nptr == NULL) { - skygw_log_write(LOGFILE_ERROR,"Memory allocation failed when adding configuration parameters"); - return; + skygw_log_write(LOGFILE_ERROR, "Memory allocation failed when adding configuration parameters"); + return; } nptr->name = strdup(key); @@ -2697,8 +2819,7 @@ bool config_has_duplicate_sections(const char* config) int size = 1024; char *buffer = malloc(size * sizeof(char)); - if (buffer && hash && re && - (mdata = pcre2_match_data_create_from_pattern(re, NULL))) + if (buffer && hash && re && (mdata = pcre2_match_data_create_from_pattern(re, NULL))) { hashtable_memory_fns(hash, (HASHMEMORYFN) strdup, NULL, (HASHMEMORYFN) free, NULL); From c7a329e43e90f7ab50b30a322a0302ad876e52fe Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 12 Nov 2015 10:15:50 +0200 Subject: [PATCH 146/179] Log: skygw_logmanager_init renamed to mxs_log_init. skygw_logmanager_init renamed to mxs_log_init and skygw_logmanager_done renamed to mxs_log_finish. skygw_logmanager_exit removed alltogether as all it did was to call skygw_logmanager_done. That appears to have been a source for confusion as in many places a call to skygw_logmanager_done was followed by a call to skygw_logmanager_exit. In addition, the function skygw_log_done was removed from the header, since it lacked an implementation. --- log_manager/log_manager.cc | 13 +--- log_manager/log_manager.h | 10 +-- log_manager/test/testlog.c | 76 +++++++++---------- log_manager/test/testorder.c | 4 +- server/core/gateway.c | 7 +- server/core/maxkeys.c | 4 +- server/core/maxpasswd.c | 4 +- server/include/test_utils.h | 2 +- server/modules/filter/dbfwfilter.c | 2 +- server/modules/filter/test/harness_common.c | 4 +- server/modules/filter/test/harness_ui.c | 6 +- server/modules/filter/test/harness_util.c | 3 +- .../modules/routing/binlog/maxbinlogcheck.c | 8 +- .../modules/routing/binlog/test/testbinlog.c | 6 +- 14 files changed, 65 insertions(+), 84 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index cf3653f90..f73d02714 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -439,7 +439,7 @@ return_succ: * @return true if succeed, otherwise false * */ -bool skygw_logmanager_init(const char* ident, const char* logdir, log_target_t target) +bool mxs_log_init(const char* ident, const char* logdir, log_target_t target) { bool succ = false; @@ -504,22 +504,13 @@ static void logmanager_done_nomutex(void) lm = NULL; } - -/** - * This function is provided for atexit() system function. - */ -void skygw_logmanager_exit(void) -{ - skygw_logmanager_done(); -} - /** * End execution of log manager * * Stops file writing thread, releases filewriter, and logfiles. * */ -void skygw_logmanager_done(void) +void mxs_log_finish(void) { acquire_lock(&lmlock); diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index be52d7675..539df718f 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -138,6 +138,9 @@ extern int lm_enabled_logfiles_bitmask; extern ssize_t log_ses_count[]; extern __thread log_info_t tls_log_info; +bool mxs_log_init(const char* ident, const char* logdir, log_target_t target); +void mxs_log_finish(void); + int mxs_log_flush(); int mxs_log_rotate(); int mxs_log_enable_priority(int priority); @@ -147,16 +150,9 @@ int mxs_log_message(int priority, const char* file, int line, const char* function, const char* format, ...); -bool skygw_logmanager_init(const char* ident, - const char* logdir, - log_target_t target); -void skygw_logmanager_done(void); -void skygw_logmanager_exit(void); - /** * free private write buffer list */ -void skygw_log_done(void); int skygw_log_flush(logfile_id_t id); void skygw_log_sync_all(void); int skygw_log_enable(logfile_id_t id); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index fc9c65255..c6f6320f0 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -113,14 +113,14 @@ int main(int argc, char* argv[]) err = 1; goto return_err; } - i = atexit(skygw_logmanager_exit); + i = atexit(mxs_log_finish); if (i != 0) { fprintf(stderr, "Couldn't register exit function.\n"); } - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + succp = mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); if (!succp) { @@ -139,7 +139,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -170,7 +170,7 @@ int main(int argc, char* argv[]) #endif logstr = "My name is Stacey %s"; err = skygw_log_write_flush(LOGFILE_TRACE, logstr, " "); - skygw_logmanager_done(); + mxs_log_finish(); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -187,7 +187,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -209,7 +209,7 @@ int main(int argc, char* argv[]) "with us. Just me and my mom - and you, of course. Then, if you wish, we could " "listen to the radio and keep company for our little Steven, my mom's cat, you know."); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_done(); + mxs_log_finish(); #if defined(TEST1) mes = skygw_message_init(); @@ -252,7 +252,7 @@ int main(int argc, char* argv[]) pthread_join(thr[i]->tid, NULL); } /** This is to release memory */ - skygw_logmanager_done(); + mxs_log_finish(); simple_mutex_unlock(mtx); @@ -309,7 +309,7 @@ int main(int argc, char* argv[]) pthread_join(thr[i]->tid, NULL); } /** This is to release memory */ - skygw_logmanager_done(); + mxs_log_finish(); simple_mutex_unlock(mtx); @@ -333,7 +333,7 @@ int main(int argc, char* argv[]) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + succp = mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); @@ -393,12 +393,12 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_ERROR, logstr); ss_dassert(err == 0); - skygw_logmanager_done(); + mxs_log_finish(); #endif /* TEST 3 */ #if defined(TEST4) - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + succp = mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -432,9 +432,9 @@ int main(int argc, char* argv[]) err = skygw_log_write(LOGFILE_MESSAGE, logstr); ss_dassert(err == 0); - skygw_logmanager_done(); + mxs_log_finish(); - succp = skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + succp = mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); ss_dassert(succp); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -488,7 +488,7 @@ int main(int argc, char* argv[]) ss_dassert(err == 0); - skygw_logmanager_done(); + mxs_log_finish(); #endif /* TEST 4 */ fprintf(stderr, ".. done.\n"); @@ -507,7 +507,7 @@ static void* thr_run(void* data) char* logstr; int err; - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -517,7 +517,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); + mxs_log_finish(); skygw_log_flush(LOGFILE_TRACE); skygw_log_flush(LOGFILE_MESSAGE); logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and " @@ -531,7 +531,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); err = skygw_log_write(LOGFILE_MESSAGE, logstr); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -539,8 +539,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); skygw_log_flush(LOGFILE_ERROR); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); @@ -553,8 +553,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference " "to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -566,11 +566,11 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); - skygw_logmanager_done(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); skygw_log_flush(LOGFILE_ERROR); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..and you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -578,8 +578,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); @@ -590,7 +590,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operatos & to both parts " @@ -602,7 +602,7 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..... and you too?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); if (err != 0) @@ -610,8 +610,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -626,8 +626,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, four\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -635,8 +635,8 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, .. where was I?\n"); err = skygw_log_write(LOGFILE_ERROR, logstr); if (err != 0) @@ -644,9 +644,9 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - skygw_logmanager_done(); - skygw_logmanager_init(NULL, "/tmp", LOG_TARGET_FS); - skygw_logmanager_done(); + mxs_log_finish(); + mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); + mxs_log_finish(); simple_mutex_lock(td->mtx, true); *td->nactive -= 1; simple_mutex_unlock(td->mtx); diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 757cfd5bb..7656e8b94 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -67,7 +67,7 @@ int main(int argc, char** argv) iterations = atoi(argv[1]); interval = atoi(argv[2]); - succp = skygw_logmanager_init(NULL, tmp, LOG_TARGET_FS); + succp = mxs_log_init(NULL, tmp, LOG_TARGET_FS); if (!succp) { @@ -108,7 +108,7 @@ int main(int argc, char** argv) } skygw_log_flush(LOGFILE_ERROR); - skygw_logmanager_done(); + mxs_log_finish(); free(message); return 0; } diff --git a/server/core/gateway.c b/server/core/gateway.c index 051387071..338c90b8c 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1081,10 +1081,7 @@ int main(int argc, char **argv) sigset_t sigset; sigset_t sigpipe_mask; sigset_t saved_mask; - void (*exitfunp[4])(void) = {skygw_logmanager_exit, - datadir_cleanup, - write_footer, - NULL}; + void (*exitfunp[4])(void) = { mxs_log_finish, datadir_cleanup, write_footer, NULL }; *syslog_enabled = 1; *maxscalelog_enabled = 1; @@ -1719,7 +1716,7 @@ int main(int argc, char **argv) logmanager_enable_syslog(*syslog_enabled); logmanager_enable_maxscalelog(*maxscalelog_enabled); - succp = skygw_logmanager_init(NULL, get_logdir(), log_target); + succp = mxs_log_init(NULL, get_logdir(), log_target); if (!succp) { diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 3b74d39af..14e94f9bb 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -48,7 +48,7 @@ int main(int argc, char **argv) keyfile = argv[1]; } - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); if (secrets_writeKeys(keyfile)) { @@ -57,7 +57,7 @@ int main(int argc, char **argv) } skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); return rval; } diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 1742b9341..9afe83d98 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -51,7 +51,7 @@ main(int argc, char **argv) return 1; } - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); pw = calloc(81, sizeof(char)); @@ -75,6 +75,6 @@ main(int argc, char **argv) free(pw); skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); return rval; } diff --git a/server/include/test_utils.h b/server/include/test_utils.h index f6707e9ca..53bcbb379 100644 --- a/server/include/test_utils.h +++ b/server/include/test_utils.h @@ -12,7 +12,7 @@ void init_test_env(char *path) const char* logdir = path ? path : TEST_LOG_DIR; - skygw_logmanager_init(NULL, logdir, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, logdir, LOG_TARGET_DEFAULT); poll_init(); hkinit(); } diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 8f64139c8..0d72f7ccb 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -2213,7 +2213,7 @@ int main(int argc, char** argv) NULL }; - skygw_logmanager_init(argc_,argv_); + mxs_log_init(argc_,argv_); init_test_env(home); diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index 0dc79909d..0b8510263 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -17,7 +17,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ char tmp[2048]; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ - skygw_logmanager_init(NULL,NULL,LOG_TARGET_DEFAULT); + mxs_log_init(NULL,NULL,LOG_TARGET_DEFAULT); } if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) @@ -51,7 +51,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ getcwd(cwd,sizeof(cwd)); sprintf(tmp,"%s",cwd); - skygw_logmanager_init(NULL, tmp, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, tmp, LOG_TARGET_DEFAULT); rval = process_opts(argc,argv); diff --git a/server/modules/filter/test/harness_ui.c b/server/modules/filter/test/harness_ui.c index fa8d14e3d..b92182a37 100644 --- a/server/modules/filter/test/harness_ui.c +++ b/server/modules/filter/test/harness_ui.c @@ -11,8 +11,7 @@ int main(int argc, char** argv){ if(harness_init(argc,argv,&hinstance)){ printf("Error: Initialization failed.\n"); skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); - skygw_logmanager_done(); - skygw_logmanager_exit(); + mxs_log_finish(); return 1; } @@ -230,8 +229,7 @@ int main(int argc, char** argv){ free_buffers(); free_filters(); - skygw_logmanager_done(); - skygw_logmanager_exit(); + mxs_log_finish(); free(instance.head); return 0; diff --git a/server/modules/filter/test/harness_util.c b/server/modules/filter/test/harness_util.c index 5b3baf31e..16d10c8c4 100644 --- a/server/modules/filter/test/harness_util.c +++ b/server/modules/filter/test/harness_util.c @@ -35,8 +35,7 @@ int main(int argc,char** argv) if(harness_init(argc,argv,&inst) || inst->error){ printf("Error: Initialization failed.\n"); skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); - skygw_logmanager_done(); - skygw_logmanager_exit(); + mxs_log_finish(); return 1; } diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 016f43235..0af03b0b8 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -124,7 +124,7 @@ int main(int argc, char **argv) { num_args = optind; - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); skygw_log_set_augmentation(0); @@ -138,7 +138,7 @@ int main(int argc, char **argv) { "Error: Memory allocation failed for ROUTER_INSTANCE"))); skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); return 1; } @@ -162,7 +162,7 @@ int main(int argc, char **argv) { path, strerror(errno)))); skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); free(inst); @@ -200,7 +200,7 @@ int main(int argc, char **argv) { "Check retcode: %i, Binlog Pos = %llu", ret, inst->binlog_position))); skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); free(inst); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index 2cb796ea8..b034307cf 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -89,7 +89,7 @@ int main(int argc, char **argv) { roptions = strdup("server-id=3,heartbeat=200,binlogdir=/not_exists/my_dir,transaction_safety=1,master_version=5.6.99-common,master_hostname=common_server,master_uuid=xxx-fff-cccc-fff,master-id=999"); - skygw_logmanager_init(NULL, NULL, LOG_TARGET_DEFAULT); + mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); skygw_log_disable(LOGFILE_DEBUG); skygw_log_disable(LOGFILE_TRACE); @@ -128,7 +128,7 @@ int main(int argc, char **argv) { "Error: Memory allocation FAILED for ROUTER_INSTANCE"))); skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); return 1; } @@ -579,7 +579,7 @@ int main(int argc, char **argv) { } skygw_log_sync_all(); - skygw_logmanager_done(); + mxs_log_finish(); free(inst); From 05fbdb1b76c7e1d3b1615ff971cc9f7cdeb818a7 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 12 Nov 2015 11:10:26 +0200 Subject: [PATCH 147/179] Log: skygw_log_flush replaced with mxs_log_flush. skygw_log_flush replaced with mxs_log_flush and skygw_log_sync_all with mxs_log_flush_sync. --- log_manager/log_manager.cc | 110 +++++++++--------- log_manager/log_manager.h | 8 +- log_manager/test/testlog.c | 15 ++- log_manager/test/testorder.c | 2 +- server/core/dcb.c | 2 +- server/core/gateway.c | 13 +-- server/core/maxkeys.c | 2 +- server/core/maxpasswd.c | 2 +- server/core/test/testhint.c | 6 +- server/core/test/testserver.c | 14 +-- server/core/test/testservice.c | 16 +-- server/core/test/testusers.c | 18 +-- server/modules/filter/dbfwfilter.c | 2 +- .../modules/routing/binlog/maxbinlogcheck.c | 8 +- .../modules/routing/binlog/test/testbinlog.c | 4 +- utils/skygw_debug.h | 4 +- 16 files changed, 111 insertions(+), 115 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index f73d02714..356d1a7c0 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1308,38 +1308,6 @@ static int log_write(int priority, return rv; } -int skygw_log_flush(logfile_id_t id) -{ - int err = -1; - - if (id == LOGFILE_ERROR) - { - if (logmanager_register(false)) - { - CHK_LOGMANAGER(lm); - - logfile_t *lf = logmanager_get_logfile(lm); - CHK_LOGFILE(lf); - - logfile_flush(lf); - err = 0; - - logmanager_unregister(); - } - else - { - ss_dfprintf(stderr, "Can't register to logmanager, flushing failed.\n"); - } - } - else - { - // We'll pretend everything went ok. - err = 0; - } - - return err; -} - /** * @node Register as a logging client to logmanager. * @@ -2592,26 +2560,6 @@ void flushall_logfiles(bool flush) simple_mutex_unlock(&lm->lm_mutex); } -/** - * Flush all log files synchronously - */ -void skygw_log_sync_all(void) -{ - if (!log_config.use_stdout) - { - skygw_log_write(LOGFILE_TRACE,"Starting log flushing to disk."); - } - - /** If initialization of the log manager has not been done, lm pointer can be - * NULL. */ - if (lm) - { - flushall_logfiles(true); - skygw_message_send(lm->lm_logmes); - skygw_message_wait(lm->lm_clientmes); - } -} - /** * Toggle high precision logging * @param val 0 for disabled, 1 for enabled @@ -2652,7 +2600,63 @@ void logmanager_enable_maxscalelog(int val) */ int mxs_log_flush() { - return skygw_log_flush(LOGFILE_ERROR); + int err = -1; + + if (logmanager_register(false)) + { + CHK_LOGMANAGER(lm); + + logfile_t *lf = logmanager_get_logfile(lm); + CHK_LOGFILE(lf); + + logfile_flush(lf); + err = 0; + + logmanager_unregister(); + } + else + { + ss_dfprintf(stderr, "Can't register to logmanager, flushing failed.\n"); + } + + return err; +} + +/** + * Explicitly ensure that all pending log messages are flushed. + * + * @return 0 if the flushing was successfully performed, otherwise -1. + * + * When the function returns 0, the flushing has been initiated and the + * flushing thread has indicated that the operation has been performed. + * However, 0 will be returned also in the case that the flushing thread + * for, whatever reason, failed to actually flush the log. + */ +int mxs_log_flush_sync(void) +{ + int err = 0; + + if (!log_config.use_stdout) + { + MXS_INFO("Starting log flushing to disk."); + } + + /** If initialization of the log manager has not been done, lm pointer can be + * NULL. */ + // TODO: Why is logmanager_register() not called here? + if (lm) + { + flushall_logfiles(true); + err = skygw_message_send(lm->lm_logmes); + + if (!err) + { + // TODO: Add error handling to skygw_message_wait. Now void. + skygw_message_wait(lm->lm_clientmes); + } + } + + return err; } /** diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 539df718f..35cab496d 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -142,7 +142,9 @@ bool mxs_log_init(const char* ident, const char* logdir, log_target_t target); void mxs_log_finish(void); int mxs_log_flush(); +int mxs_log_flush_sync(); int mxs_log_rotate(); + int mxs_log_enable_priority(int priority); int mxs_log_disable_priority(int priority); @@ -150,14 +152,8 @@ int mxs_log_message(int priority, const char* file, int line, const char* function, const char* format, ...); -/** - * free private write buffer list - */ -int skygw_log_flush(logfile_id_t id); -void skygw_log_sync_all(void); int skygw_log_enable(logfile_id_t id); int skygw_log_disable(logfile_id_t id); -void skygw_log_sync_all(void); void skygw_set_highp(int); void logmanager_enable_syslog(int); void logmanager_enable_maxscalelog(int); diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index c6f6320f0..ddf1c410a 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -152,14 +152,14 @@ int main(int argc, char* argv[]) logstr = ("Fourth write, no flush. Next flush only."); err = skygw_log_write(LOGFILE_ERROR, logstr); - err = skygw_log_flush(LOGFILE_ERROR); + err = mxs_log_flush(); logstr = "My name is %s %d years and %d months."; #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif err = skygw_log_write(LOGFILE_TRACE, logstr, "TraceyTracey", 3, 7); - skygw_log_flush(LOGFILE_TRACE); + mxs_log_flush(); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -508,7 +508,7 @@ static void* thr_run(void* data) int err; mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); - skygw_log_flush(LOGFILE_MESSAGE); + mxs_log_flush(); logstr = ("Hi, how are you?"); err = skygw_log_write(LOGFILE_MESSAGE, logstr); @@ -518,8 +518,7 @@ static void* thr_run(void* data) } ss_dassert(err == 0); mxs_log_finish(); - skygw_log_flush(LOGFILE_TRACE); - skygw_log_flush(LOGFILE_MESSAGE); + mxs_log_flush(); logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and " "I thought that would you like to come to my place and have a little piece of " "cheese with us. Just me and my mom - and you, of course. Then, if you wish, " @@ -541,7 +540,7 @@ static void* thr_run(void* data) ss_dassert(err == 0); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); - skygw_log_flush(LOGFILE_ERROR); + mxs_log_flush(); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) @@ -568,7 +567,7 @@ static void* thr_run(void* data) ss_dassert(err == 0); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); mxs_log_finish(); - skygw_log_flush(LOGFILE_ERROR); + mxs_log_flush(); mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..and you?"); @@ -615,7 +614,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - skygw_log_flush(LOGFILE_TRACE); + mxs_log_flush(); logstr = ("For automatic and register variables, it is done each time the function or block is entered."); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 7656e8b94..06494cfdd 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -107,7 +107,7 @@ int main(int argc, char** argv) nanosleep(&ts1, NULL); } - skygw_log_flush(LOGFILE_ERROR); + mxs_log_flush(); mxs_log_finish(); free(message); return 0; diff --git a/server/core/dcb.c b/server/core/dcb.c index f45f682f1..ac7646ade 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -980,7 +980,7 @@ int dcb_read_SSL(DCB *dcb, if (GWBUF_LENGTH(buffer) != n) { - skygw_log_sync_all(); + mxs_log_flush_sync(); } ss_info_dassert((buffer->start <= buffer->end), "Buffer start has passed end."); diff --git a/server/core/gateway.c b/server/core/gateway.c index 338c90b8c..71cbb321c 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -316,7 +316,7 @@ static void sigterm_handler (int i) { skygw_log_write_flush( LOGFILE_ERROR, "MaxScale received signal SIGTERM. Exiting."); - skygw_log_sync_all(); + mxs_log_flush_sync(); shutdown_server(); } @@ -328,7 +328,7 @@ sigint_handler (int i) skygw_log_write_flush( LOGFILE_ERROR, "MaxScale received signal SIGINT. Shutting down."); - skygw_log_sync_all(); + mxs_log_flush_sync(); shutdown_server(); fprintf(stderr, "\n\nShutting down MaxScale\n\n"); } @@ -409,7 +409,7 @@ sigfatal_handler(int i) } } - skygw_log_sync_all(); + mxs_log_flush_sync(); /* re-raise signal to enforce core dump */ fprintf(stderr, "\n\nWriting core dump\n"); @@ -822,7 +822,7 @@ static bool file_is_readable( absolute_pathname, eno, strerror_r(eno, errbuf, sizeof(errbuf))); - skygw_log_sync_all(); + mxs_log_flush_sync(); succp = false; } return succp; @@ -2054,10 +2054,7 @@ static void log_flush_cb( LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "Started MaxScale log flusher."))); while (!do_exit) { - skygw_log_flush(LOGFILE_ERROR); - skygw_log_flush(LOGFILE_MESSAGE); - skygw_log_flush(LOGFILE_TRACE); - skygw_log_flush(LOGFILE_DEBUG); + mxs_log_flush(); nanosleep(&ts1, NULL); } LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, diff --git a/server/core/maxkeys.c b/server/core/maxkeys.c index 14e94f9bb..21546fb49 100644 --- a/server/core/maxkeys.c +++ b/server/core/maxkeys.c @@ -56,7 +56,7 @@ int main(int argc, char **argv) rval = 1; } - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); return rval; diff --git a/server/core/maxpasswd.c b/server/core/maxpasswd.c index 9afe83d98..89d37caaf 100644 --- a/server/core/maxpasswd.c +++ b/server/core/maxpasswd.c @@ -74,7 +74,7 @@ main(int argc, char **argv) } free(pw); - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); return rval; } diff --git a/server/core/test/testhint.c b/server/core/test/testhint.c index 77c1aa4e8..38bccc3e3 100644 --- a/server/core/test/testhint.c +++ b/server/core/test/testhint.c @@ -44,7 +44,7 @@ * test1 Allocate table of users and mess around with it * */ -void skygw_log_sync_all(void); +int mxs_log_flush_sync(void); static int test1() { @@ -56,13 +56,13 @@ HINT *hint; char* name = strdup("name"); hint = hint_create_parameter(NULL, name, "value"); free(name); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL != hint, "New hint list should not be null"); ss_info_dassert(0 == strcmp("value", hint->value), "Hint value should be correct"); ss_info_dassert(0 != hint_exists(&hint, HINT_PARAMETER), "Hint of parameter type should exist"); ss_dfprintf(stderr, "\t..done\nFree hints."); if (NULL != hint) hint_free(hint); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_dfprintf(stderr, "\t..done\n"); return 0; diff --git a/server/core/test/testserver.c b/server/core/test/testserver.c index b82c1f2c8..57f4d4e3a 100644 --- a/server/core/test/testserver.c +++ b/server/core/test/testserver.c @@ -55,7 +55,7 @@ char *status; ss_dfprintf(stderr, "testserver : creating server called MyServer"); server = server_alloc("MyServer", "HTTPD", 9876); - skygw_log_sync_all(); + mxs_log_flush_sync(); //ss_info_dassert(NULL != service, "New server with valid protocol and port must not be null"); //ss_info_dassert(0 != service_isvalid(service), "Service must be valid after creation"); @@ -63,32 +63,32 @@ char *status; ss_dfprintf(stderr, "\t..done\nTest Parameter for Server."); ss_info_dassert(NULL == serverGetParameter(server, "name"), "Parameter should be null when not set"); serverAddParameter(server, "name", "value"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 == strcmp("value", serverGetParameter(server, "name")), "Parameter should be returned correctly"); ss_dfprintf(stderr, "\t..done\nTesting Unique Name for Server."); ss_info_dassert(NULL == server_find_by_unique_name("uniquename"), "Should not find non-existent unique name."); server_set_unique_name(server, "uniquename"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(server == server_find_by_unique_name("uniquename"), "Should find by unique name."); ss_dfprintf(stderr, "\t..done\nTesting Status Setting for Server."); status = server_status(server); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 == strcmp("Running", status), "Status of Server should be Running by default."); if (NULL != status) free(status); server_set_status(server, SERVER_MASTER); status = server_status(server); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 == strcmp("Master, Running", status), "Should find correct status."); server_clear_status(server, SERVER_MASTER); free(status); status = server_status(server); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 == strcmp("Running", status), "Status of Server should be Running after master status cleared."); if (NULL != status) free(status); ss_dfprintf(stderr, "\t..done\nRun Prints for Server and all Servers."); printServer(server); printAllServers(); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_dfprintf(stderr, "\t..done\nFreeing Server."); ss_info_dassert(0 != server_free(server), "Free should succeed"); ss_dfprintf(stderr, "\t..done\n"); diff --git a/server/core/test/testservice.c b/server/core/test/testservice.c index 5fa7e0436..4bb41fee5 100644 --- a/server/core/test/testservice.c +++ b/server/core/test/testservice.c @@ -60,12 +60,12 @@ init_test_env(NULL); ss_dfprintf(stderr, "testservice : creating service called MyService with router nonexistent"); service = service_alloc("MyService", "non-existent"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL == service, "New service with invalid router should be null"); ss_info_dassert(0 == service_isvalid(service), "Service must not be valid after incorrect creation"); ss_dfprintf(stderr, "\t..done\nValid service creation, router testroute."); service = service_alloc("MyService", "testroute"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL != service, "New service with valid router must not be null"); ss_info_dassert(0 != service_isvalid(service), "Service must be valid after creation"); ss_info_dassert(0 == strcmp("MyService", service_get_name(service)), "Service must have given name"); @@ -73,26 +73,26 @@ init_test_env(NULL); ss_info_dassert(0 != serviceAddProtocol(service, "testprotocol", "localhost", 9876), "Add Protocol should succeed"); ss_info_dassert(0 != serviceHasProtocol(service, "testprotocol", 9876), "Service should have new protocol as requested"); serviceStartProtocol(service, "testprotocol", 9876); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_dfprintf(stderr, "\t..done\nStarting Service."); result = serviceStart(service); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 != result, "Start should succeed"); serviceStop(service); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(service->state == SERVICE_STATE_STOPPED, "Stop should succeed"); result = serviceStartAll(); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 != result, "Start all should succeed"); ss_dfprintf(stderr, "\t..done\nTiming out a session."); service->conn_timeout = 1; result = serviceStart(service); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(0 != result, "Start should succeed"); serviceStop(service); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(service->state == SERVICE_STATE_STOPPED, "Stop should succeed"); if((dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER)) == NULL) diff --git a/server/core/test/testusers.c b/server/core/test/testusers.c index 4385d74eb..fcc933b1a 100644 --- a/server/core/test/testusers.c +++ b/server/core/test/testusers.c @@ -58,39 +58,39 @@ int result, count; ss_dfprintf(stderr, "testusers : Initialise the user table."); users = users_alloc(); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL != users, "Allocating user table should not return NULL.") ss_dfprintf(stderr, "\t..done\nAdd a user"); count = users_add(users, "username", "authorisation"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(1 == count, "Should add one user"); authdata = users_fetch(users, "username"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL != authdata, "Fetch valid user must not return NULL"); ss_info_dassert(0 == strcmp("authorisation", authdata), "User authorisation should be correct"); ss_dfprintf(stderr, "\t..done\nPrint users"); usersPrint(users); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_dfprintf(stderr, "\t..done\nUpdate a user"); count = users_update(users, "username", "newauth"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(1 == count, "Should update just one user"); authdata = users_fetch(users, "username"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(NULL != authdata, "Fetch valid user must not return NULL"); ss_info_dassert(0 == strcmp("newauth", authdata), "User authorisation should be correctly updated"); ss_dfprintf(stderr, "\t..done\nAdd another user"); count = users_add(users, "username2", "authorisation2"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(1 == count, "Should add one user"); ss_dfprintf(stderr, "\t..done\nDelete a user."); count = users_delete(users, "username"); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_info_dassert(1 == count, "Should delete just one user"); ss_dfprintf(stderr, "\t..done\nFree user table."); users_free(users); - skygw_log_sync_all(); + mxs_log_flush_sync(); ss_dfprintf(stderr, "\t..done\n"); return 0; diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 0d72f7ccb..37dc5419f 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -2231,7 +2231,7 @@ int main(int argc, char** argv) printf("Failed to parse rule. Read the error log for the reason of the failure.\n"); } - skygw_log_sync_all(); + mxs_log_flush_sync(); return 0; } diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 0af03b0b8..086e63e71 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -137,7 +137,7 @@ int main(int argc, char **argv) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "Error: Memory allocation failed for ROUTER_INSTANCE"))); - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); return 1; @@ -161,7 +161,7 @@ int main(int argc, char **argv) { "Failed to open binlog file %s: %s", path, strerror(errno)))); - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); free(inst); @@ -194,12 +194,12 @@ int main(int argc, char **argv) { close(inst->binlog_fd); - skygw_log_sync_all(); + mxs_log_flush_sync(); LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, "Check retcode: %i, Binlog Pos = %llu", ret, inst->binlog_position))); - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); free(inst); diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index b034307cf..ee4609517 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -127,7 +127,7 @@ int main(int argc, char **argv) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "Error: Memory allocation FAILED for ROUTER_INSTANCE"))); - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); return 1; @@ -578,7 +578,7 @@ int main(int argc, char **argv) { return 1; } - skygw_log_sync_all(); + mxs_log_flush_sync(); mxs_log_finish(); free(inst); diff --git a/utils/skygw_debug.h b/utils/skygw_debug.h index 2fa094ffb..fe99fcd85 100644 --- a/utils/skygw_debug.h +++ b/utils/skygw_debug.h @@ -55,11 +55,11 @@ # define ss_dassert(exp) if(!(exp)){(skygw_log_write(LE,\ "debug assert %s:%d\n", \ (char*)__FILE__, \ - __LINE__));skygw_log_sync_all();assert(exp);} + __LINE__));mxs_log_flush_sync();assert(exp);} #define ss_info_dassert(exp,info) if(!(exp)){(skygw_log_write(LE,\ "debug assert %s:%d %s\n", \ (char*)__FILE__, \ - __LINE__,info));skygw_log_sync_all();assert(exp);} + __LINE__,info));mxs_log_flush_sync();assert(exp);} # define ss_debug(exp) exp # define ss_dfprintf fprintf # define ss_dfflush fflush From 2c1b53c120cb305839bda126b0b7ea531393df62 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 12 Nov 2015 13:15:29 +0200 Subject: [PATCH 148/179] Log: Cleanup of API skygw_ functions removed and replaced with mxs_ equivalents. logfile_id_t removed. --- log_manager/log_manager.cc | 153 ++++++++---------- log_manager/log_manager.h | 18 +-- server/core/config.c | 2 +- server/core/gateway.c | 7 +- .../modules/routing/binlog/maxbinlogcheck.c | 2 +- server/modules/routing/debugcmd.c | 4 +- 6 files changed, 78 insertions(+), 108 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 356d1a7c0..f81f9ef79 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -65,18 +65,26 @@ static int block_start_index; static int prevval; static simple_mutex_t msg_mutex; #endif + +/** + * Default augmentation. + */ +static int DEFAULT_LOG_AUGMENTATION = 0; + static struct { - int highprec; // Can change during the lifetime of log_manager. - int do_syslog; // Can change during the lifetime of log_manager. - int do_maxscalelog; // Can change during the lifetime of log_manager. - int use_stdout; // Can NOT changed during the lifetime of log_manager. + int augmentation; // Can change during the lifetime of log_manager. + bool do_highprecision; // Can change during the lifetime of log_manager. + bool do_syslog; // Can change during the lifetime of log_manager. + bool do_maxscalelog; // Can change during the lifetime of log_manager. + bool use_stdout; // Can NOT changed during the lifetime of log_manager. } log_config = { - 0, // highprec - 1, // do_syslog - 1, // do_maxscalelog - 0 // use_stdout + DEFAULT_LOG_AUGMENTATION, // augmentation + false, // do_highprecision + true, // do_syslog + true, // do_maxscalelog + false // use_stdout }; /** @@ -130,12 +138,6 @@ static bool flushall_flag; static bool flushall_started_flag; static bool flushall_done_flag; -/** - * Default augmentation. - */ -static int default_log_augmentation = 0; -static int log_augmentation = default_log_augmentation; - /** This is used to detect if the initialization of the log manager has failed * and that it isn't initialized again after a failure has occurred. */ static bool fatal_error = false; @@ -625,7 +627,7 @@ static int logmanager_write_log(int priority, // The config parameters are copied to local variables, because the values in // log_config may change during the course of the function, with would have // unpleasant side-effects. - int highprec = log_config.highprec; + int do_highprecision = log_config.do_highprecision; int do_maxscalelog = log_config.do_maxscalelog; int do_syslog = log_config.do_syslog; @@ -655,7 +657,7 @@ static int logmanager_write_log(int priority, { sesid_str_len = 0; } - if (highprec) + if (do_highprecision) { timestamp_len = get_timestamp_len_hp(); } @@ -733,7 +735,7 @@ static int logmanager_write_log(int priority, * to wp. * Returned timestamp_len doesn't include terminating null. */ - if (highprec) + if (do_highprecision) { timestamp_len = snprint_timestamp_hp(wp, timestamp_len); } @@ -1210,7 +1212,7 @@ static bool logfile_set_enabled(logfile_id_t id, bool val) if (logmanager_is_valid_id(id)) { - if (log_config.use_stdout == 0) + if (!log_config.use_stdout) { const char *name; @@ -1260,14 +1262,14 @@ static bool logfile_set_enabled(logfile_id_t id, bool val) return rval; } -void skygw_log_set_augmentation(int bits) +/** + * Set log augmentation. + * + * @param bits One of the log_augmentation_t constants. + */ +void mxs_log_set_augmentation(int bits) { - log_augmentation = bits & LOG_AUGMENTATION_MASK; -} - -int skygw_log_get_augmentation() -{ - return log_augmentation; + log_config.augmentation = bits & LOG_AUGMENTATION_MASK; } /** @@ -1430,12 +1432,12 @@ static bool fnames_conf_init(fnames_conf_t* fn, const char* logdir) const char* dir; if (logdir) { - log_config.use_stdout = 0; + log_config.use_stdout = false; dir = logdir; } else { - log_config.use_stdout = 1; + log_config.use_stdout = true; // TODO: Re-arrange things so that fn->fn_logpath can be NULL. dir = "/tmp"; } @@ -2561,31 +2563,33 @@ void flushall_logfiles(bool flush) } /** - * Toggle high precision logging - * @param val 0 for disabled, 1 for enabled + * Enable/disable syslog logging. + * + * @param enabled True, if high precision logging should be enabled, false if it should be disabled. */ -void skygw_set_highp(int val) +void mxs_log_set_highprecision_enabled(bool enabled) { - log_config.highprec = !!val; -} - - -/** - * Toggle syslog logging - * @param val 0 for disabled, 1 for enabled - */ -void logmanager_enable_syslog(int val) -{ - log_config.do_syslog = !!val; + log_config.do_highprecision = enabled; } /** - * Toggle syslog logging - * @param val 0 for disabled, 1 for enabled + * Enable/disable syslog logging. + * + * @param enabled True, if syslog logging should be enabled, false if it should be disabled. */ -void logmanager_enable_maxscalelog(int val) +void mxs_log_set_syslog_enabled(bool enabled) { - log_config.do_maxscalelog = !!val; + log_config.do_syslog = enabled; +} + +/** + * Enable/disable maxscale log logging. + * + * @param enabled True, if syslog logging should be enabled, false if it should be disabled. + */ +void mxs_log_set_maxscalelog_enabled(bool enabled) +{ + log_config.do_maxscalelog = enabled; } @@ -2736,12 +2740,14 @@ static bool convert_priority_to_file(int priority, logfile_id_t* idp, const char } /** - * Enable a particular syslog priority. + * Enable/disable a particular syslog priority. * * @param priority One of the LOG_ERR etc. constants from sys/syslog.h. + * @param enabled True if the priority should be enabled, false if it to be disabled. + * * @return 0 if the priority was valid, -1 otherwise. */ -int mxs_log_enable_priority(int priority) +int mxs_log_set_priority_enabled(int priority, bool enabled) { int rv = -1; logfile_id_t id; @@ -2751,48 +2757,18 @@ int mxs_log_enable_priority(int priority) { if (!text) { - rv = skygw_log_enable(id); + if (enabled) + { + rv = skygw_log_enable(id); + } + else + { + rv = skygw_log_disable(id); + } } else { - // TODO: Change to warning when available. - MXS_DEBUG("Attempt to enable syslog priority %s, which is not available yet.", text); - rv = 0; - } - } - else - { - MXS_ERROR("Attempt to enable unknown syslog priority: %d", priority); - } - - return rv; -} - -/** - * Disable a particular syslog priority. - * - * @param priority One of the LOG_ERR etc. constants from sys/syslog.h. - * - * Note that there is no hierarchy. That is, disabling a priority of - * high importance, such as LOG_ERR, does not automatically disable - * all lower prioritys. - */ -int mxs_log_disable_priority(int priority) -{ - int rv = -1; - logfile_id_t id; - const char* text; - - if (convert_priority_to_file(priority, &id, &text)) - { - if (!text) - { - rv = skygw_log_disable(id); - } - else - { - // TODO: Change to warning when available. - MXS_DEBUG("Attempt to enable syslog priority %s, which is not available.", text); + MXS_WARNING("Attempt to enable syslog priority %s, which is not available yet.", text); rv = 0; } } @@ -2969,9 +2945,10 @@ int mxs_log_message(int priority, static const char FORMAT_FUNCTION[] = "(%s): "; + int augmentation = log_config.augmentation; // Other thread might change log_config.augmentation. int augmentation_len = 0; - switch (log_augmentation) + switch (augmentation) { case LOG_AUGMENT_WITH_FUNCTION: augmentation_len = sizeof(FORMAT_FUNCTION) - 1; // Remove trailing 0 @@ -3005,7 +2982,7 @@ int mxs_log_message(int priority, { int len = 0; - switch (log_augmentation) + switch (augmentation) { case LOG_AUGMENT_WITH_FUNCTION: len = sprintf(augmentation_text, FORMAT_FUNCTION, function); diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 35cab496d..fa4c79903 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -145,8 +145,11 @@ int mxs_log_flush(); int mxs_log_flush_sync(); int mxs_log_rotate(); -int mxs_log_enable_priority(int priority); -int mxs_log_disable_priority(int priority); +int mxs_log_set_priority_enabled(int priority, bool enabled); +void mxs_log_set_syslog_enabled(bool enabled); +void mxs_log_set_maxscalelog_enabled(bool enabled); +void mxs_log_set_highprecision_enabled(bool enabled); +void mxs_log_set_augmentation(int bits); int mxs_log_message(int priority, const char* file, int line, const char* function, @@ -154,9 +157,6 @@ int mxs_log_message(int priority, int skygw_log_enable(logfile_id_t id); int skygw_log_disable(logfile_id_t id); -void skygw_set_highp(int); -void logmanager_enable_syslog(int); -void logmanager_enable_maxscalelog(int); inline int mxs_log_id_to_priority(logfile_id_t id) { @@ -172,14 +172,6 @@ inline int mxs_log_id_to_priority(logfile_id_t id) #define skygw_log_write_flush(id, format, ...) skygw_log_write(id, format, ##__VA_ARGS__) -/** - * What augmentation if any should a logged message be augmented with. - * - * Currently this is a global setting and affects all loggers. - */ -void skygw_log_set_augmentation(int bits); -int skygw_log_get_augmentation(); - EXTERN_C_BLOCK_END /** diff --git a/server/core/config.c b/server/core/config.c index 8927def5d..8011e7ea7 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -1629,7 +1629,7 @@ handle_global_item(const char *name, const char *value) } else if (strcmp(name, "ms_timestamp") == 0) { - skygw_set_highp(config_truth_value((char*)value)); + mxs_log_set_highprecision_enabled(config_truth_value((char*)value)); } else if (strcmp(name, "auth_connect_timeout") == 0) { diff --git a/server/core/gateway.c b/server/core/gateway.c index 71cbb321c..f17e31fa6 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1713,8 +1713,9 @@ int main(int argc, char **argv) { printf("MaxScale logging is disabled.\n"); } - logmanager_enable_syslog(*syslog_enabled); - logmanager_enable_maxscalelog(*maxscalelog_enabled); + + mxs_log_set_syslog_enabled(*syslog_enabled); + mxs_log_set_maxscalelog_enabled(*maxscalelog_enabled); succp = mxs_log_init(NULL, get_logdir(), log_target); @@ -2342,7 +2343,7 @@ void set_log_augmentation(const char* value) if (!augmentation_set) { - skygw_log_set_augmentation(atoi(value)); + mxs_log_set_augmentation(atoi(value)); augmentation_set = true; } diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 086e63e71..8c8e0428f 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -126,7 +126,7 @@ int main(int argc, char **argv) { mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); - skygw_log_set_augmentation(0); + mxs_log_set_augmentation(0); if (!debug_out) skygw_log_disable(LOGFILE_DEBUG); diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 137f9e7bd..b3e846b57 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -1577,7 +1577,7 @@ static void enable_log_priority(DCB *dcb, char *arg1) if (priority != -1) { - mxs_log_enable_priority(priority); + mxs_log_set_priority_enabled(priority, true); } else { @@ -1595,7 +1595,7 @@ static void disable_log_priority(DCB *dcb, char *arg1) if (priority != -1) { - mxs_log_enable_priority(priority); + mxs_log_set_priority_enabled(priority, false); } else { From 1433d28f5ffd6bf2e13cdebd16734537269d53f9 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 13 Nov 2015 06:54:13 +0200 Subject: [PATCH 149/179] Added missing initialization for monitor parameters Monitor parameters were uninitialized and the pointer was used when the monitors were started. --- server/core/monitor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/core/monitor.c b/server/core/monitor.c index fd2852d23..3158f379a 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -84,6 +84,7 @@ MONITOR *mon; mon->write_timeout = DEFAULT_WRITE_TIMEOUT; mon->connect_timeout = DEFAULT_CONNECT_TIMEOUT; mon->interval = MONITOR_INTERVAL; + mon->parameters = NULL; spinlock_init(&mon->lock); spinlock_acquire(&monLock); mon->next = allMonitors; From 327c29849c2fbd4eb09117b9f2c08cb8f6d1f085 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 13 Nov 2015 10:39:21 +0200 Subject: [PATCH 150/179] Fixed spelling mistakes in documentation. --- Documentation/Changelog.md | 2 +- Documentation/Design-Documents/SchemaRouter-technical.md | 6 +++--- Documentation/Documentation-Contents.md | 2 +- Documentation/Filters/RabbitMQ-Consumer-Client.md | 2 +- Documentation/Filters/Regex-Filter.md | 2 +- Documentation/Getting-Started/Configuration-Guide.md | 2 +- Documentation/Reference/Debug-And-Diagnostic-Support.md | 2 +- Documentation/Reference/Hint-Syntax.md | 2 +- .../Reference/MaxScale-HA-with-Corosync-Pacemaker.md | 2 +- Documentation/Reference/MaxScale-HA-with-lsyncd.md | 8 ++++---- Documentation/Routers/ReadConnRoute.md | 4 ++-- Documentation/Tutorials/Administration-Tutorial.md | 2 +- .../Galera-Cluster-Read-Write-Splitting-Tutorial.md | 2 +- .../MySQL-Replication-Read-Write-Splitting-Tutorial.md | 2 +- Documentation/Tutorials/Nagios-Plugins.md | 4 ++-- Documentation/Tutorials/Notification-Service.md | 2 +- .../Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 2dbd116ea..fa304852f 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -10,7 +10,7 @@ These are the changes introduced in the next MaxScale version. This is not the o ## MaxScale 1.1.1 -* Schemarouter now also allows for an upper limit to session commans. +* Schemarouter now also allows for an upper limit to session commands. * Schemarouter correctly handles SHOW DATABASES responses that span multiple buffers. * Readwritesplit and Schemarouter now allow disabling of the session command history. diff --git a/Documentation/Design-Documents/SchemaRouter-technical.md b/Documentation/Design-Documents/SchemaRouter-technical.md index fc6e48f81..6c42e9563 100644 --- a/Documentation/Design-Documents/SchemaRouter-technical.md +++ b/Documentation/Design-Documents/SchemaRouter-technical.md @@ -4,19 +4,19 @@ This document is designed with a developer's point-of-view in mind. It explains ## Source Files and Data Structures -The schemarouter router consists of the schemarouter.h header file located in the `server/modules/include/` directory and the schemarouter.c file located in the `server/modules/routing/schemarouter` directory. This router implements the router interface defined in the router.h file. The entry points and structures this router uses can be found in the header file. The two main structures in use are the router instace and router session structures. The router instance structure is defined in `struct router_instance` and the router session structure in `struct router_client_session`. +The schemarouter router consists of the schemarouter.h header file located in the `server/modules/include/` directory and the schemarouter.c file located in the `server/modules/routing/schemarouter` directory. This router implements the router interface defined in the router.h file. The entry points and structures this router uses can be found in the header file. The two main structures in use are the router instance and router session structures. The router instance structure is defined in `struct router_instance` and the router session structure in `struct router_client_session`. The definitions of the external functions and all the internal functions of the router can be found in the schemarouter.c file. ## Router Lifecycle -When MaxScale first starts, it creates all services and thus creates the router instances of all the routers. The functions involved in this stage are ModuleInit, which is called only once when MaxScale first starts, and createInstance, called for each individual instace of this router in all the configured services. These functions read configuraion values and initialize internal data. +When MaxScale first starts, it creates all services and thus creates the router instances of all the routers. The functions involved in this stage are ModuleInit, which is called only once when MaxScale first starts, and createInstance, called for each individual instance of this router in all the configured services. These functions read configuration values and initialize internal data. When a user connects to MaxScale, a new session is created and the newSession function is called. At this point the client session connects to all the backend servers and initializes the list of databases. After the session is created queries are routed to the router's routeQuery function. This is where most of the work regarding the resolution of query destinations is done. This router parses the incoming buffers for full SQL packets first and routes each of them individually. The main internal functions involved in routing the query are get_shard_route_target (detects if a query needs to be sent to all the servers or to a specific one), get_shard_target_name (parses the query and finds the name of the right server) and route_session_write (handles sending and and storing session commands). After this point the client's query has been sent to the backend server and the router waits for either an response or an error signaling that the backend server is not responding. -If a response is received the clientReply function is called and response is simply sent to the client and the router is then ready for more queries. If there is no response from the server and the connection to it is lost the handleError function is called. This function tries to find replacement servers for the failed ones and regenerates the list of databases. This also triggeres the sending of an error packet to the client that notifies that the server is not responding. +If a response is received the clientReply function is called and response is simply sent to the client and the router is then ready for more queries. If there is no response from the server and the connection to it is lost the handleError function is called. This function tries to find replacement servers for the failed ones and regenerates the list of databases. This also triggers the sending of an error packet to the client that notifies that the server is not responding. After the session ends the closeSession is called where the session is set to a closed state after which the freeSession is called where the final freeing of memory is done. After this point the router's session has gone through all the stages of its lifecycle. diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 14248e222..527590b28 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -50,7 +50,7 @@ ## Routers - [Read Write Split](Routers/ReadWriteSplit.md) - - [Read Connnection Router](Routers/ReadConnRoute.md) + - [Read Connection Router](Routers/ReadConnRoute.md) - [Schemarouter](Routers/SchemaRouter.md) ## Filters diff --git a/Documentation/Filters/RabbitMQ-Consumer-Client.md b/Documentation/Filters/RabbitMQ-Consumer-Client.md index 324d8623e..1efd39507 100644 --- a/Documentation/Filters/RabbitMQ-Consumer-Client.md +++ b/Documentation/Filters/RabbitMQ-Consumer-Client.md @@ -14,7 +14,7 @@ The **RabbitMQ Consumer Client** only has one command line argument. ## Installation -To install the RabbitMQ Consumer Client you ca either use the provided packages or you can compile it from source code. The source code is included as a part of the MaxScale source code and can be found in the `rabbtmq_consumer` folder. Please refer to the [README](../../rabbitmq_consumer/README) in the folder for more detailed instructions about installation and configuration. +To install the RabbitMQ Consumer Client you ca either use the provided packages or you can compile it from source code. The source code is included as a part of the MaxScale source code and can be found in the `rabbitmq_consumer` folder. Please refer to the [README](../../rabbitmq_consumer/README) in the folder for more detailed instructions about installation and configuration. ## Configuration diff --git a/Documentation/Filters/Regex-Filter.md b/Documentation/Filters/Regex-Filter.md index ce0f54358..db99debdb 100644 --- a/Documentation/Filters/Regex-Filter.md +++ b/Documentation/Filters/Regex-Filter.md @@ -68,7 +68,7 @@ user=john ### `log_file` -The optional log_file parameter defines a log file in which the filter writes all queries that are not mached and maching queries with their replacement queries. All sessions will log to this file so this should only be used for diagnostic purposes. +The optional log_file parameter defines a log file in which the filter writes all queries that are not matched and matching queries with their replacement queries. All sessions will log to this file so this should only be used for diagnostic purposes. ``` log_file=/tmp/regexfilter.log diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index b41d51391..300a1db1c 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -978,7 +978,7 @@ filters=qla|fetch|from In addition to this, readwritesplit needs configuration for a listener, for all servers listed, and for each filter. Listener, server - and filter configurations are described in their own sections in this document. -An important parameter is the `max_slave_connections=50%` parameter. This sets the number of slaves each client connection will use. With the default values, client connections will only use a single slave for reads. For example, setting the parameter value to 100% will use all available slaves and read queries will be balanced evenly across all slaves. Changing the `max_slave_conections` parameter and `slave_selection_criteria` router option allows you to change the way MaxScale will balance reads. For more information about the `slave_selection_criteria` router option, please read the ReadWriteSplit documentation. +An important parameter is the `max_slave_connections=50%` parameter. This sets the number of slaves each client connection will use. With the default values, client connections will only use a single slave for reads. For example, setting the parameter value to 100% will use all available slaves and read queries will be balanced evenly across all slaves. Changing the `max_slave_connections` parameter and `slave_selection_criteria` router option allows you to change the way MaxScale will balance reads. For more information about the `slave_selection_criteria` router option, please read the ReadWriteSplit documentation. Below is a listener example for the "RWSplit Service" defined above: diff --git a/Documentation/Reference/Debug-And-Diagnostic-Support.md b/Documentation/Reference/Debug-And-Diagnostic-Support.md index 12298624c..e0b8ab505 100644 --- a/Documentation/Reference/Debug-And-Diagnostic-Support.md +++ b/Documentation/Reference/Debug-And-Diagnostic-Support.md @@ -1837,7 +1837,7 @@ MariaDB Corporation MaxScale /home/jdoe/bin/develop/log/skygw_msg1.log Tue Dec ### Trace log -Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OSs shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm//skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the /var/log/maxscale directory. +Trace log includes information about available servers and their states, client sessions, queries being executed, routing decisions and other routing related data. Trace log can be found from the same directory with other logs but it is physically stored elsewhere, to OS's shared memory to reduce the latency caused by logging. The location of physical file is : /dev/shm//skygw_traceX.log where ‘X’ is the same sequence number as in the file name in the /var/log/maxscale directory. Individual trace log entry looks similar to those in other logs but there is some difference too. Some log entries include a number within square brackets to specify which client session they belong to. For example: diff --git a/Documentation/Reference/Hint-Syntax.md b/Documentation/Reference/Hint-Syntax.md index 4f5d17f30..ef7ccfd51 100644 --- a/Documentation/Reference/Hint-Syntax.md +++ b/Documentation/Reference/Hint-Syntax.md @@ -29,7 +29,7 @@ The client connection will need to have comments enabled. For example the `mysql For comment types, use either `-- ` (notice the whitespace) or `#` after the semicolon or `/* .. */` before the semicolon. All comment types work with routing hints. The MySQL manual doesn`t specify if comment blocks, i.e. `/* .. */`, should contain a w -hitespace character before or after the tags, so adding whitespace at both the start and the end is advised. +whitespace character before or after the tags, so adding whitespace at both the start and the end is advised. ## Hint body diff --git a/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md b/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md index af6a897d3..873af6b68 100644 --- a/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md +++ b/Documentation/Reference/MaxScale-HA-with-Corosync-Pacemaker.md @@ -318,7 +318,7 @@ The script exit code for "status" is 0 Note: the MaxScale script is LSB compatible and returns the proper exit code for each action: -For additional informations; +For additional information; [http://www.linux-ha.org/wiki/LSB_Resource_Agents](http://www.linux-ha.org/wiki/LSB_Resource_Agents) diff --git a/Documentation/Reference/MaxScale-HA-with-lsyncd.md b/Documentation/Reference/MaxScale-HA-with-lsyncd.md index c9e6ac332..e8184ba6b 100644 --- a/Documentation/Reference/MaxScale-HA-with-lsyncd.md +++ b/Documentation/Reference/MaxScale-HA-with-lsyncd.md @@ -4,7 +4,7 @@ This document guides you in setting up multiple MaxScale instances and synchronizing the configuration files with lsyncd. Lsyncd is a rsync wrapper which can synchronize files across the network. The lsyncd daemon uses a configuration file to control the files to synchronize and the remote targets where these files are synchronized to. -Copying the configuration file and running the lsyncd daemon on all the hosts keeps all the configuration files in sync. Modifications in the configuration file on one of the hosts will be copied on the other hosts. This allows adinistrators to easily provide a highly available, disaster resistant MaxScale installation with up-to-date configuration files on all the hosts. +Copying the configuration file and running the lsyncd daemon on all the hosts keeps all the configuration files in sync. Modifications in the configuration file on one of the hosts will be copied on the other hosts. This allows administrators to easily provide a highly available, disaster resistant MaxScale installation with up-to-date configuration files on all the hosts. ### Requirements You will need: @@ -127,9 +127,9 @@ The most important part is the `sync` section which defines a target for synchro The `source` parameter tells lsyncd where to read the files from. This should be the location of the maxscale.cnf file. The `host` parameter defines the host where the files should be synchronized to and the user account lsyncd should use when synchronizing the files. The `targetdir` parameter defines the local directory on the remote target where the files should be synchronized to. This value should be the location on the remote host where the maxscale.cnf file is searched from. By default, this is the `/etc` folder. -The optional `ssh` parameter and its sub-parameter `port`define a custom port for the SSH connection. Most users do not need this parameterer. The `rsycn` parameter contains an arra of options that are passed to the rsycn executable. These should not be changed unless you specifically know what you are doing. For more information on the options passed to rsync read the rsync(1) manpage. +The optional `ssh` parameter and its sub-parameter `port`define a custom port for the SSH connection. Most users do not need this parameter. The `rsycn` parameter contains an array of options that are passed to the rsycn executable. These should not be changed unless you specifically know what you are doing. For more information on the options passed to rsync read the rsync(1) manpage. -You can add multiple remote targets by defining multiple `sync` sections. Here is an example with two sync sections defining different hosts that have MaxScale installed and whose configuration files should be kep in sync. +You can add multiple remote targets by defining multiple `sync` sections. Here is an example with two sync sections defining different hosts that have MaxScale installed and whose configuration files should be kept in sync. ``` settings{ @@ -167,7 +167,7 @@ rsync={ ## Starting Lsyncd -Starting lsyncd can be done from the command line or through a init script. To start syncd from the command like, execute the `lsyncd` command and pass the configuration file as the only parameter. +Starting lsyncd can be done from the command line or through a init script. To start lsyncd from the command like, execute the `lsyncd` command and pass the configuration file as the only parameter. By default lsyncd will search for the configuration file in `/etc/lsyncd.conf`. By placing the configuration file we created in the `/etc` folder, we can start lsyncd with the following command. diff --git a/Documentation/Routers/ReadConnRoute.md b/Documentation/Routers/ReadConnRoute.md index 50d5b80ae..c1994e439 100644 --- a/Documentation/Routers/ReadConnRoute.md +++ b/Documentation/Routers/ReadConnRoute.md @@ -1,6 +1,6 @@ # Readconnroute -This document provides anoverview of the **readconnroute** router module and its intended use case scenarios. It also displays all router configuration parameters with their descriptions. +This document provides an overview of the **readconnroute** router module and its intended use case scenarios. It also displays all router configuration parameters with their descriptions. ## Overview @@ -63,7 +63,7 @@ servers=server1,server2 weightby=serv_weight ``` -With this configuration and a heavy query load, the server *server1* will get most of the connections and about a third of the remaining queries are routed to the second server. With server weights, you can assing secondary servers that are only used when the primary server is under heavy load. +With this configuration and a heavy query load, the server *server1* will get most of the connections and about a third of the remaining queries are routed to the second server. With server weights, you can assign secondary servers that are only used when the primary server is under heavy load. Without the weightby parameter, each connection counts as a single connection. With a weighting parameter, a single connection received its weight from the server's own weighting parameter divided by the sum of all weighting parameters in all the configured servers. diff --git a/Documentation/Tutorials/Administration-Tutorial.md b/Documentation/Tutorials/Administration-Tutorial.md index b6ea00964..896c004e9 100644 --- a/Documentation/Tutorials/Administration-Tutorial.md +++ b/Documentation/Tutorials/Administration-Tutorial.md @@ -223,5 +223,5 @@ To bring the server back into service use the "clear server" command to clear th MaxScale> clear server dbserver3 maintenance MaxScale> ``` -Note that maintenance mode is not persistent, if MaxScale restarts when a node is in maintenance mode a new instance of MaxScale will not honour this mode. If multiple MaxScale instances are configured to use the node them maintenance mode must be set within each MaxScale instance. However if multiple services within one MaxScale instance are using the server then you only need set the maintenance mode once on the server for all services to take note of the mode change. +Note that maintenance mode is not persistent, if MaxScale restarts when a node is in maintenance mode a new instance of MaxScale will not honor this mode. If multiple MaxScale instances are configured to use the node them maintenance mode must be set within each MaxScale instance. However if multiple services within one MaxScale instance are using the server then you only need set the maintenance mode once on the server for all services to take note of the mode change. diff --git a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md index 18ca0f99c..d0f0b6594 100644 --- a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md @@ -154,7 +154,7 @@ This monitor module will assign one node within the Galera Cluster as the curren [Galera Monitor] type=monitor module=galeramon -diable_master_failback=1 +disable_master_failback=1 servers=dbserv1, dbserv2, dbserv3 user=maxscale passwd=96F99AA1315BDC3604B006F427DD9484 diff --git a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md index 577731b3e..572d9482b 100644 --- a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md @@ -150,7 +150,7 @@ port=3306 socket=/tmp/ClusterMaster ``` -An address parameter may be given if the listener is required to bind to a particular network address when using hosts with multiple network addresses. The default behaviour is to listen on all network interfaces. +An address parameter may be given if the listener is required to bind to a particular network address when using hosts with multiple network addresses. The default behavior is to listen on all network interfaces. The next stage is the configuration is to define the server information. This defines how to connect to each of the servers within the cluster, again a section is created for each server, with the type set to server, the network address and port to connect to and the protocol to use to connect to the server. Currently the protocol module for all database connections in MySQLBackend. ``` diff --git a/Documentation/Tutorials/Nagios-Plugins.md b/Documentation/Tutorials/Nagios-Plugins.md index 1a90ff74e..bf91baaf3 100644 --- a/Documentation/Tutorials/Nagios-Plugins.md +++ b/Documentation/Tutorials/Nagios-Plugins.md @@ -29,7 +29,7 @@ While MaxScale resources and status can be monitored via CLI using maxadmin comm ![Nagios and MaxScale interaction](images/HowMaxScaleWorksWithNagios.png) -There are three nagios plugin scripts that MaxScale provides. +There are three Nagios plugin scripts that MaxScale provides. 1. check_maxscale_threads.pl: This command provides you the status of current running threads and events in the queue on MaxScale Server. The Performance data associated with this command current and historic wait time for threads and events @@ -38,7 +38,7 @@ Current resources are: modules, services, listeners, servers, sessions, filters. 3. check_maxscale_monitor.pl: This command provides you status of the configured monitor modules on MaxScale server. -In order to use these scripts on your Nagios Server, you need to copy them from the MaxScale binary package or download them from source tree on github. +In order to use these scripts on your Nagios Server, you need to copy them from the MaxScale binary package or download them from source tree on GitHub. # MaxScale Nagios Plugin Requirements diff --git a/Documentation/Tutorials/Notification-Service.md b/Documentation/Tutorials/Notification-Service.md index 060b852c7..4ea40ef3a 100644 --- a/Documentation/Tutorials/Notification-Service.md +++ b/Documentation/Tutorials/Notification-Service.md @@ -53,7 +53,7 @@ MaxScale generates the feedback report containing following information: - MaxScale Version - An identifier of the MaxScale installation, i.e. the HEX encoding of SHA1 digest of the first network interface MAC address - Operating System (i.e Linux) - - Operating Suystem Distribution (i.e. CentOS release 6.5 (Final)) + - Operating System Distribution (i.e. CentOS release 6.5 (Final)) - All the modules in use in MaxScale and their API and version - MaxScale server UNIX_TIME at generation time diff --git a/Documentation/Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md b/Documentation/Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md index 7ffff76c2..f5a6b57af 100644 --- a/Documentation/Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md +++ b/Documentation/Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md @@ -364,7 +364,7 @@ If the consumer.cnf file is not in the same directory as the binary file is, you # ./consumer -c path/to/file ``` -and start maxScale as well +and start MaxScale as well ## Step 6 - Test the filter and check collected data From 76856e6c9080a2116b6a6bded65af4c5eceef35c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 13 Nov 2015 11:53:12 +0200 Subject: [PATCH 151/179] Fixed compiler warnings. --- server/core/secrets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/secrets.c b/server/core/secrets.c index cc23d312a..01cf66315 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -331,7 +331,7 @@ decryptPassword(const char *crypt) MAXKEYS *keys; AES_KEY aeskey; unsigned char *plain; - char *ptr; + const char *ptr; unsigned char encrypted[80]; int enlen; From 841ec695e440ce864ca2377676aee4281f38c135 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 13 Nov 2015 12:48:13 +0200 Subject: [PATCH 152/179] Incorrect error handling corrected. --- log_manager/log_manager.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index f81f9ef79..a3584c072 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -2651,13 +2651,16 @@ int mxs_log_flush_sync(void) if (lm) { flushall_logfiles(true); - err = skygw_message_send(lm->lm_logmes); - if (!err) + if (skygw_message_send(lm->lm_logmes) == MES_RC_SUCCESS) { // TODO: Add error handling to skygw_message_wait. Now void. skygw_message_wait(lm->lm_clientmes); } + else + { + err = -1; + } } return err; From 0b2e00118a9f5de1e7553db703497e274cdf3da3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 13 Nov 2015 16:38:22 +0200 Subject: [PATCH 153/179] Added missing initialization The service->protocol->listener was never initialized in serviceAddProtocol and caused a crash if the listener was not started. --- server/core/service.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/core/service.c b/server/core/service.c index 826c61bee..ccc599748 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -690,6 +690,7 @@ SERV_PROTOCOL *proto; { return 0; } + proto->listener = NULL; proto->protocol = strdup(protocol); if (address) proto->address = strdup(address); From b0c48c3f662bd6189208822f24d82303aade8928 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 11 Nov 2015 10:07:02 +0200 Subject: [PATCH 154/179] Updated config.c to use PCRE2 config.c now uses PCRE2 to clean up parameter values. --- server/core/config.c | 69 +++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/server/core/config.c b/server/core/config.c index 8011e7ea7..0d659dbd7 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -73,15 +73,11 @@ #include #include #include -#include #include #include #define PCRE2_CODE_UNIT_WIDTH 8 #include -/** According to the PCRE manual, this should be a multiple of 3 */ -#define MAXSCALE_PCRE_BUFSZ 24 - extern int setipaddress(struct in_addr *, char *); static int process_config_context(CONFIG_CONTEXT *); static int process_config_update(CONFIG_CONTEXT *); @@ -141,50 +137,63 @@ trim(char *str) */ char* config_clean_string_list(char* str) { - char *tmp; - - if ((tmp = malloc(sizeof(char) * (strlen(str) + 1))) != NULL) + char *dest; + size_t destsize = strlen(str) + 1; + if ((dest = malloc(destsize)) != NULL) { - char *ptr; - int match[MAXSCALE_PCRE_BUFSZ]; - pcre* re; - const char *re_err; - int err_offset, rval; + pcre2_code* re; + pcre2_match_data* data; + int re_err; + size_t err_offset; - tmp[0] = '\0'; - - if ((re = pcre_compile("\\s*+([^,]*[^,\\s])", 0, &re_err, &err_offset, NULL)) == NULL) + if ((re = pcre2_compile((PCRE2_SPTR) "[[:space:],]*([^,]+)\\b[[:space:],]*", PCRE2_ZERO_TERMINATED, 0, + &re_err, &err_offset, NULL)) == NULL || + (data = pcre2_match_data_create_from_pattern(re, NULL)) == NULL) { + PCRE2_UCHAR errbuf[STRERROR_BUFLEN]; + pcre2_get_error_message(re_err, errbuf, sizeof(errbuf)); skygw_log_write(LE, "[%s] Error: Regular expression compilation failed at %d: %s", - __FUNCTION__, err_offset, re_err); - free(tmp); + __FUNCTION__, err_offset, errbuf); + pcre2_code_free(re); + free(dest); return NULL; } - ptr = str; - - while ((rval = pcre_exec(re, NULL, ptr, strlen(ptr), 0, 0, (int*)&match, MAXSCALE_PCRE_BUFSZ)) > 1) + const char *replace = "$1,"; + int rval = 0; + while ((rval = pcre2_substitute(re, (PCRE2_SPTR) str, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_GLOBAL, data, NULL, + (PCRE2_SPTR) replace, PCRE2_ZERO_TERMINATED, + (PCRE2_UCHAR*) dest, &destsize)) == PCRE2_ERROR_NOMEMORY) { - const char* substr; - - pcre_get_substring(ptr, (int*)&match, rval, 1, &substr); - if (strlen(tmp) > 0) + char* tmp = realloc(dest, destsize * 2); + if (tmp == NULL) { - strcat(tmp, ","); + free(dest); + dest = NULL; + break; } - strcat(tmp, substr); - pcre_free_substring(substr); - ptr = &ptr[match[1]]; + dest = tmp; + destsize *= 2; } - pcre_free(re); + + /** Remove the trailing comma */ + if (dest && dest[strlen(dest) - 1] == ',') + { + dest[strlen(dest) - 1] = '\0'; + } + + pcre2_code_free(re); + pcre2_match_data_free(data); } else { skygw_log_write(LE, "[%s] Error: Memory allocation failed.", __FUNCTION__); } - return tmp; + return dest; } + /** * Config item handler for the ini file reader * From 86dcd1cc0f55addebcc92406fac754e593d3e61c Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 13 Nov 2015 14:26:43 +0200 Subject: [PATCH 155/179] LOGIF_MAYBE macros cleaned away. Used in few places and only obscured what was going on. --- log_manager/log_manager.h | 15 --------- server/core/dcb.c | 11 ++++--- server/core/poll.c | 64 ++++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index fa4c79903..51f7b2f14 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -83,14 +83,6 @@ typedef struct log_info #define LOG_MAY_BE_ENABLED(id) (((lm_enabled_logfiles_bitmask & id) || \ log_ses_count[id] > 0) ? true : false) -/** - * Execute the given command if specified log is enabled in general or - * if there is at least one session for whom the log is enabled. - */ -#define LOGIF_MAYBE(id,cmd) if (LOG_MAY_BE_ENABLED(id)) \ - { \ - cmd; \ - } /** * Execute the given command if specified log is enabled in general or @@ -101,13 +93,6 @@ typedef struct log_info cmd; \ } -#if !defined(LOGIF) -#define LOGIF(id,cmd) if (lm_enabled_logfiles_bitmask & id) \ - { \ - cmd; \ - } -#endif - /** * UNINIT means zeroed memory buffer allocated for the struct. * INIT means that struct members may have values, and memory may diff --git a/server/core/dcb.c b/server/core/dcb.c index 7dafccfd9..22d1b7b87 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -628,10 +628,13 @@ dcb_process_victim_queue(DCB *listofdcb) #endif /* FAKE_CODE */ } } - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } dcb->state = DCB_STATE_DISCONNECTED; nextdcb = dcb->memdata.next; diff --git a/server/core/poll.c b/server/core/poll.c index a88405029..0869b63f8 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -880,10 +880,13 @@ unsigned long qtime; if (eno == 0) { atomic_add(&pollStats.n_write, 1); /** Read session id to thread's local storage */ - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } + if (poll_dcb_session_check(dcb, "write_ready")) { dcb->func.write_ready(dcb); @@ -914,10 +917,14 @@ unsigned long qtime; dcb->fd))); atomic_add( &pollStats.n_accept, 1); - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } + if (poll_dcb_session_check(dcb, "accept")) { dcb->func.accept(dcb); @@ -934,10 +941,13 @@ unsigned long qtime; dcb->fd))); atomic_add(&pollStats.n_read, 1); /** Read session id to thread's local storage */ - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } + if (poll_dcb_session_check(dcb, "read")) { dcb->func.read(dcb); @@ -974,10 +984,12 @@ unsigned long qtime; } atomic_add(&pollStats.n_error, 1); /** Read session id to thread's local storage */ - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } if (poll_dcb_session_check(dcb, "error")) { dcb->func.error(dcb); @@ -1006,10 +1018,12 @@ unsigned long qtime; dcb->flags |= DCBF_HUNG; spinlock_release(&dcb->dcb_initlock); /** Read session id to thread's local storage */ - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } if (poll_dcb_session_check(dcb, "hangup EPOLLHUP")) { dcb->func.hangup(dcb); @@ -1042,10 +1056,12 @@ unsigned long qtime; dcb->flags |= DCBF_HUNG; spinlock_release(&dcb->dcb_initlock); /** Read session id to thread's local storage */ - LOGIF_MAYBE(LT, (dcb_get_ses_log_info( - dcb, - &tls_log_info.li_sesid, - &tls_log_info.li_enabled_logs))); + if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) + { + dcb_get_ses_log_info(dcb, + &tls_log_info.li_sesid, + &tls_log_info.li_enabled_logs); + } if (poll_dcb_session_check(dcb, "hangup EPOLLRDHUP")) { dcb->func.hangup(dcb); From 2dcdab29b6ef092a5dbcc73117930b89e3075496 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 13 Nov 2015 14:26:43 +0200 Subject: [PATCH 156/179] LOGIF_MAYBE macros cleaned away. Used in few places and only obscured what was going on. --- server/core/poll.c | 1 - 1 file changed, 1 deletion(-) diff --git a/server/core/poll.c b/server/core/poll.c index 0869b63f8..dfdfb53c5 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -917,7 +917,6 @@ unsigned long qtime; dcb->fd))); atomic_add( &pollStats.n_accept, 1); - if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) { dcb_get_ses_log_info(dcb, From bcb918e60b216ac0f1b2cf307d36010b377acfb6 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 13 Nov 2015 13:47:10 +0200 Subject: [PATCH 157/179] Log: Another step in the move from logfiles to priorities. skygw_[enable|disable]_log has now been removed from the external interface and priorities must instead be set using mxs_log_set_priority_enabled(int priority, bool enabled). A bitmask is already being updated, but internally and as used by the LOG_IF macros, the actual enabling is still made using logfile ids. The configuration entries have been replaced as follows: log_messages -> log_notice log_trace -> log_info The old ones can be used, but cause a warning to be logged. Similarily the maxadmin commands have been updated. "[enable|disable] log ..." works as expected, but there will be a message about it being deprecated. Instead there is now a [enable|disable] log-priority err|warning|notice|info|debug command that should be used instead. --- log_manager/log_manager.cc | 188 ++++++------------ log_manager/log_manager.h | 20 +- log_manager/test/testlog.c | 32 +++ log_manager/test/testorder.c | 32 +++ server/core/config.c | 30 +-- .../modules/routing/binlog/maxbinlogcheck.c | 7 +- .../modules/routing/binlog/test/testbinlog.c | 8 +- server/modules/routing/debugcmd.c | 159 +++++++-------- 8 files changed, 238 insertions(+), 238 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index a3584c072..3534f60e5 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -94,6 +94,12 @@ static struct */ int lm_enabled_logfiles_bitmask = 0; +/** + * Variable holding the enabled priorities information. + * Used from logging macros. + */ +int lm_enabled_priorities_bitmask = 0; + /** * Thread-specific struct variable for storing current session id and currently * enabled log files for the session. @@ -310,7 +316,6 @@ static char* blockbuf_get_writepos(blockbuf_t** p_bb, static void blockbuf_register(blockbuf_t* bb); static void blockbuf_unregister(blockbuf_t* bb); -static bool logfile_set_enabled(logfile_id_t id, bool val); static char* add_slash(char* str); static bool check_file_and_path(char* filename, @@ -318,7 +323,6 @@ static bool check_file_and_path(char* filename, bool do_log); static bool file_is_symlink(char* filename); -static int skygw_log_disable_raw(logfile_id_t id, bool emergency); /*< no locking */ static int find_last_seqno(strpart_t* parts, int seqno, int seqnoidx); void flushall_logfiles(bool flush); bool thr_flushall_check(); @@ -1150,7 +1154,7 @@ static blockbuf_t* blockbuf_init() } -int skygw_log_enable(logfile_id_t id) +static int skygw_log_enable(logfile_id_t id) { bool rval = -1; @@ -1158,14 +1162,11 @@ int skygw_log_enable(logfile_id_t id) { CHK_LOGMANAGER(lm); - if (logfile_set_enabled(id, true)) - { - lm->lm_enabled_logfiles |= id; - /** - * Set global variable - */ - lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; - } + lm->lm_enabled_logfiles |= id; + /** + * Set global variable + */ + lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; logmanager_unregister(); rval = 0; @@ -1174,12 +1175,7 @@ int skygw_log_enable(logfile_id_t id) return rval; } -int skygw_log_disable(logfile_id_t id) /*< no locking */ -{ - return skygw_log_disable_raw(id, false); -} - -static int skygw_log_disable_raw(logfile_id_t id, bool emergency) /*< no locking */ +static int skygw_log_disable(logfile_id_t id) { bool rval = -1; @@ -1187,14 +1183,11 @@ static int skygw_log_disable_raw(logfile_id_t id, bool emergency) /*< no locking { CHK_LOGMANAGER(lm); - if (emergency || logfile_set_enabled(id, false)) - { - lm->lm_enabled_logfiles &= ~id; - /** - * Set global variable - */ - lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; - } + lm->lm_enabled_logfiles &= ~id; + /** + * Set global variable + */ + lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; logmanager_unregister(); rval = 0; @@ -1204,64 +1197,6 @@ static int skygw_log_disable_raw(logfile_id_t id, bool emergency) /*< no locking } -static bool logfile_set_enabled(logfile_id_t id, bool val) -{ - bool rval = false; - - CHK_LOGMANAGER(lm); - - if (logmanager_is_valid_id(id)) - { - if (!log_config.use_stdout) - { - const char *name; - - switch (id) - { - default: - case LOGFILE_ERROR: - name = "LOGFILE_ERROR"; - break; - - case LOGFILE_MESSAGE: - name = "LOGFILE_MESSAGE"; - break; - - case LOGFILE_TRACE: - name = "LOGFILE_TRACE"; - break; - - case LOGFILE_DEBUG: - name = "LOGFILE_DEBUG"; - break; - } - - const char FORMAT[] = "The logging of %s messages is %s."; - const char *action; - - if (val) - { - action = "enabled"; - } - else - { - action = "disabled"; - } - - MXS_NOTICE(FORMAT, name, action); - } - - rval = true; - } - else - { - MXS_ERROR("Invalid logfile id %d.", id); - ss_dassert(!true); - } - - return rval; -} - /** * Set log augmentation. * @@ -2309,7 +2244,7 @@ static bool thr_flush_file(logmanager_t *lm, filewriter_t *fwr) err, strerror_r(err, errbuf, sizeof(errbuf))); /** Force log off */ - skygw_log_disable_raw(LOGFILE_ERROR, true); + skygw_log_disable(LOGFILE_ERROR); } /** * Reset buffer's counters and mark @@ -2702,44 +2637,50 @@ int mxs_log_rotate() return err; } -static bool convert_priority_to_file(int priority, logfile_id_t* idp, const char** textp) +static logfile_id_t priority_to_file_id(int priority) { - bool converted = true; - - *idp = (logfile_id_t) -1; - *textp = NULL; - switch (priority) { case LOG_DEBUG: - *idp = LOGFILE_DEBUG; - break; + return LOGFILE_DEBUG; case LOG_INFO: - *idp = LOGFILE_TRACE; - break; + return LOGFILE_TRACE; case LOG_NOTICE: - *idp = LOGFILE_MESSAGE; - break; + return LOGFILE_MESSAGE; case LOG_ERR: - *idp = LOGFILE_ERROR; - break; case LOG_WARNING: - *textp = "LOG_WARNING"; - break; case LOG_CRIT: - *textp = "LOG_CRIT"; - break; case LOG_ALERT: - *textp = "LOG_ALERT"; - break; case LOG_EMERG: - *textp = "LOG_EMERG"; - break; default: - converted = false; + return LOGFILE_ERROR; } +} - return converted; +static const char* priority_name(int priority) +{ + switch (priority) + { + case LOG_EMERG: + return "emercency"; + case LOG_ALERT: + return "alert"; + case LOG_CRIT: + return "critical"; + case LOG_ERR: + return "error"; + case LOG_WARNING: + return "warning"; + case LOG_NOTICE: + return "notice"; + case LOG_INFO: + return "informational"; + case LOG_DEBUG: + return "debug"; + default: + assert(!true); + return "unknown"; + } } /** @@ -2750,34 +2691,33 @@ static bool convert_priority_to_file(int priority, logfile_id_t* idp, const char * * @return 0 if the priority was valid, -1 otherwise. */ -int mxs_log_set_priority_enabled(int priority, bool enabled) +int mxs_log_set_priority_enabled(int priority, bool enable) { int rv = -1; - logfile_id_t id; - const char* text; + const char* text = (enable ? "enable" : "disable"); - if (convert_priority_to_file(priority, &id, &text)) + if ((priority & ~LOG_PRIMASK) == 0) { - if (!text) + logfile_id_t id = priority_to_file_id(priority); + int bit = (1 << priority); + + if (enable) { - if (enabled) - { - rv = skygw_log_enable(id); - } - else - { - rv = skygw_log_disable(id); - } + // TODO: Put behind spinlock. + lm_enabled_priorities_bitmask |= bit; + skygw_log_enable(id); } else { - MXS_WARNING("Attempt to enable syslog priority %s, which is not available yet.", text); - rv = 0; + lm_enabled_priorities_bitmask &= ~bit; + skygw_log_disable(id); } + + MXS_NOTICE("The logging of %s messages has been %sd.", priority_name(priority), text); } else { - MXS_ERROR("Attempt to enable unknown syslog priority: %d", priority); + MXS_ERROR("Attempt to %s unknown syslog priority %d.", text, priority); } return rv; diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index 51f7b2f14..cec3b12df 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -27,6 +27,21 @@ #define STRERROR_BUFLEN 512 #endif +enum mxs_log_priorities +{ + MXS_LOG_EMERG = (1 << LOG_EMERG), + MXS_LOG_ALERT = (1 << LOG_ALERT), + MXS_LOG_CRIT = (1 << LOG_CRIT), + MXS_LOG_ERR = (1 << LOG_ERR), + MXS_LOG_WARNING = (1 << LOG_WARNING), + MXS_LOG_NOTICE = (1 << LOG_NOTICE), + MXS_LOG_INFO = (1 << LOG_INFO), + MXS_LOG_DEBUG = (1 << LOG_DEBUG), + + MXS_LOG_MASK = (MXS_LOG_EMERG | MXS_LOG_ALERT | MXS_LOG_CRIT | MXS_LOG_ERR | + MXS_LOG_WARNING | MXS_LOG_NOTICE | MXS_LOG_INFO | MXS_LOG_DEBUG), +}; + typedef enum { BB_READY = 0x00, @@ -80,7 +95,6 @@ typedef struct log_info (log_ses_count[id] > 0 && \ tls_log_info.li_enabled_logs & id)) ? true : false) - #define LOG_MAY_BE_ENABLED(id) (((lm_enabled_logfiles_bitmask & id) || \ log_ses_count[id] > 0) ? true : false) @@ -119,6 +133,7 @@ typedef enum EXTERN_C_BLOCK_BEGIN +extern int lm_enabled_priorities_bitmask; extern int lm_enabled_logfiles_bitmask; extern ssize_t log_ses_count[]; extern __thread log_info_t tls_log_info; @@ -140,9 +155,6 @@ int mxs_log_message(int priority, const char* file, int line, const char* function, const char* format, ...); -int skygw_log_enable(logfile_id_t id); -int skygw_log_disable(logfile_id_t id); - inline int mxs_log_id_to_priority(logfile_id_t id) { if (id & LOGFILE_ERROR) return LOG_ERR; diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index ddf1c410a..df44490d1 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -62,6 +62,38 @@ const int N_THR = 4; #define TEST_ERROR(msg)\ do { fprintf(stderr, "[%s:%d]: %s\n", basename(__FILE__), __LINE__, msg); } while (false) +static logfile_id_t id_to_priority(logfile_id_t id) +{ + switch (id) + { + case LOGFILE_ERROR: + return LOG_ERR; + + case LOGFILE_MESSAGE: + return LOG_NOTICE; + + case LOGFILE_TRACE: + return LOG_INFO; + + case LOGFILE_DEBUG: + return LOG_DEBUG; + + default: + assert(!true); + return LOG_ERR; + } +} + +static void skygw_log_enable(logfile_id_t id) +{ + mxs_log_set_priority_enabled(id_to_priority(id), true); +} + +static void skygw_log_disable(logfile_id_t id) +{ + mxs_log_set_priority_enabled(id_to_priority(id), false); +} + int main(int argc, char* argv[]) { int err = 0; diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 06494cfdd..6514ecf76 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -23,6 +23,38 @@ #include #include +static logfile_id_t id_to_priority(logfile_id_t id) +{ + switch (id) + { + case LOGFILE_ERROR: + return LOG_ERR; + + case LOGFILE_MESSAGE: + return LOG_NOTICE; + + case LOGFILE_TRACE: + return LOG_INFO; + + case LOGFILE_DEBUG: + return LOG_DEBUG; + + default: + assert(!true); + return LOG_ERR; + } +} + +static void skygw_log_enable(logfile_id_t id) +{ + mxs_log_set_priority_enabled(id_to_priority(id), true); +} + +static void skygw_log_disable(logfile_id_t id) +{ + mxs_log_set_priority_enabled(id_to_priority(id), false); +} + int main(int argc, char** argv) { int iterations = 0, i, interval = 10; diff --git a/server/core/config.c b/server/core/config.c index 0d659dbd7..5dc866898 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -1596,12 +1596,16 @@ config_get_feedback_data() static struct { - char *logname; - logfile_id_t logfile; + char* name; + int priority; + char* replacement; } lognames[] = { - { "log_messages", LOGFILE_MESSAGE }, - { "log_trace", LOGFILE_TRACE }, - { "log_debug", LOGFILE_DEBUG }, + { "log_messages", LOG_NOTICE, "log_notice" }, // Deprecated + { "log_trace", LOG_INFO, "log_info" }, // Deprecated + { "log_debug", LOG_DEBUG, NULL }, + { "log_warning", LOG_WARNING, NULL }, + { "log_notice", LOG_NOTICE, NULL }, + { "log_info", LOG_INFO, NULL }, { NULL, 0 } }; /** @@ -1681,18 +1685,18 @@ handle_global_item(const char *name, const char *value) } else { - for (i = 0; lognames[i].logname; i++) + for (i = 0; lognames[i].name; i++) { - if (strcasecmp(name, lognames[i].logname) == 0) + if (strcasecmp(name, lognames[i].name) == 0) { - if (config_truth_value((char*)value)) + if (lognames[i].replacement) { - skygw_log_enable(lognames[i].logfile); - } - else - { - skygw_log_disable(lognames[i].logfile); + MXS_WARNING("In the configuration file the use of '%s' is deprecated, " + "use '%s' instead.", + lognames[i].name, lognames[i].replacement); } + + mxs_log_set_priority_enabled(lognames[i].priority, config_truth_value((char*)value)); } } } diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 8c8e0428f..3116bc845 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -125,13 +125,8 @@ int main(int argc, char **argv) { num_args = optind; mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); - mxs_log_set_augmentation(0); - - if (!debug_out) - skygw_log_disable(LOGFILE_DEBUG); - else - skygw_log_enable(LOGFILE_DEBUG); + mxs_log_set_priority_enabled(LOG_DEBUG, debug_out); if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, diff --git a/server/modules/routing/binlog/test/testbinlog.c b/server/modules/routing/binlog/test/testbinlog.c index ee4609517..257994351 100644 --- a/server/modules/routing/binlog/test/testbinlog.c +++ b/server/modules/routing/binlog/test/testbinlog.c @@ -91,10 +91,10 @@ int main(int argc, char **argv) { mxs_log_init(NULL, NULL, LOG_TARGET_DEFAULT); - skygw_log_disable(LOGFILE_DEBUG); - skygw_log_disable(LOGFILE_TRACE); - skygw_log_disable(LOGFILE_ERROR); - skygw_log_disable(LOGFILE_MESSAGE); + mxs_log_set_priority_enabled(LOG_DEBUG, false); + mxs_log_set_priority_enabled(LOG_INFO, false); + mxs_log_set_priority_enabled(LOG_NOTICE, false); + mxs_log_set_priority_enabled(LOG_ERR, false); service = service_alloc("test_service", "binlogrouter"); service->credentials.name = strdup("foo"); diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 51dbbf6cb..b21e31b47 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -410,22 +410,20 @@ struct subcommand enableoptions[] = { "log", 1, enable_log_action, - "Enable Log options for MaxScale, options trace | error | " - "message E.g. enable log message.", - "Enable Log options for MaxScale, options trace | error | " - "message E.g. enable log message.", + "[deprecated] Enable Log options for MaxScale, options 'trace' | 'error' | 'message'." + "E.g. 'enable log message'.", + "[deprecated] Enable Log options for MaxScale, options 'trace' | 'error' | 'message'." + "E.g. 'enable log message'.", {ARG_TYPE_STRING, 0, 0} }, { "log-priority", 1, enable_log_priority, - "Enable log priority for MaxScale; options LOG_ERR | " - "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " - "E.g.: enable log-priority LOG_INFO.", - "Enable log priority for MaxScale; options LOG_ERR | " - "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " - "E.g.: enable log-priority LOG_INFO.", + "Enable a logging priority; options 'err' | 'warning' | 'notice' | 'info' | 'debug'. " + "E.g.: 'enable log-priority info'.", + "Enable a logging priority; options 'err' | 'warning' | 'notice' | 'info' | 'debug'. " + "E.g.: 'enable log-priority info'.", {ARG_TYPE_STRING, 0, 0} }, { @@ -482,22 +480,20 @@ struct subcommand disableoptions[] = { "log", 1, disable_log_action, - "Disable Log for MaxScale, Options: debug | trace | error | message " - "E.g. disable log debug", - "Disable Log for MaxScale, Options: debug | trace | error | message " - "E.g. disable log debug", + "[deprecated] Disable Log for MaxScale, Options: 'debug' | 'trace' | 'error' | 'message'." + "E.g. 'disable log debug'.", + "[deprecated] Disable Log for MaxScale, Options: 'debug' | 'trace' | 'error' | 'message'." + "E.g. 'disable log debug'.", {ARG_TYPE_STRING, 0, 0} }, { "log-priority", 1, disable_log_priority, - "Disable log priority for MaxScale; options LOG_ERR | " - "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " - "E.g.: enable log-priority LOG_INFO.", - "Disable log priority for MaxScale; options LOG_ERR | " - "LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG. " - "E.g.: enable log-priority LOG_INFO.", + "Disable a logging priority; options 'err' | 'warning' | 'notice' | 'info' | 'debug'. " + "E.g.: 'disable log-priority info'.", + "Disable a logging priority; options 'err' | 'warning' | 'notice' | 'info' | 'debug'. " + "E.g.: 'disable log-priority info'.", {ARG_TYPE_STRING, 0, 0} }, { @@ -962,7 +958,7 @@ execute_cmd(CLI_SESSION *cli) dcb_printf(dcb, "Available options to the %s command:\n", args[1]); for (j = 0; cmds[i].options[j].arg1; j++) { - dcb_printf(dcb, " %-10s %s\n", cmds[i].options[j].arg1, + dcb_printf(dcb, " %-12s %s\n", cmds[i].options[j].arg1, cmds[i].options[j].help); } } @@ -1449,98 +1445,87 @@ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2) dcb_printf(dcb, "Session not found: %s\n", arg2); } +struct log_action_entry +{ + const char* name; + int priority; + const char* replacement; +}; + +static bool get_log_action(const char* name, struct log_action_entry* entryp) +{ + static const struct log_action_entry entries[] = + { + { "debug", LOG_DEBUG, "debug" }, + { "trace", LOG_INFO, "info" }, + { "message", LOG_NOTICE, "notice" }, + { "error", LOG_ERR, "err" } + }; + const int n_entries = sizeof(entries) / sizeof(entries[0]); + + bool found = false; + int i = 0; + + while (!found && (i < n_entries)) + { + if (strcmp(name, entries[i].name) == 0) + { + *entryp = entries[i]; + found = true; + } + + ++i; + } + + return found; +} + /** * The log enable action */ - static void enable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type = -1; - int max_len = strlen("message"); - const char* priority; + struct log_action_entry entry; - if (strncmp(arg1, "debug", max_len) == 0) + if (get_log_action(arg1, &entry)) { - type = LOGFILE_DEBUG; - priority = "LOG_DEBUG"; - } - else if (strncmp(arg1, "trace", max_len) == 0) - { - type = LOGFILE_TRACE; - priority = "LOG_INFO"; - } - else if (strncmp(arg1, "error", max_len) == 0) - { - type = LOGFILE_ERROR; - priority = "LOG_ERR"; - } - else if (strncmp(arg1, "message", max_len) == 0) - { - type = LOGFILE_MESSAGE; - priority = "LOG_NOTICE"; - } + mxs_log_set_priority_enabled(entry.priority, true); - if (type != -1) - { - skygw_log_enable(type); dcb_printf(dcb, "'enable log %s' is accepted but deprecated, use 'enable log-priority %s' instead.\n", - arg1, priority); + arg1, entry.replacement); } else { - dcb_printf(dcb, "%s is not supported for enable log\n", arg1); + dcb_printf(dcb, "'%s' is not supported for enable log\n", arg1); } } /** * The log disable action */ - static void disable_log_action(DCB *dcb, char *arg1) { - logfile_id_t type = -1; - int max_len = strlen("message"); - const char* priority; + struct log_action_entry entry; - if (strncmp(arg1, "debug", max_len) == 0) + if (get_log_action(arg1, &entry)) { - type = LOGFILE_DEBUG; - priority = "LOG_DEBUG"; - } - else if (strncmp(arg1, "trace", max_len) == 0) - { - type = LOGFILE_TRACE; - priority = "LOG_INFO"; - } - else if (strncmp(arg1, "error", max_len) == 0) - { - type = LOGFILE_ERROR; - priority = "LOG_ERR"; - } - else if (strncmp(arg1, "message", max_len) == 0) - { - type = LOGFILE_MESSAGE; - priority = "LOG_NOTICE"; - } + mxs_log_set_priority_enabled(entry.priority, false); - if (type != -1) - { - skygw_log_disable(type); dcb_printf(dcb, - "'disable log %s' is accepted but deprecated, use 'disable log-priority %s' instead.\n", - arg1, priority); + "'disable log %s' is accepted but deprecated, use 'enable log-priority %s' instead.\n", + arg1, entry.replacement); } else { - dcb_printf(dcb, "%s is not supported for disable log\n", arg1); + dcb_printf(dcb, "'%s' is not supported for 'disable log'\n", arg1); } } struct log_priority_entry { - int priority; const char* name; + int priority; }; static int compare_log_priority_entries(const void* l, const void* r) @@ -1556,16 +1541,16 @@ static int string_to_priority(const char* name) static const struct log_priority_entry LOG_PRIORITY_ENTRIES[] = { // NOTE: If you make changes to this array, ensure that it remains alphabetically ordered. - { LOG_DEBUG, "LOG_DEBUG" }, - { LOG_ERR, "LOG_ERR" }, - { LOG_INFO, "LOG_INFO" }, - { LOG_NOTICE, "LOG_NOTICE" }, - { LOG_WARNING, "LOG_WARNING" }, + { "debug", LOG_DEBUG }, + { "err", LOG_ERR }, + { "info", LOG_INFO }, + { "notice", LOG_NOTICE }, + { "warning", LOG_WARNING }, }; const size_t N_LOG_PRIORITY_ENTRIES = sizeof(LOG_PRIORITY_ENTRIES) / sizeof(LOG_PRIORITY_ENTRIES[0]); - struct log_priority_entry key = { -1, name }; + struct log_priority_entry key = { name, -1 }; struct log_priority_entry* result = bsearch(&key, LOG_PRIORITY_ENTRIES, N_LOG_PRIORITY_ENTRIES, @@ -1589,7 +1574,7 @@ static void enable_log_priority(DCB *dcb, char *arg1) } else { - dcb_printf(dcb, "%s is not a supported log priority\n", arg1); + dcb_printf(dcb, "'%s' is not a supported log priority\n", arg1); } } @@ -1607,7 +1592,7 @@ static void disable_log_priority(DCB *dcb, char *arg1) } else { - dcb_printf(dcb, "%s is not a supported log priority\n", arg1); + dcb_printf(dcb, "'%s' is not a supported log priority\n", arg1); } } From b8fda016c93440e3220636cffcbd2b7bfc4debcf Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Sat, 14 Nov 2015 23:07:44 +0200 Subject: [PATCH 158/179] Log: Some cleanup. Stuff that does not need to be in the header moved to the implementation file. --- log_manager/log_manager.cc | 32 ++++++++++++++++++++--- log_manager/log_manager.h | 53 ++++++++++---------------------------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 3534f60e5..81b386d66 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -49,6 +49,35 @@ static const char LOGFILE_NAME_SUFFIX[] = ".log"; extern char *program_invocation_name; extern char *program_invocation_short_name; +typedef enum +{ + BB_READY = 0x00, + BB_FULL, + BB_CLEARED +} blockbuf_state_t; + +typedef enum +{ + FILEWRITER_INIT, + FILEWRITER_RUN, + FILEWRITER_DONE +} filewriter_state_t; + +/** + * UNINIT means zeroed memory buffer allocated for the struct. + * INIT means that struct members may have values, and memory may + * have been allocated. Done function must check and free it. + * RUN Struct is valid for run-time checking. + * DONE means that possible memory allocations have been released. + */ +typedef enum +{ + UNINIT = 0, + INIT, + RUN, + DONE +} flat_obj_state_t; + /** * LOG_FLUSH_NO Do not flush after writing. * LOG_FLUSH_YES Flush after writing. @@ -124,9 +153,6 @@ ssize_t log_ses_count[LOGFILE_LAST] = {0}; */ const char* shm_pathname_prefix = "/dev/shm/"; -/** Errors are written to syslog too by default */ -char* syslog_id_str = strdup("LOGFILE_ERROR"); - /** Forward declarations */ typedef struct filewriter filewriter_t; diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index cec3b12df..e5984bb7a 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -16,10 +16,14 @@ * Copyright MariaDB Corporation Ab 2013-2014 */ #if !defined(LOG_MANAGER_H) -# define LOG_MANAGER_H +#define LOG_MANAGER_H #include +#if defined(__cplusplus) +extern "C" { +#endif + /* * We need a common.h file that is included by every component. */ @@ -42,13 +46,6 @@ enum mxs_log_priorities MXS_LOG_WARNING | MXS_LOG_NOTICE | MXS_LOG_INFO | MXS_LOG_DEBUG), }; -typedef enum -{ - BB_READY = 0x00, - BB_FULL, - BB_CLEARED -} blockbuf_state_t; - typedef enum { LOGFILE_ERROR = 1, @@ -59,13 +56,6 @@ typedef enum LOGFILE_LAST = LOGFILE_DEBUG } logfile_id_t; -typedef enum -{ - FILEWRITER_INIT, - FILEWRITER_RUN, - FILEWRITER_DONE -} filewriter_state_t; - typedef enum { LOG_TARGET_DEFAULT = 0, @@ -87,6 +77,11 @@ typedef struct log_info #define LT LOGFILE_TRACE #define LD LOGFILE_DEBUG +extern int lm_enabled_priorities_bitmask; +extern int lm_enabled_logfiles_bitmask; +extern ssize_t log_ses_count[]; +extern __thread log_info_t tls_log_info; + /** * Check if specified log type is enabled in general or if it is enabled * for the current session. @@ -107,21 +102,6 @@ typedef struct log_info cmd; \ } -/** - * UNINIT means zeroed memory buffer allocated for the struct. - * INIT means that struct members may have values, and memory may - * have been allocated. Done function must check and free it. - * RUN Struct is valid for run-time checking. - * DONE means that possible memory allocations have been released. - */ -typedef enum -{ - UNINIT = 0, - INIT, - RUN, - DONE -} flat_obj_state_t; - /** * LOG_AUGMENT_WITH_FUNCTION Each logged line is suffixed with [function-name]. */ @@ -131,13 +111,6 @@ typedef enum LOG_AUGMENTATION_MASK = (LOG_AUGMENT_WITH_FUNCTION) } log_augmentation_t; -EXTERN_C_BLOCK_BEGIN - -extern int lm_enabled_priorities_bitmask; -extern int lm_enabled_logfiles_bitmask; -extern ssize_t log_ses_count[]; -extern __thread log_info_t tls_log_info; - bool mxs_log_init(const char* ident, const char* logdir, log_target_t target); void mxs_log_finish(void); @@ -169,8 +142,6 @@ inline int mxs_log_id_to_priority(logfile_id_t id) #define skygw_log_write_flush(id, format, ...) skygw_log_write(id, format, ##__VA_ARGS__) -EXTERN_C_BLOCK_END - /** * Helper, not to be called directly. */ @@ -189,4 +160,8 @@ EXTERN_C_BLOCK_END #define MXS_INFO(format, ...) MXS_LOG_MESSAGE(LOG_INFO, format, ##__VA_ARGS__) #define MXS_DEBUG(format, ...) MXS_LOG_MESSAGE(LOG_DEBUG, format, ##__VA_ARGS__) +#if defined(__cplusplus) +} +#endif + #endif /** LOG_MANAGER_H */ From 1f15843d61dae099f0cda98403b8701fbfa7d877 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sun, 8 Nov 2015 16:19:46 +0200 Subject: [PATCH 159/179] Refactored schemarouter to use the resultset.h data types and functions The generated responses to SHOW DATABASES are now generated by using the resultset.h data types and functions. --- .../routing/schemarouter/schemarouter.c | 254 +++++------------- 1 file changed, 71 insertions(+), 183 deletions(-) diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 3bf85d16c..8dc7ec873 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -1818,7 +1818,40 @@ void check_create_tmp_table( int cmpfn(const void* a, const void *b) { - return strcmp(*(char**)a,*(char**)b); + return strcmp(*(char* const *)a,*(char* const *)b); +} + +/** Internal structure used to stream the list of databases */ +struct string_array +{ + char** array; + int position; + int size; +}; + +/** + * Callback for the database list streaming. + * @param rset Result set which is being processed + * @param data Pointer to struct string_array containing the database names + * @return New resultset row or NULL if no more data is available. If memory allocation + * failed, NULL is returned. + */ +RESULT_ROW *result_set_cb(struct resultset * rset, void *data) +{ + RESULT_ROW *row = NULL; + struct string_array *strarray = (struct string_array*) data; + ss_dassert(strarray->position < strarray->size); + + if ((row = resultset_make_row(rset))) + { + if (resultset_row_set(row, 0, strarray->array[strarray->position++]) == 0) + { + resultset_free_row(row); + row = NULL; + } + } + + return row; } /** @@ -1827,190 +1860,48 @@ int cmpfn(const void* a, const void *b) * in it. * @param router Router instance * @param client Router client session - * @return Pointer to new GWBUF containing the custom result set + * @return True if the sending of the database list was successful, otherwise false */ -GWBUF* -gen_show_dbs_response(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client) +bool send_database_list(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client) { - GWBUF* rval = NULL; - backend_ref_t *bref = client->rses_backend_ref; - BACKEND** backends = router->servers; - unsigned int coldef_len = 0; - int i; - char dbname[MYSQL_DATABASE_MAXLEN + 1]; - char *value; - unsigned char* ptr; - char catalog[4] = {0x03, 'd', 'e', 'f'}; - const char* schema = "information_schema"; - const char* table = "SCHEMATA"; - const char* org_table = "SCHEMATA"; - const char* name = "Database"; - const char* org_name = "SCHEMA_NAME"; - char next_length = 0x0c; - char charset[2] = {0x21, 0x00}; - char column_length[4] = {MYSQL_DATABASE_MAXLEN, - MYSQL_DATABASE_MAXLEN >> 8, - MYSQL_DATABASE_MAXLEN >> 16, - MYSQL_DATABASE_MAXLEN >> 24}; - char column_type = 0xfd; - - char eof[9] = {0x05, 0x00, 0x00, - 0x03, 0xfe, 0x00, - 0x00, 0x22, 0x00}; -#if defined(NOT_USED) - char ok_packet[11] = {0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00}; -#endif - - coldef_len = sizeof(catalog) + strlen(schema) + 1 + - strlen(table) + 1 + - strlen(org_table) + 1 + - strlen(name) + 1 + - strlen(org_name) + 1 + - 1 + 2 + 4 + 1 + 2 + 1 + 2; - - - rval = gwbuf_alloc(5 + 4 + coldef_len + sizeof(eof)); - - ptr = rval->start; - - /**First packet*/ - - *ptr++ = 0x01; - *ptr++ = 0x00; - *ptr++ = 0x00; - *ptr++ = 0x01; - *ptr++ = 0x01; - - /**Second packet containing the column definitions*/ - - *ptr++ = coldef_len; - *ptr++ = coldef_len >> 8; - *ptr++ = coldef_len >> 16; - *ptr++ = 0x02; - - memcpy((void*) ptr, catalog, 4); - ptr += 4; - - *ptr++ = strlen(schema); - memcpy((void*) ptr, schema, strlen(schema)); - ptr += strlen(schema); - - *ptr++ = strlen(table); - memcpy((void*) ptr, table, strlen(table)); - ptr += strlen(table); - - *ptr++ = strlen(org_table); - memcpy((void*) ptr, org_table, strlen(org_table)); - ptr += strlen(org_table); - - *ptr++ = strlen(name); - memcpy((void*) ptr, name, strlen(name)); - ptr += strlen(name); - - *ptr++ = strlen(org_name); - memcpy((void*) ptr, org_name, strlen(org_name)); - ptr += strlen(org_name); - - *ptr++ = next_length; - *ptr++ = charset[0]; - *ptr++ = charset[1]; - *ptr++ = column_length[0]; - *ptr++ = column_length[1]; - *ptr++ = column_length[2]; - *ptr++ = column_length[3]; - *ptr++ = column_type; - *ptr++ = 0x01; - memset(ptr, 0, 4); - ptr += 4; - - memcpy(ptr, eof, sizeof(eof)); - - unsigned int packet_num = 4; - int j = 0,ndbs = 0, bufsz = 10; - char** dbs; - - if((dbs = malloc(sizeof(char*) * bufsz)) == NULL) - { - gwbuf_free(rval); - return NULL; - } - + bool rval = false; spinlock_acquire(&client->shardmap->lock); - - if(client->shardmap->state == SHMAP_READY) + if (client->shardmap->state == SHMAP_READY) { - HASHTABLE* ht = client->shardmap->hash; - HASHITERATOR* iter = hashtable_iterator(ht); + struct string_array strarray; + const int size = hashtable_size(client->shardmap->hash); + strarray.array = malloc(size * sizeof(char*)); + strarray.position = 0; + HASHITERATOR *iter = hashtable_iterator(client->shardmap->hash); + RESULTSET* resultset = resultset_create(result_set_cb, &strarray); - while((value = (char*) hashtable_next(iter))) + if (strarray.array && iter && resultset) { - char* bend = hashtable_fetch(ht, value); - for(i = 0; backends[i]; i++) + char *key; + int i = 0; + while ((key = hashtable_next(iter))) { - if(strcmp(bref[i].bref_backend->backend_server->unique_name, bend) == 0 && - BREF_IS_IN_USE(&bref[i]) && !BREF_IS_CLOSED(&bref[i])) + char *value = hashtable_fetch(client->shardmap->hash, key); + SERVER * server = server_find_by_unique_name(value); + if (SERVER_IS_RUNNING(server)) { - ndbs++; - if(ndbs >= bufsz) - { - bufsz += bufsz / 2; - char** tmp = realloc(dbs,sizeof(char*) * bufsz); - if(tmp == NULL) - { - gwbuf_free(rval); - hashtable_iterator_free(iter); - for (i = 0; i < ndbs - 1; i++) - { - free(dbs[i]); - } - free(dbs); - spinlock_release(&client->shardmap->lock); - return NULL; - } - dbs = tmp; - } - dbs[j++] = strdup(value); + strarray.array[i++] = key; } } + strarray.size = i; + qsort(strarray.array, strarray.size, sizeof(char*), cmpfn); + if (resultset_add_column(resultset, "Database", MYSQL_DATABASE_MAXLEN, + COL_TYPE_VARCHAR)) + { + resultset_stream_mysql(resultset, client->rses_client_dcb); + rval = true; + } } + resultset_free(resultset); hashtable_iterator_free(iter); + free(strarray.array); } - spinlock_release(&client->shardmap->lock); - - qsort(&dbs[0],(size_t)ndbs,sizeof(char*),cmpfn); - - for(j = 0;jstart; - *ptr++ = plen; - *ptr++ = plen >> 8; - *ptr++ = plen >> 16; - *ptr++ = packet_num++; - *ptr++ = plen - 1; - memcpy(ptr, dbname, plen - 1); - - /** Append the row*/ - rval = gwbuf_append(rval, temp); - free(dbs[j]); - } - - eof[3] = packet_num; - - GWBUF* last_packet = gwbuf_alloc(sizeof(eof)); - memcpy(last_packet->start, eof, sizeof(eof)); - rval = gwbuf_append(rval, last_packet); - free(dbs); return rval; } @@ -2306,18 +2197,15 @@ static int routeQuery( } } - if(QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_DATABASES)) - { - /** - * Generate custom response that contains all the databases - */ - - GWBUF* fake = gen_show_dbs_response(inst,router_cli_ses); - poll_add_epollin_event_to_dcb(router_cli_ses->dcb_reply,fake); - ret = 1; - - goto retblock; - } + /** Create the response to the SHOW DATABASES from the mapped databases */ + if (QUERY_IS_TYPE(qtype, QUERY_TYPE_SHOW_DATABASES)) + { + if (send_database_list(inst, router_cli_ses)) + { + ret = 1; + } + goto retblock; + } route_target = get_shard_route_target(qtype, router_cli_ses->rses_transaction_active, From 44df53d84611d1a5c551c2bde49f0cfc234ebd68 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Sun, 15 Nov 2015 19:37:15 +0200 Subject: [PATCH 160/179] LOGIF and skygw_write_log removed from server/core/*.c LOGIF and skygw_write_log removed from server/core/*.c and replaced with calls to MXS_(ERROR|WARNING|NOTICE|INFO|DEBUG). This is a mechanism change, no updating of the actual message has been performed. Currently this causes a very small performance hit, since the check whether the priority is enabled or not is performed in the function that is called and not before the function is called. Once all LOGIFs and skygw_write_logs have been replaced, the behaviour will be altered back to what it was. --- server/core/adminusers.c | 115 +++---- server/core/buffer.c | 30 +- server/core/config.c | 455 +++++++++++-------------- server/core/dbusers.c | 704 +++++++++++++++----------------------- server/core/dcb.c | 715 +++++++++++++++++---------------------- server/core/externcmd.c | 16 +- server/core/filter.c | 10 +- server/core/gateway.c | 216 +++++------- server/core/gw_utils.c | 36 +- server/core/load_utils.c | 191 ++++------- server/core/modutil.c | 17 +- server/core/monitor.c | 59 ++-- server/core/poll.c | 257 ++++++-------- server/core/secrets.c | 146 ++++---- server/core/server.c | 48 ++- server/core/service.c | 209 +++++------- server/core/session.c | 109 +++--- server/core/users.c | 6 +- server/core/utils.c | 20 +- 19 files changed, 1367 insertions(+), 1992 deletions(-) diff --git a/server/core/adminusers.c b/server/core/adminusers.c index 9a344f0b2..310d741b7 100644 --- a/server/core/adminusers.c +++ b/server/core/adminusers.c @@ -159,19 +159,13 @@ char fname[1024], *home, *cpasswd; fname[1023] = '\0'; if (users == NULL) { - LOGIF(LM, - (skygw_log_write(LOGFILE_MESSAGE, - "Create initial password file."))); + MXS_NOTICE("Create initial password file."); if ((users = users_alloc()) == NULL) return ADMIN_ERR_NOMEM; if ((fp = fopen(fname, "w")) == NULL) { - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to create password file %s.", - fname))); + MXS_ERROR("Unable to create password file %s.", fname); return ADMIN_ERR_PWDFILEOPEN; } fclose(fp); @@ -184,10 +178,7 @@ char fname[1024], *home, *cpasswd; users_add(users, uname, cpasswd); if ((fp = fopen(fname, "a")) == NULL) { - LOGIF(LE, - (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Unable to append to password file %s.", - fname))); + MXS_ERROR("Unable to append to password file %s.", fname); return ADMIN_ERR_FILEAPPEND; } fprintf(fp, "%s:%s\n", uname, cpasswd); @@ -219,19 +210,14 @@ char* admin_remove_user( int n_deleted; if (!admin_search_user(uname)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Couldn't find user %s. Removing user failed", - uname))); - return ADMIN_ERR_USERNOTFOUND; + MXS_ERROR("Couldn't find user %s. Removing user failed.", uname); + return ADMIN_ERR_USERNOTFOUND; } if (admin_verify(uname, passwd) == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Authentication failed, wrong user/password " - "combination. Removing user failed."))); - return ADMIN_ERR_AUTHENTICATION; + MXS_ERROR("Authentication failed, wrong user/password " + "combination. Removing user failed."); + return ADMIN_ERR_AUTHENTICATION; } @@ -239,11 +225,9 @@ char* admin_remove_user( n_deleted = users_delete(users, uname); if (n_deleted == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Deleting the only user is forbidden. Add new " - "user before deleting the one."))); - return ADMIN_ERR_DELLASTUSER; + MXS_ERROR("Deleting the only user is forbidden. Add new " + "user before deleting the one."); + return ADMIN_ERR_DELLASTUSER; } /** * Open passwd file and remove user from the file. @@ -258,13 +242,11 @@ char* admin_remove_user( if ((fp = fopen(fname, "r")) == NULL) { int err = errno; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to open password file %s : errno %d.\n" - "Removing user from file failed; it must be done " - "manually.", - fname, - err))); + MXS_ERROR("Unable to open password file %s : errno %d.\n" + "Removing user from file failed; it must be done " + "manually.", + fname, + err); return ADMIN_ERR_PWDFILEOPEN; } /** @@ -273,13 +255,11 @@ char* admin_remove_user( if ((fp_tmp = fopen(fname_tmp, "w")) == NULL) { int err = errno; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to open tmp file %s : errno %d.\n" - "Removing user from passwd file failed; it must be done " - "manually.", - fname_tmp, - err))); + MXS_ERROR("Unable to open tmp file %s : errno %d.\n" + "Removing user from passwd file failed; it must be done " + "manually.", + fname_tmp, + err); fclose(fp); return ADMIN_ERR_TMPFILEOPEN; } @@ -289,13 +269,11 @@ char* admin_remove_user( */ if (fgetpos(fp, &rpos) != 0) { int err = errno; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to process passwd file %s : errno %d.\n" - "Removing user from file failed, and must be done " - "manually.", - fname, - err))); + MXS_ERROR("Unable to process passwd file %s : errno %d.\n" + "Removing user from file failed, and must be done " + "manually.", + fname, + err); fclose(fp); fclose(fp_tmp); unlink(fname_tmp); @@ -309,26 +287,21 @@ char* admin_remove_user( * Unmatching lines are copied to tmp file. */ if (strncmp(uname, fusr, strlen(uname)+1) != 0) { - if(fsetpos(fp, &rpos) != 0){ /** one step back */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to set stream position. "))); - - } - fgets(line, LINELEN, fp); - fputs(line, fp_tmp); + if(fsetpos(fp, &rpos) != 0){ /** one step back */ + MXS_ERROR("Unable to set stream position. "); + } + fgets(line, LINELEN, fp); + fputs(line, fp_tmp); } if (fgetpos(fp, &rpos) != 0) { int err = errno; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to process passwd file %s : " - "errno %d.\n" - "Removing user from file failed, and must be " - "done manually.", - fname, - err))); + MXS_ERROR("Unable to process passwd file %s : " + "errno %d.\n" + "Removing user from file failed, and must be " + "done manually.", + fname, + err); fclose(fp); fclose(fp_tmp); unlink(fname_tmp); @@ -341,14 +314,12 @@ char* admin_remove_user( */ if (rename(fname_tmp, fname)) { int err = errno; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to rename new passwd file %s : errno " - "%d.\n" - "Rename it to %s manually.", - fname_tmp, - err, - fname))); + MXS_ERROR("Unable to rename new passwd file %s : errno " + "%d.\n" + "Rename it to %s manually.", + fname_tmp, + err, + fname); unlink(fname_tmp); fclose(fp_tmp); return ADMIN_ERR_PWDFILEACCESS; diff --git a/server/core/buffer.c b/server/core/buffer.c index e8a1d9100..fe50f0303 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -124,10 +124,8 @@ retblock: if (rval == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); } #if defined(BUFFER_TRACE) else @@ -299,10 +297,8 @@ GWBUF *rval; { ss_dassert(rval != NULL); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); return NULL; } @@ -367,10 +363,8 @@ GWBUF *gwbuf_clone_portion( { ss_dassert(clonebuf != NULL); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); return NULL; } atomic_add(&buf->sbuf->refcount, 1); @@ -625,10 +619,8 @@ void gwbuf_add_buffer_object( if (newb == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); return; } newb->bo_id = id; @@ -716,10 +708,8 @@ BUF_PROPERTY *prop; { ss_dassert(prop != NULL); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); return 0; } prop->name = strdup(name); diff --git a/server/core/config.c b/server/core/config.c index 5dc866898..fe88b4b26 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -152,8 +152,8 @@ char* config_clean_string_list(char* str) { PCRE2_UCHAR errbuf[STRERROR_BUFLEN]; pcre2_get_error_message(re_err, errbuf, sizeof(errbuf)); - skygw_log_write(LE, "[%s] Error: Regular expression compilation failed at %d: %s", - __FUNCTION__, err_offset, errbuf); + MXS_ERROR("[%s] Regular expression compilation failed at %d: %s", + __FUNCTION__, err_offset, errbuf); pcre2_code_free(re); free(dest); return NULL; @@ -188,7 +188,7 @@ char* config_clean_string_list(char* str) } else { - skygw_log_write(LE, "[%s] Error: Memory allocation failed.", __FUNCTION__); + MXS_ERROR("[%s] Memory allocation failed.", __FUNCTION__); } return dest; @@ -254,7 +254,7 @@ handler(void *userdata, const char *section, const char *name, const char *value if ((tmp = realloc(p1->value, sizeof(char) * (paramlen))) == NULL) { - skygw_log_write(LE, "[%s] Error: Memory allocation failed.", __FUNCTION__); + MXS_ERROR("[%s] Memory allocation failed.", __FUNCTION__); return 0; } strcat(tmp, ","); @@ -262,7 +262,7 @@ handler(void *userdata, const char *section, const char *name, const char *value if ((p1->value = config_clean_string_list(tmp)) == NULL) { p1->value = tmp; - skygw_log_write(LE, "[%s] Error: Cleaning configuration parameter failed.", __FUNCTION__); + MXS_ERROR("[%s] Cleaning configuration parameter failed.", __FUNCTION__); return 0; } free(tmp); @@ -366,7 +366,7 @@ config_load(char *file) "Error: Failed to parse configuration file. Memory allocation failed."); } - skygw_log_write(LE, errorbuffer); + MXS_ERROR("%s", errorbuffer); return 0; } @@ -443,7 +443,7 @@ process_config_context(CONFIG_CONTEXT *context) if ((monitorhash = hashtable_alloc(5, simple_str_hash, strcmp)) == NULL) { - skygw_log_write(LOGFILE_ERROR, "Error: Failed to allocate, monitor configuration check hashtable."); + MXS_ERROR("Failed to allocate, monitor configuration check hashtable."); return 0; } hashtable_memory_fns(monitorhash, (HASHMEMORYFN)strdup, NULL, (HASHMEMORYFN)free, NULL); @@ -458,10 +458,7 @@ process_config_context(CONFIG_CONTEXT *context) char *type = config_get_value(obj->parameters, "type"); if (type == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object '%s' has no type.", - obj->object))); + MXS_ERROR("Configuration object '%s' has no type.", obj->object); error_count++; } else if (!strcmp(type, "service")) @@ -543,13 +540,11 @@ process_config_context(CONFIG_CONTEXT *context) if (obj->element == NULL) /*< if module load failed */ { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Reading configuration " - "for router service '%s' failed. " - "Router %s is not loaded.", - obj->object, - obj->object))); + MXS_ERROR("Reading configuration " + "for router service '%s' failed. " + "Router %s is not loaded.", + obj->object, + obj->object); obj = obj->next; continue; /*< process next obj */ } @@ -584,50 +579,50 @@ process_config_context(CONFIG_CONTEXT *context) if (ssl_cert == NULL) { error_count++; - skygw_log_write(LE, "Error: Server certificate missing for service '%s'." - "Please provide the path to the server certificate by adding " - "the ssl_cert= parameter", obj->object); + MXS_ERROR("Server certificate missing for service '%s'." + "Please provide the path to the server certificate by adding " + "the ssl_cert= parameter", obj->object); } if (ssl_ca_cert == NULL) { error_count++; - skygw_log_write(LE, "Error: CA Certificate missing for service '%s'." - "Please provide the path to the certificate authority " - "certificate by adding the ssl_ca_cert= parameter", - obj->object); + MXS_ERROR("CA Certificate missing for service '%s'." + "Please provide the path to the certificate authority " + "certificate by adding the ssl_ca_cert= parameter", + obj->object); } if (ssl_key == NULL) { error_count++; - skygw_log_write(LE, "Error: Server private key missing for service '%s'. " - "Please provide the path to the server certificate key by " - "adding the ssl_key= parameter", - obj->object); + MXS_ERROR("Server private key missing for service '%s'. " + "Please provide the path to the server certificate key by " + "adding the ssl_key= parameter", + obj->object); } if (access(ssl_ca_cert, F_OK) != 0) { - skygw_log_write(LE, "Error: Certificate authority file for service '%s' " - "not found: %s", - obj->object, ssl_ca_cert); + MXS_ERROR("Certificate authority file for service '%s' " + "not found: %s", + obj->object, ssl_ca_cert); error_count++; } if (access(ssl_cert, F_OK) != 0) { - skygw_log_write(LE, "Error: Server certificate file for service '%s' not found: %s", - obj->object, - ssl_cert); + MXS_ERROR("Server certificate file for service '%s' not found: %s", + obj->object, + ssl_cert); error_count++; } if (access(ssl_key, F_OK) != 0) { - skygw_log_write(LE, "Error: Server private key file for service '%s' not found: %s", - obj->object, - ssl_key); + MXS_ERROR("Server private key file for service '%s' not found: %s", + obj->object, + ssl_key); error_count++; } @@ -635,8 +630,8 @@ process_config_context(CONFIG_CONTEXT *context) { if (serviceSetSSL(obj->element, ssl) != 0) { - skygw_log_write(LE, "Error: Unknown parameter for service '%s': %s", - obj->object, ssl); + MXS_ERROR("Unknown parameter for service '%s': %s", + obj->object, ssl); error_count++; } else @@ -646,9 +641,9 @@ process_config_context(CONFIG_CONTEXT *context) { if (serviceSetSSLVersion(obj->element, ssl_version) != 0) { - skygw_log_write(LE, "Error: Unknown parameter value for " - "'ssl_version' for service '%s': %s", - obj->object, ssl_version); + MXS_ERROR("Unknown parameter value for " + "'ssl_version' for service '%s': %s", + obj->object, ssl_version); error_count++; } } @@ -656,9 +651,9 @@ process_config_context(CONFIG_CONTEXT *context) { if (serviceSetSSLVerifyDepth(obj->element, atoi(ssl_cert_verify_depth)) != 0) { - skygw_log_write(LE, "Error: Invalid parameter value for " - "'ssl_cert_verify_depth' for service '%s': %s", - obj->object, ssl_cert_verify_depth); + MXS_ERROR("Invalid parameter value for " + "'ssl_cert_verify_depth' for service '%s': %s", + obj->object, ssl_cert_verify_depth); error_count++; } } @@ -716,12 +711,10 @@ process_config_context(CONFIG_CONTEXT *context) } else if (user && auth == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Service '%s' has a " - "user defined but no " - "corresponding password.", - obj->object))); + MXS_ERROR("Service '%s' has a " + "user defined but no " + "corresponding password.", + obj->object); } /** Read, validate and set max_slave_connections */ if (max_slave_conn_str != NULL) @@ -747,17 +740,15 @@ process_config_context(CONFIG_CONTEXT *context) if (!succp) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is either for slave connection " - "count or\n\t%% for specifying the " - "maximum percentage of available the " - "slaves that will be connected.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); + MXS_WARNING("Invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is either for slave connection " + "count or\n\t%% for specifying the " + "maximum percentage of available the " + "slaves that will be connected.", + ((SERVICE*)obj->element)->name, + param->name, + param->value); } } /** Read, validate and set max_slave_replication_lag */ @@ -786,15 +777,13 @@ process_config_context(CONFIG_CONTEXT *context) if (!succp) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is for maximum " - "slave replication lag.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); + MXS_WARNING("Invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is for maximum " + "slave replication lag.", + ((SERVICE*)obj->element)->name, + param->name, + param->value); } } /** Parameters for rwsplit router only */ @@ -829,21 +818,17 @@ process_config_context(CONFIG_CONTEXT *context) { if(param) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is [master|all] for " - "use sql variables in.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); + MXS_WARNING("Invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is [master|all] for " + "use sql variables in.", + ((SERVICE*)obj->element)->name, + param->name, + param->value); } else { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : parameter was NULL"))); + MXS_ERROR("Parameter was NULL"); } } } @@ -852,11 +837,7 @@ process_config_context(CONFIG_CONTEXT *context) else { obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No router defined for service " - "'%s'\n", - obj->object))); + MXS_ERROR("No router defined for service '%s'.", obj->object); error_count++; } } @@ -884,14 +865,12 @@ process_config_context(CONFIG_CONTEXT *context) else { obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' is missing a " - "required configuration parameter. A " - "server must " - "have address, port and protocol " - "defined.", - obj->object))); + MXS_ERROR("Server '%s' is missing a " + "required configuration parameter. A " + "server must " + "have address, port and protocol " + "defined.", + obj->object); error_count++; } @@ -901,11 +880,9 @@ process_config_context(CONFIG_CONTEXT *context) } else if (monuser && monpw == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' has a monitoruser" - "defined but no corresponding password.", - obj->object))); + MXS_ERROR("Server '%s' has a monitoruser" + "defined but no corresponding password.", + obj->object); } if (obj->element) @@ -945,11 +922,9 @@ process_config_context(CONFIG_CONTEXT *context) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Filter '%s' has no module " - "defined defined to load.", - obj->object))); + MXS_ERROR("Filter '%s' has no module " + "defined defined to load.", + obj->object); error_count++; } @@ -1023,25 +998,21 @@ process_config_context(CONFIG_CONTEXT *context) if (!found) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " - "server '%s' that is " - "configured as part of " - "service '%s'.", - s, obj->object))); + MXS_ERROR("Unable to find " + "server '%s' that is " + "configured as part of " + "service '%s'.", + s, obj->object); } s = strtok_r(NULL, ",", &lasts); } } else if (servers == NULL && !isInternalService(router)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning: The service '%s' is missing a " - "definition of the servers that provide " - "the service.", - obj->object))); + MXS_WARNING("The service '%s' is missing a " + "definition of the servers that provide " + "the service.", + obj->object); } if (roptions && obj->element) @@ -1099,12 +1070,10 @@ process_config_context(CONFIG_CONTEXT *context) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s', " - "service '%s' not found. " - "Listener will not execute for socket %s.", - obj->object, service, socket))); + MXS_ERROR("Listener '%s', " + "service '%s' not found. " + "Listener will not execute for socket %s.", + obj->object, service, socket); error_count++; } } @@ -1123,25 +1092,21 @@ process_config_context(CONFIG_CONTEXT *context) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s', " - "service '%s' not found. " - "Listener will not execute.", - obj->object, service))); + MXS_ERROR("Listener '%s', " + "service '%s' not found. " + "Listener will not execute.", + obj->object, service); error_count++; } } } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Listener '%s' is missing a " - "required " - "parameter. A Listener must have a " - "service, port and protocol defined.", - obj->object))); + MXS_ERROR("Listener '%s' is missing a " + "required " + "parameter. A Listener must have a " + "service, port and protocol defined.", + obj->object); error_count++; } } @@ -1200,9 +1165,9 @@ process_config_context(CONFIG_CONTEXT *context) } else { - skygw_log_write(LOGFILE_ERROR, "Warning: Monitor '%s' " - "missing monitor_interval parameter, " - "default value of 10000 miliseconds.", obj->object); + MXS_WARNING("Monitor '%s' " + "missing monitor_interval parameter, " + "default value of 10000 miliseconds.", obj->object); } /* set timeouts */ @@ -1232,10 +1197,9 @@ process_config_context(CONFIG_CONTEXT *context) found = 1; if (hashtable_add(monitorhash, obj1->object, "") == 0) { - skygw_log_write(LOGFILE_ERROR, - "Warning: Multiple monitors are monitoring server [%s]. " - "This will cause undefined behavior.", - obj1->object); + MXS_WARNING("Multiple monitors are monitoring server [%s]. " + "This will cause undefined behavior.", + obj1->object); } monitorAddServer(obj->element, obj1->element); } @@ -1243,14 +1207,11 @@ process_config_context(CONFIG_CONTEXT *context) } if (!found) { - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " + MXS_ERROR("Unable to find " "server '%s' that is " "configured in the " "monitor '%s'.", - s, obj->object))); + s, obj->object); } s = strtok_r(NULL, ",", &lasts); @@ -1264,32 +1225,26 @@ process_config_context(CONFIG_CONTEXT *context) } else if (obj->element && user) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, "Error: " - "Monitor '%s' defines a " - "username with no password.", - obj->object))); + MXS_ERROR("Monitor '%s' defines a " + "username with no password.", + obj->object); error_count++; } } else { obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor '%s' is missing a " - "require module parameter.", - obj->object))); + MXS_ERROR("Monitor '%s' is missing a " + "require module parameter.", + obj->object); error_count++; } } else if (strcmp(type, "server") != 0 && strcmp(type, "filter") != 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object '%s' has an " - "invalid type specified.", - obj->object))); + MXS_ERROR("Configuration object '%s' has an " + "invalid type specified.", + obj->object); error_count++; } @@ -1305,12 +1260,10 @@ process_config_context(CONFIG_CONTEXT *context) if (error_count) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : %d errors where encountered processing the " - "configuration file '%s'.", - error_count, - config_file))); + MXS_ERROR("%d errors where encountered processing the " + "configuration file '%s'.", + error_count, + config_file); return 0; } @@ -1628,7 +1581,7 @@ handle_global_item(const char *name, const char *value) } else { - skygw_log_write(LE, "Warning: Invalid value for 'threads': %s.", value); + MXS_WARNING("Invalid value for 'threads': %s.", value); return 0; } } @@ -1654,7 +1607,7 @@ handle_global_item(const char *name, const char *value) } else { - skygw_log_write(LE, "Invalid timeout value for 'auth_connect_timeout': %s", value); + MXS_WARNING("Invalid timeout value for 'auth_connect_timeout': %s", value); } } else if (strcmp(name, "auth_read_timeout") == 0) @@ -1667,7 +1620,7 @@ handle_global_item(const char *name, const char *value) } else { - skygw_log_write(LE, "Invalid timeout value for 'auth_read_timeout': %s", value); + MXS_ERROR("Invalid timeout value for 'auth_read_timeout': %s", value); } } else if (strcmp(name, "auth_write_timeout") == 0) @@ -1680,7 +1633,7 @@ handle_global_item(const char *name, const char *value) } else { - skygw_log_write(LE, "Invalid timeout value for 'auth_write_timeout': %s", value); + MXS_ERROR("Invalid timeout value for 'auth_write_timeout': %s", value); } } else @@ -1834,11 +1787,7 @@ process_config_update(CONFIG_CONTEXT *context) char *type = config_get_value(obj->parameters, "type"); if (type == NULL) { - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object %s has no type.", - obj->object))); + MXS_ERROR("Configuration object %s has no type.", obj->object); } else if (!strcmp(type, "service")) { @@ -1963,17 +1912,15 @@ process_config_update(CONFIG_CONTEXT *context) if (!succp && param != NULL) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is either for slave connection " - "count or\n\t%% for specifying the " - "maximum percentage of available the " - "slaves that will be connected.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); + MXS_WARNING("Invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is either for slave connection " + "count or\n\t%% for specifying the " + "maximum percentage of available the " + "slaves that will be connected.", + ((SERVICE*)obj->element)->name, + param->name, + param->value); } } /** Read, validate and set max_slave_replication_lag */ @@ -2003,22 +1950,19 @@ process_config_update(CONFIG_CONTEXT *context) if (!succp) { - if(param){ - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "* Warning : invalid value type " - "for parameter \'%s.%s = %s\'\n\tExpected " - "type is for maximum " - "slave replication lag.", - ((SERVICE*)obj->element)->name, - param->name, - param->value))); + if (param) + { + MXS_WARNING("Invalid value type " + "for parameter \'%s.%s = %s\'\n\tExpected " + "type is for maximum " + "slave replication lag.", + ((SERVICE*)obj->element)->name, + param->name, + param->value); } else { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : parameter was NULL"))); + MXS_ERROR("Parameter was NULL"); } } } @@ -2074,11 +2018,7 @@ process_config_update(CONFIG_CONTEXT *context) else { obj->element = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No router defined for service " - "'%s'.", - obj->object))); + MXS_ERROR("No router defined for service '%s'.", obj->object); } } else if (!strcmp(type, "server")) @@ -2123,14 +2063,12 @@ process_config_update(CONFIG_CONTEXT *context) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Server '%s' is missing a " - "required " - "configuration parameter. A server must " - "have address, port and protocol " - "defined.", - obj->object))); + MXS_ERROR("Server '%s' is missing a " + "required " + "configuration parameter. A server must " + "have address, port and protocol " + "defined.", + obj->object); } } obj = obj->next; @@ -2181,13 +2119,11 @@ process_config_update(CONFIG_CONTEXT *context) } if (!found) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Unable to find " - "server '%s' that is " - "configured as part of " - "service '%s'.", - s, obj->object))); + MXS_ERROR("Unable to find " + "server '%s' that is " + "configured as part of " + "service '%s'.", + s, obj->object); } s = strtok_r(NULL, ",", &lasts); } @@ -2261,11 +2197,7 @@ process_config_update(CONFIG_CONTEXT *context) strcmp(type, "monitor") != 0 && strcmp(type, "filter") != 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Configuration object %s has an invalid " - "type specified.", - obj->object))); + MXS_ERROR("Configuration object %s has an invalid type specified.", obj->object); } obj = obj->next; } @@ -2389,14 +2321,12 @@ check_config_objects(CONFIG_CONTEXT *context) if (found == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unexpected parameter " - "'%s' for object '%s' of type " - "'%s'.", - params->name, - obj->object, - type))); + MXS_ERROR("Unexpected parameter " + "'%s' for object '%s' of type " + "'%s'.", + params->name, + obj->object, + type); } params = params->next; } @@ -2472,7 +2402,7 @@ config_truth_value(char *str) { return 0; } - skygw_log_write(LOGFILE_ERROR, "Error: Not a boolean value: %s", str); + MXS_ERROR("Not a boolean value: %s", str); return -1; } @@ -2745,32 +2675,26 @@ config_enable_feedback_task(void) /* Add the task to the tasl list */ if (hktask_add("send_feedback", module_feedback_send, cfg, cfg->feedback_frequency)) { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Notification service feedback task started: URL=%s, User-Info=%s, " - "Frequency %u seconds", - cfg->feedback_url, - cfg->feedback_user_info, - cfg->feedback_frequency))); + MXS_NOTICE("Notification service feedback task started: URL=%s, User-Info=%s, " + "Frequency %u seconds", + cfg->feedback_url, + cfg->feedback_user_info, + cfg->feedback_frequency); } } else { if (enable_set) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Notification service feedback cannot start: feedback_enable=1 but" - " some required parameters are not set: %s%s%s", - url_set == 0 ? "feedback_url is not set" : "", - (user_info_set == 0 && url_set == 0) ? ", " : "", - user_info_set == 0 ? "feedback_user_info is not set" : ""))); + MXS_ERROR("Notification service feedback cannot start: feedback_enable=1 but" + " some required parameters are not set: %s%s%s", + url_set == 0 ? "feedback_url is not set" : "", + (user_info_set == 0 && url_set == 0) ? ", " : "", + user_info_set == 0 ? "feedback_user_info is not set" : ""); } else { - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Notification service feedback is not enabled"))); + MXS_INFO("Notification service feedback is not enabled."); } } } @@ -2795,7 +2719,7 @@ void config_add_param(CONFIG_CONTEXT* obj, char* key, char* value) if (nptr == NULL) { - skygw_log_write(LOGFILE_ERROR, "Memory allocation failed when adding configuration parameters"); + MXS_ERROR("Memory allocation failed when adding configuration parameters."); return; } @@ -2858,8 +2782,7 @@ bool config_has_duplicate_sections(const char* config) if (hashtable_add(hash, section, "") == 0) { - skygw_log_write(LE, "Error: Duplicate section found: %s", - section); + MXS_ERROR("Duplicate section found: %s", section); rval = true; } } @@ -2869,15 +2792,15 @@ bool config_has_duplicate_sections(const char* config) else { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, "Error: Failed to open file '%s': %s", config, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to open file '%s': %s", config, + strerror_r(errno, errbuf, sizeof(errbuf))); rval = true; } } else { - skygw_log_write(LE, "Error: Failed to allocate enough memory when checking" - " for duplicate sections in configuration file."); + MXS_ERROR("Failed to allocate enough memory when checking" + " for duplicate sections in configuration file."); rval = true; } @@ -2926,9 +2849,9 @@ int maxscale_getline(char** dest, int* size, FILE* file) } else { - skygw_log_write(LE, "Error: Failed to reallocate memory from %d" - " bytes to %d bytes when reading from file.", - *size, *size * 2); + MXS_ERROR("Failed to reallocate memory from %d" + " bytes to %d bytes when reading from file.", + *size, *size * 2); destptr[offset - 1] = '\0'; *dest = destptr; return -1; diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 593894158..1eca857ed 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -288,20 +288,16 @@ HASHTABLE *oldresources; /* digest compare */ if (oldusers != NULL && memcmp(oldusers->cksum, newusers->cksum, SHA_DIGEST_LENGTH) == 0) { /* same data, nothing to do */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [replace_mysql_users] users' tables not switched, checksum is the same", - pthread_self()))); + MXS_DEBUG("%lu [replace_mysql_users] users' tables not switched, checksum is the same", + pthread_self()); /* free the new table */ users_free(newusers); i = 0; } else { /* replace the service with effective new data */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [replace_mysql_users] users' tables replaced, checksum differs", - pthread_self()))); + MXS_DEBUG("%lu [replace_mysql_users] users' tables replaced, checksum differs", + pthread_self()); service->users = newusers; } @@ -432,11 +428,7 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p key.netmask = normalize_hostname(host, ret_ip); if (key.netmask == -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : strdup() failed in normalize_hostname for %s@%s", - user, - host))); + MXS_ERROR("strdup() failed in normalize_hostname for %s@%s", user, host); } } @@ -494,25 +486,21 @@ addDatabases(SERVICE *service, MYSQL *con) return -1; if (mysql_query(con, get_showdbs_priv_query)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); - return -1; + MXS_ERROR("Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)); + return -1; } result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); - return -1; + MXS_ERROR("Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)); + return -1; } /* Result has only one row */ @@ -523,10 +511,7 @@ addDatabases(SERVICE *service, MYSQL *con) } else { ndbs = 0; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - ERROR_NO_SHOW_DATABASES, - service->name, service_user))); + MXS_ERROR(ERROR_NO_SHOW_DATABASES, service->name, service_user); } /* free resut set */ @@ -538,34 +523,30 @@ addDatabases(SERVICE *service, MYSQL *con) } if (mysql_query(con, "SHOW DATABASES")) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)); - return -1; + return -1; } result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)); - return -1; + return -1; } /* insert key and value "" */ while ((row = mysql_fetch_row(result))) { if(resource_add(service->resources, row[0], "")) { - skygw_log_write(LOGFILE_DEBUG,"%s: Adding database %s to the resouce hash.",service->name,row[0]); + MXS_DEBUG("%s: Adding database %s to the resouce hash.", service->name, row[0]); } } @@ -599,25 +580,21 @@ getDatabases(SERVICE *service, MYSQL *con) return -1; if (mysql_query(con, get_showdbs_priv_query)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error when querying database privileges: %s.", - service->name, - mysql_error(con)))); - return -1; + MXS_ERROR("Loading database names for service %s encountered " + "error when querying database privileges: %s.", + service->name, + mysql_error(con)); + return -1; } result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error when storing result set of database privilege query: %s.", - service->name, - mysql_error(con)))); - return -1; + MXS_ERROR("Loading database names for service %s encountered " + "error when storing result set of database privilege query: %s.", + service->name, + mysql_error(con)); + return -1; } /* Result has only one row */ @@ -628,10 +605,7 @@ getDatabases(SERVICE *service, MYSQL *con) } else { ndbs = 0; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - ERROR_NO_SHOW_DATABASES, - service->name, service_user))); + MXS_ERROR(ERROR_NO_SHOW_DATABASES, service->name, service_user); } /* free resut set */ @@ -643,27 +617,23 @@ getDatabases(SERVICE *service, MYSQL *con) } if (mysql_query(con, "SHOW DATABASES")) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error when executing SHOW DATABASES query: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading database names for service %s encountered " + "error when executing SHOW DATABASES query: %s.", + service->name, + mysql_error(con)); - return -1; + return -1; } result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading database names for service %s encountered " - "error when storing the result set: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading database names for service %s encountered " + "error when storing the result set: %s.", + service->name, + mysql_error(con)); - return -1; + return -1; } /* Now populate service->resources hashatable with db names */ @@ -671,7 +641,7 @@ getDatabases(SERVICE *service, MYSQL *con) /* insert key and value "" */ while ((row = mysql_fetch_row(result))) { - skygw_log_write(LOGFILE_DEBUG,"%s: Adding database %s to the resouce hash.",service->name,row[0]); + MXS_DEBUG("%s: Adding database %s to the resouce hash.", service->name, row[0]); resource_add(service->resources, row[0], ""); } @@ -752,30 +722,22 @@ getAllUsers(SERVICE *service, USERS *users) if (con == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : mysql_init: %s", - mysql_error(con)))); + MXS_ERROR("mysql_init: %s", mysql_error(con)); goto cleanup; } /** Set read, write and connect timeout values */ if (gw_mysql_set_timeouts(con)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set timeout values for backend " - "connection."))); + MXS_ERROR("Failed to set timeout values for backend connection."); mysql_close(con); goto cleanup; } if (mysql_options(con, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set external connection. " - "It is needed for backend server connections."))); + MXS_ERROR("Failed to set external connection. " + "It is needed for backend server connections."); mysql_close(con); goto cleanup; } @@ -798,11 +760,9 @@ getAllUsers(SERVICE *service, USERS *users) if (server == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to get user data from backend database " - "for service [%s]. Missing server information.", - service->name))); + MXS_ERROR("Unable to get user data from backend database " + "for service [%s]. Missing server information.", + service->name); mysql_close(con); goto cleanup; } @@ -821,30 +781,22 @@ getAllUsers(SERVICE *service, USERS *users) if (con == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : mysql_init: %s", - mysql_error(con)))); + MXS_ERROR("mysql_init: %s", mysql_error(con)); goto cleanup; } /** Set read, write and connect timeout values */ if (gw_mysql_set_timeouts(con)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set timeout values for backend " - "connection."))); + MXS_ERROR("Failed to set timeout values for backend connection."); mysql_close(con); goto cleanup; } if (mysql_options(con, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set external connection. " - "It is needed for backend server connections."))); + MXS_ERROR("Failed to set external connection. " + "It is needed for backend server connections."); mysql_close(con); goto cleanup; } @@ -867,11 +819,9 @@ getAllUsers(SERVICE *service, USERS *users) if (server == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to get user data from backend database " - "for service [%s]. Missing server information.", - service->name))); + MXS_ERROR("Unable to get user data from backend database " + "for service [%s]. Missing server information.", + service->name); mysql_close(con); goto cleanup; } @@ -890,12 +840,9 @@ getAllUsers(SERVICE *service, USERS *users) if (mysql_query(con, user_with_db_count)) { if (mysql_errno(con) != ER_TABLEACCESS_DENIED_ERROR) { /* This is an error we cannot handle, return */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); mysql_close(con); goto cleanup; } else { @@ -904,12 +851,9 @@ getAllUsers(SERVICE *service, USERS *users) * try counting users from mysql.user without DB names. */ if (mysql_query(con, MYSQL_USERS_COUNT)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); mysql_close(con); goto cleanup; } @@ -919,12 +863,9 @@ getAllUsers(SERVICE *service, USERS *users) result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); mysql_close(con); goto cleanup; } @@ -936,10 +877,7 @@ getAllUsers(SERVICE *service, USERS *users) mysql_free_result(result); if (!nusers) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Counting users for service %s returned 0", - service->name))); + MXS_ERROR("Counting users for service %s returned 0.", service->name); mysql_close(con); goto cleanup; } @@ -959,13 +897,11 @@ getAllUsers(SERVICE *service, USERS *users) if (1142 != mysql_errno(con)) { /* This is an error we cannot handle, return */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users with dbnames for service [%s] encountered " - "error: [%s], MySQL errno %i", - service->name, - mysql_error(con), - mysql_errno(con)))); + MXS_ERROR("Loading users with dbnames for service [%s] encountered " + "error: [%s], MySQL errno %i", + service->name, + mysql_error(con), + mysql_errno(con)); mysql_close(con); @@ -976,10 +912,7 @@ getAllUsers(SERVICE *service, USERS *users) * try loading users from mysql.user without DB names. */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - ERROR_NO_SHOW_DATABASES, - service->name, service_user))); + MXS_ERROR(ERROR_NO_SHOW_DATABASES, service->name, service_user); /* check for root user select */ if(service->enable_root) { @@ -989,13 +922,11 @@ getAllUsers(SERVICE *service, USERS *users) } if (mysql_query(con, users_query)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s], code %i", - service->name, - mysql_error(con), - mysql_errno(con)))); + MXS_ERROR("Loading users for service [%s] encountered " + "error: [%s], code %i", + service->name, + mysql_error(con), + mysql_errno(con)); mysql_close(con); @@ -1004,30 +935,25 @@ getAllUsers(SERVICE *service, USERS *users) /* users successfully loaded but without db grants */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Loading users from [mysql.user] without access to [mysql.db] for " - "service [%s]. MaxScale Authentication with DBname on connect " - "will not consider database grants.", - service->name))); + MXS_NOTICE("Loading users from [mysql.user] without access to [mysql.db] for " + "service [%s]. MaxScale Authentication with DBname on connect " + "will not consider database grants.", + service->name); } } else { /* * users successfully loaded with db grants. */ - skygw_log_write(LOGFILE_DEBUG,"[%s] Loading users with db grants.",service->name); + MXS_DEBUG("[%s] Loading users with db grants.",service->name); db_grants = 1; } result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading users for service %s encountered error: %s.", + service->name, + mysql_error(con)); mysql_free_result(result); mysql_close(con); @@ -1039,12 +965,9 @@ getAllUsers(SERVICE *service, USERS *users) if (users_data == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation for user data failed due to " - "%d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation for user data failed due to %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); mysql_free_result(result); mysql_close(con); @@ -1074,16 +997,14 @@ getAllUsers(SERVICE *service, USERS *users) if (row[2] != NULL) { /* detect mysql_old_password (pre 4.1 protocol) */ if (strlen(row[2]) == 16) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%s: The user %s@%s has on old password in the " - "backend database. MaxScale does not support these " - "old passwords. This user will not be able to connect " - "via MaxScale. Update the users password to correct " - "this.", - service->name, - row[0], - row[1]))); + MXS_ERROR("%s: The user %s@%s has on old password in the " + "backend database. MaxScale does not support these " + "old passwords. This user will not be able to connect " + "via MaxScale. Update the users password to correct " + "this.", + service->name, + row[0], + row[1]); continue; } @@ -1107,28 +1028,26 @@ getAllUsers(SERVICE *service, USERS *users) havedb = true; if(service->strip_db_esc) { strip_escape_chars(dbnm); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "[%s]: %s -> %s", - service->name, - row[5], - dbnm))); + MXS_DEBUG("[%s]: %s -> %s", + service->name, + row[5], + dbnm); } } if(havedb && wildcard_db_grant(dbnm) && service->optimize_wildcard) { rc = add_wildcard_users(users, row[0], row[1], password, row[4], dbnm, service->resources); - skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"%s: Converted '%s' to %d individual database grants.",service->name,dbnm,rc); + MXS_INFO("%s: Converted '%s' to %d individual database grants.",service->name,dbnm,rc); } else { rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, row[4], havedb ? dbnm : NULL); } - LOGIF(LD,(skygw_log_write(LOGFILE_DEBUG,"%s: Adding user:%s host:%s anydb:%s db:%s.", - service->name,row[0],row[1],row[4], - havedb ? dbnm : NULL))); + MXS_DEBUG("%s: Adding user:%s host:%s anydb:%s db:%s.", + service->name,row[0],row[1],row[4], + havedb ? dbnm : NULL); } else { /* we don't have dbgrants, simply set ANY DB for the user */ rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], password, "Y", NULL); @@ -1150,22 +1069,17 @@ getAllUsers(SERVICE *service, USERS *users) strcpy(dbgrant, "no db"); /* Log the user being added with its db grants */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG|LOGFILE_TRACE, - "%s: User %s@%s for database %s added to " - "service user table.", - service->name, - row[0], - row[1], - dbgrant))); + MXS_INFO("%s: User %s@%s for database %s added to service user table.", + service->name, + row[0], + row[1], + dbgrant); } else { /* Log the user being added (without db grants) */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG|LOGFILE_TRACE, - "%s: User %s@%s added to service user table.", - service->name, - row[0], - row[1]))); + MXS_INFO("%s: User %s@%s added to service user table.", + service->name, + row[0], + row[1]); } /* Append data in the memory area for SHA1 digest */ @@ -1177,18 +1091,18 @@ getAllUsers(SERVICE *service, USERS *users) /** Duplicate user*/ if (service->log_auth_warnings) { - skygw_log_write(LM, "Duplicate MySQL user found for service" - " [%s]: %s@%s%s%s", service->name, row[0], - row[1], havedb ? " for database: " : "", - havedb ? dbnm : ""); + MXS_NOTICE("Duplicate MySQL user found for service" + " [%s]: %s@%s%s%s", service->name, row[0], + row[1], havedb ? " for database: " : "", + havedb ? dbnm : ""); } } else { if (service->log_auth_warnings) { - skygw_log_write_flush(LM, "Warning: Failed to add user %s@%s" - " for service [%s]. This user will be " - "unavailable via MaxScale.", row[0], - row[1], service->name); + MXS_NOTICE("Warning: Failed to add user %s@%s" + " for service [%s]. This user will be " + "unavailable via MaxScale.", row[0], + row[1], service->name); } } } @@ -1282,30 +1196,22 @@ getUsers(SERVICE *service, USERS *users) con = mysql_init(NULL); if (con == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : mysql_init: %s", - mysql_error(con)))); + MXS_ERROR("mysql_init: %s", mysql_error(con)); return -1; } /** Set read, write and connect timeout values */ if (gw_mysql_set_timeouts(con)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set timeout values for backend " - "connection."))); - mysql_close(con); - return -1; + MXS_ERROR("Failed to set timeout values for backend connection."); + mysql_close(con); + return -1; } if (mysql_options(con, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set external connection. " - "It is needed for backend server connections."))); - mysql_close(con); - return -1; + MXS_ERROR("Failed to set external connection. " + "It is needed for backend server connections."); + mysql_close(con); + return -1; } /** * Attempt to connect to one of the databases database or until we run @@ -1336,13 +1242,11 @@ getUsers(SERVICE *service, USERS *users) server->server->port, NULL, 0) != NULL)) { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Dbusers : Loading data from backend database with " - "Master role [%s:%i] for service [%s]", - server->server->name, - server->server->port, - service->name))); + MXS_DEBUG("Dbusers : Loading data from backend database with " + "Master role [%s:%i] for service [%s]", + server->server->name, + server->server->port, + service->name); } else { /* load data from other servers via loop */ server = service->dbref; @@ -1358,15 +1262,13 @@ getUsers(SERVICE *service, USERS *users) NULL, 0) == NULL)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failure loading users data from backend " - "[%s:%i] for service [%s]. MySQL error %i, %s", - server->server->name, - server->server->port, - service->name, - mysql_errno(con), - mysql_error(con)))); + MXS_ERROR("Failure loading users data from backend " + "[%s:%i] for service [%s]. MySQL error %i, %s", + server->server->name, + server->server->port, + service->name, + mysql_errno(con), + mysql_error(con)); server = server->next; } @@ -1379,13 +1281,11 @@ getUsers(SERVICE *service, USERS *users) } if (server != NULL) { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Dbusers : Loading data from backend database " - "[%s:%i] for service [%s]", - server->server->name, - server->server->port, - service->name))); + MXS_DEBUG("Loading data from backend database " + "[%s:%i] for service [%s]", + server->server->name, + server->server->port, + service->name); } } @@ -1393,13 +1293,11 @@ getUsers(SERVICE *service, USERS *users) if (server == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to get user data from backend database " - "for service [%s]. Failed to connect to any of the backend databases.", - service->name))); - mysql_close(con); - return -1; + MXS_ERROR("Unable to get user data from backend database " + "for service [%s]. Failed to connect to any of the backend databases.", + service->name); + mysql_close(con); + return -1; } if (server->server->server_string == NULL) @@ -1416,29 +1314,23 @@ getUsers(SERVICE *service, USERS *users) /** Count users. Start with users and db grants for users */ if (mysql_query(con, user_with_db_count)) { if (mysql_errno(con) != ER_TABLEACCESS_DENIED_ERROR) { - /* This is an error we cannot handle, return */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); - mysql_close(con); - return -1; + /* This is an error we cannot handle, return */ + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); + mysql_close(con); + return -1; } else { /* * We have got ER_TABLEACCESS_DENIED_ERROR * try counting users from mysql.user without DB names. */ if (mysql_query(con, MYSQL_USERS_COUNT)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); - mysql_close(con); - return -1; + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); + mysql_close(con); + return -1; } } } @@ -1446,14 +1338,11 @@ getUsers(SERVICE *service, USERS *users) result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s].", - service->name, - mysql_error(con)))); - mysql_close(con); - return -1; + MXS_ERROR("Loading users for service [%s] encountered error: [%s].", + service->name, + mysql_error(con)); + mysql_close(con); + return -1; } row = mysql_fetch_row(result); @@ -1463,12 +1352,9 @@ getUsers(SERVICE *service, USERS *users) mysql_free_result(result); if (!nusers) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Counting users for service %s returned 0", - service->name))); - mysql_close(con); - return -1; + MXS_ERROR("Counting users for service %s returned 0.", service->name); + mysql_close(con); + return -1; } users_query = get_mysql_users_query(server->server->server_string, @@ -1484,27 +1370,21 @@ getUsers(SERVICE *service, USERS *users) if (1142 != mysql_errno(con)) { /* This is an error we cannot handle, return */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users with dbnames for service [%s] encountered " - "error: [%s], MySQL errno %i", - service->name, - mysql_error(con), - mysql_errno(con)))); + MXS_ERROR("Loading users with dbnames for service [%s] encountered " + "error: [%s], MySQL errno %i", + service->name, + mysql_error(con), + mysql_errno(con)); - mysql_close(con); - - return -1; + mysql_close(con); + return -1; } else { /* * We have got ER_TABLEACCESS_DENIED_ERROR * try loading users from mysql.user without DB names. */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - ERROR_NO_SHOW_DATABASES, - service->name, service_user))); + MXS_ERROR(ERROR_NO_SHOW_DATABASES, service->name, service_user); /* check for root user select */ if(service->enable_root) { @@ -1514,27 +1394,22 @@ getUsers(SERVICE *service, USERS *users) } if (mysql_query(con, users_query)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service [%s] encountered " - "error: [%s], code %i", - service->name, - mysql_error(con), - mysql_errno(con)))); + MXS_ERROR("Loading users for service [%s] encountered " + "error: [%s], code %i", + service->name, + mysql_error(con), + mysql_errno(con)); - mysql_close(con); - - return -1; + mysql_close(con); + return -1; } /* users successfully loaded but without db grants */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Loading users from [mysql.user] without access to [mysql.db] for " - "service [%s]. MaxScale Authentication with DBname on connect " - "will not consider database grants.", - service->name))); + MXS_NOTICE("Loading users from [mysql.user] without access to [mysql.db] for " + "service [%s]. MaxScale Authentication with DBname on connect " + "will not consider database grants.", + service->name); } } else { /* @@ -1547,32 +1422,24 @@ getUsers(SERVICE *service, USERS *users) result = mysql_store_result(con); if (result == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Loading users for service %s encountered " - "error: %s.", - service->name, - mysql_error(con)))); + MXS_ERROR("Loading users for service %s encountered error: %s.", + service->name, + mysql_error(con)); - mysql_free_result(result); - mysql_close(con); - - return -1; + mysql_free_result(result); + mysql_close(con); + return -1; } users_data = (char *)calloc(nusers, (users_data_row_len * sizeof(char)) + 1); if (users_data == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation for user data failed due to " - "%d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation for user data failed due to %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); mysql_free_result(result); mysql_close(con); - return -1; } @@ -1580,11 +1447,9 @@ getUsers(SERVICE *service, USERS *users) /* load all mysql database names */ dbnames = getDatabases(service, con); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "Loaded %d MySQL Database Names for service [%s]", - dbnames, - service->name))); + MXS_DEBUG("Loaded %d MySQL Database Names for service [%s]", + dbnames, + service->name); } else { service->resources = NULL; } @@ -1612,17 +1477,15 @@ getUsers(SERVICE *service, USERS *users) if (row[2] != NULL) { /* detect mysql_old_password (pre 4.1 protocol) */ if (strlen(row[2]) == 16) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%s: The user %s@%s has on old password in the " - "backend database. MaxScale does not support these " - "old passwords. This user will not be able to connect " - "via MaxScale. Update the users password to correct " - "this.", - service->name, - row[0], - row[1]))); - continue; + MXS_ERROR("%s: The user %s@%s has on old password in the " + "backend database. MaxScale does not support these " + "old passwords. This user will not be able to connect " + "via MaxScale. Update the users password to correct " + "this.", + service->name, + row[0], + row[1]); + continue; } if (strlen(row[2]) > 1) @@ -1645,12 +1508,10 @@ getUsers(SERVICE *service, USERS *users) havedb = true; if(service->strip_db_esc) { strip_escape_chars(dbnm); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "[%s]: %s -> %s", - service->name, - row[5], - dbnm))); + MXS_DEBUG("[%s]: %s -> %s", + service->name, + row[5], + dbnm); } } @@ -1659,7 +1520,8 @@ getUsers(SERVICE *service, USERS *users) if(service->optimize_wildcard) { rc = add_wildcard_users(users, row[0], row[1], password, row[4], dbnm, service->resources); - skygw_log_write(LOGFILE_DEBUG|LOGFILE_TRACE,"%s: Converted '%s' to %d individual database grants.",service->name,row[5],rc); + MXS_INFO("%s: Converted '%s' to %d individual database grants.", + service->name, row[5], rc); } else { @@ -1693,22 +1555,18 @@ getUsers(SERVICE *service, USERS *users) strcpy(dbgrant, "no db"); /* Log the user being added with its db grants */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG|LOGFILE_TRACE, - "%s: User %s@%s for database %s added to " - "service user table.", - service->name, - row[0], - row[1], - dbgrant))); + MXS_INFO("%s: User %s@%s for database %s added to " + "service user table.", + service->name, + row[0], + row[1], + dbgrant); } else { - /* Log the user being added (without db grants) */ - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG|LOGFILE_TRACE, - "%s: User %s@%s added to service user table.", - service->name, - row[0], - row[1]))); + /* Log the user being added (without db grants) */ + MXS_INFO("%s: User %s@%s added to service user table.", + service->name, + row[0], + row[1]); } /* Append data in the memory area for SHA1 digest */ @@ -1720,17 +1578,17 @@ getUsers(SERVICE *service, USERS *users) /** Duplicate user*/ if (service->log_auth_warnings) { - skygw_log_write(LM, "Warning: Duplicate MySQL user found for " - "service [%s]: %s@%s%s%s", service->name, row[0], - row[1], db_grants ? " for database: " : "", - db_grants ? row[5] : ""); + MXS_WARNING("Duplicate MySQL user found for " + "service [%s]: %s@%s%s%s", service->name, row[0], + row[1], db_grants ? " for database: " : "", + db_grants ? row[5] : ""); } } else { if (service->log_auth_warnings) { - skygw_log_write_flush(LM, "Warning: Failed to add user %s@%s for" - " service [%s]. This user will be unavailable" - " via MaxScale.", row[0], row[1], service->name); + MXS_WARNING("Failed to add user %s@%s for" + " service [%s]. This user will be unavailable" + " via MaxScale.", row[0], row[1], service->name); } } } @@ -2198,33 +2056,24 @@ static int gw_mysql_set_timeouts(MYSQL* handle) MYSQL_OPT_READ_TIMEOUT, (void *)&cnf->auth_read_timeout))) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set read timeout for backend " - "connection."))); - goto retblock; + MXS_ERROR("Failed to set read timeout for backend connection."); + goto retblock; } if ((rc = mysql_options(handle, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&cnf->auth_conn_timeout))) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set connect timeout for backend " - "connection."))); - goto retblock; + MXS_ERROR("Failed to set connect timeout for backend connection."); + goto retblock; } if ((rc = mysql_options(handle, MYSQL_OPT_WRITE_TIMEOUT, (void *)&cnf->auth_write_timeout))) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : failed to set write timeout for backend " - "connection."))); - goto retblock; + MXS_ERROR("Failed to set write timeout for backend connection."); + goto retblock; } retblock: @@ -2482,9 +2331,8 @@ int add_wildcard_users(USERS *users, char* name, char* host, char* password, cha if((err = regcomp(&re,restr,REG_ICASE|REG_NOSUB))) { regerror(err,&re,errbuf,1024); - skygw_log_write(LOGFILE_ERROR,"Error: Failed to compile regex " - "when resolving wildcard database grants: %s", - errbuf); + MXS_ERROR("Failed to compile regex when resolving wildcard database grants: %s", + errbuf); free(restr); return 0; } @@ -2529,7 +2377,7 @@ bool check_service_permissions(SERVICE* service) if(service->dbref == NULL) { - skygw_log_write(LE,"%s: Error: Service is missing the servers parameter.",service->name); + MXS_ERROR("%s: Service is missing the servers parameter.", service->name); return false; } @@ -2537,8 +2385,7 @@ bool check_service_permissions(SERVICE* service) if (serviceGetUser(service, &user, &password) == 0) { - skygw_log_write(LE, - "%s: Error: Service is missing the user credentials for authentication.", + MXS_ERROR("%s: Service is missing the user credentials for authentication.", service->name); return false; } @@ -2547,7 +2394,7 @@ bool check_service_permissions(SERVICE* service) if((mysql = mysql_init(NULL)) == NULL) { - skygw_log_write(LE,"[%s] Error: MySQL connection initialization failed.",__FUNCTION__); + MXS_ERROR("[%s] MySQL connection initialization failed.", __FUNCTION__); free(dpasswd); return false; } @@ -2561,14 +2408,14 @@ bool check_service_permissions(SERVICE* service) { int my_errno = mysql_errno(mysql); - skygw_log_write(LE,"%s: Error: Failed to connect to server %s(%s:%d) when" - " checking authentication user credentials and permissions: %d %s", - service->name, - server->server->unique_name, - server->server->name, - server->server->port, - my_errno, - mysql_error(mysql)); + MXS_ERROR("%s: Failed to connect to server %s(%s:%d) when" + " checking authentication user credentials and permissions: %d %s", + service->name, + server->server->unique_name, + server->server->name, + server->server->port, + my_errno, + mysql_error(mysql)); mysql_close(mysql); free(dpasswd); @@ -2580,25 +2427,25 @@ bool check_service_permissions(SERVICE* service) { if(mysql_errno(mysql) == ER_TABLEACCESS_DENIED_ERROR) { - skygw_log_write(LE,"%s: Error: User '%s' is missing SELECT privileges" - " on mysql.user table. MySQL error message: %s", - service->name,user,mysql_error(mysql)); + MXS_ERROR("%s: User '%s' is missing SELECT privileges" + " on mysql.user table. MySQL error message: %s", + service->name,user,mysql_error(mysql)); rval = false; } else { - skygw_log_write(LE,"%s: Error: Failed to query from mysql.user table." - " MySQL error message: %s", - service->name,mysql_error(mysql)); + MXS_ERROR("%s: Error: Failed to query from mysql.user table." + " MySQL error message: %s", + service->name,mysql_error(mysql)); } } else { if((res = mysql_use_result(mysql)) == NULL) { - skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for" - " permissions to the mysql.user table: %s", - service->name,mysql_error(mysql)); + MXS_ERROR("%s: Error: Result retrieval failed when checking for" + " permissions to the mysql.user table: %s", + service->name,mysql_error(mysql)); mysql_close(mysql); free(dpasswd); return true; @@ -2609,21 +2456,22 @@ bool check_service_permissions(SERVICE* service) { if(mysql_errno(mysql) == ER_TABLEACCESS_DENIED_ERROR) { - skygw_log_write(LE,"%s: Warning: User '%s' is missing SELECT privileges on mysql.db table. Database name will be ignored in authentication. MySQL error message: %s", - service->name,user,mysql_error(mysql)); + MXS_WARNING("%s: User '%s' is missing SELECT privileges on mysql.db table. " + "Database name will be ignored in authentication. MySQL error message: %s", + service->name,user,mysql_error(mysql)); } else { - skygw_log_write(LE,"%s: Error: Failed to query from mysql.db table. MySQL error message: %s", - service->name,mysql_error(mysql)); + MXS_ERROR("%s: Failed to query from mysql.db table. MySQL error message: %s", + service->name,mysql_error(mysql)); } } else { if((res = mysql_use_result(mysql)) == NULL) { - skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for permissions to the mysql.db table: %s", - service->name,mysql_error(mysql)); + MXS_ERROR("%s: Result retrieval failed when checking for permissions to the mysql.db table: %s", + service->name,mysql_error(mysql)); } else { diff --git a/server/core/dcb.c b/server/core/dcb.c index 22d1b7b87..20ca54f18 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -304,11 +304,8 @@ dcb_final_free(DCB *dcb) if (DCB_POLL_BUSY(dcb)) { - /* Check if DCB has outstanding poll events */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "dcb_final_free: DCB %p has outstanding events", - dcb))); + /* Check if DCB has outstanding poll events */ + MXS_ERROR("dcb_final_free: DCB %p has outstanding events.", dcb); } /*< First remove this DCB from the chain */ @@ -481,16 +478,14 @@ DCB *listofdcb = NULL; previousdcb->memdata.next = zombiedcb->memdata.next; } - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [%s] Remove dcb " - "%p fd %d in state %s from the " - "list of zombies.", - pthread_self(), - __func__, - zombiedcb, - zombiedcb->fd, - STRDCBSTATE(zombiedcb->state)))); + MXS_DEBUG("%lu [%s] Remove dcb " + "%p fd %d in state %s from the " + "list of zombies.", + pthread_self(), + __func__, + zombiedcb, + zombiedcb->fd, + STRDCBSTATE(zombiedcb->state)); /*< * Move zombie dcb to linked list of victim dcbs. * The variable dcb is used to hold the last DCB @@ -547,15 +542,13 @@ dcb_process_victim_queue(DCB *listofdcb) { if (dcb->state == DCB_STATE_LISTENING) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%lu [%s] Error : Removing DCB %p but was in state %s " - "which is not expected for a call to dcb_close, although it" - "should be processed correctly. ", - pthread_self(), - __func__, - dcb, - STRDCBSTATE(dcb->state)))); + MXS_ERROR("%lu [%s] Error : Removing DCB %p but was in state %s " + "which is not expected for a call to dcb_close, although it" + "should be processed correctly. ", + pthread_self(), + __func__, + dcb, + STRDCBSTATE(dcb->state)); } else { /* Must be DCB_STATE_POLLING */ @@ -602,27 +595,23 @@ dcb_process_victim_queue(DCB *listofdcb) int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [dcb_process_victim_queue] Error : Failed to close " - "socket %d on dcb %p due error %d, %s.", - pthread_self(), - dcb->fd, - dcb, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("%lu [dcb_process_victim_queue] Error : Failed to close " + "socket %d on dcb %p due error %d, %s.", + pthread_self(), + dcb->fd, + dcb, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } else { dcb->fd = DCBFD_CLOSED; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [dcb_process_victim_queue] Closed socket " - "%d on dcb %p.", - pthread_self(), - dcb->fd, - dcb))); + MXS_DEBUG("%lu [dcb_process_victim_queue] Closed socket " + "%d on dcb %p.", + pthread_self(), + dcb->fd, + dcb); #if defined(FAKE_CODE) conn_open[dcb->fd] = false; #endif /* FAKE_CODE */ @@ -643,7 +632,10 @@ dcb_process_victim_queue(DCB *listofdcb) dcb = nextdcb; } /** Reset threads session data */ - LOGIF(LT, tls_log_info.li_sesid = 0); + if (LOG_IS_ENABLED(LOGFILE_TRACE)) + { + tls_log_info.li_sesid = 0; + } } /** @@ -690,9 +682,8 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol) user = session_getUser(session); if (user && strlen(user)) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Looking for persistent connection DCB user %s protocol %s\n", pthread_self(), user, protocol))); + MXS_DEBUG("%lu [dcb_connect] Looking for persistent connection DCB " + "user %s protocol %s\n", pthread_self(), user, protocol); dcb = server_get_persistent(server, user, protocol); if (dcb) { @@ -701,26 +692,21 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol) */ if (!session_link_dcb(session, dcb)) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Failed to link to session, the " - "session has been removed.\n", - pthread_self()))); + MXS_DEBUG("%lu [dcb_connect] Failed to link to session, the " + "session has been removed.\n", + pthread_self()); dcb_close(dcb); return NULL; } - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Reusing a persistent connection, dcb %p\n", pthread_self(), dcb))); + MXS_DEBUG("%lu [dcb_connect] Reusing a persistent connection, dcb %p\n", + pthread_self(), dcb); dcb->persistentstart = 0; return dcb; } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Failed to find a reusable persistent connection.\n", - pthread_self()))); + MXS_DEBUG("%lu [dcb_connect] Failed to find a reusable persistent connection.\n", + pthread_self()); } } @@ -734,12 +720,9 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol) { dcb->state = DCB_STATE_DISCONNECTED; dcb_final_free(dcb); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to load protocol module for %s, free " - "dcb %p\n", - protocol, - dcb))); + MXS_ERROR("Failed to load protocol module for %s, free dcb %p\n", + protocol, + dcb); return NULL; } memcpy(&(dcb->func), funcs, sizeof(GWPROTOCOL)); @@ -750,41 +733,35 @@ dcb_connect(SERVER *server, SESSION *session, const char *protocol) */ if (!session_link_dcb(session, dcb)) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Failed to link to session, the " - "session has been removed.", - pthread_self()))); - dcb_final_free(dcb); - return NULL; + MXS_DEBUG("%lu [dcb_connect] Failed to link to session, the " + "session has been removed.", + pthread_self()); + dcb_final_free(dcb); + return NULL; } fd = dcb->func.connect(dcb, server, session); if (fd == DCBFD_CLOSED) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_connect] Failed to connect to server %s:%d, " - "from backend dcb %p, client dcp %p fd %d.", - pthread_self(), - server->name, - server->port, - dcb, - session->client, - session->client->fd))); - dcb->state = DCB_STATE_DISCONNECTED; - dcb_final_free(dcb); - return NULL; + MXS_DEBUG("%lu [dcb_connect] Failed to connect to server %s:%d, " + "from backend dcb %p, client dcp %p fd %d.", + pthread_self(), + server->name, + server->port, + dcb, + session->client, + session->client->fd); + dcb->state = DCB_STATE_DISCONNECTED; + dcb_final_free(dcb); + return NULL; } else { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [dcb_connect] Connected to server %s:%d, " - "from backend dcb %p, client dcp %p fd %d.", - pthread_self(), - server->name, - server->port, - dcb, - session->client, - session->client->fd))); + MXS_DEBUG("%lu [dcb_connect] Connected to server %s:%d, " + "from backend dcb %p, client dcp %p fd %d.", + pthread_self(), + server->name, + server->port, + dcb, + session->client, + session->client->fd); } /** * Successfully connected to backend. Assign file descriptor to dcb @@ -854,11 +831,9 @@ int dcb_read( if (dcb->fd <= 0) { /* */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [dcb_read] Error : Read failed, dcb is %s.", - pthread_self(), - dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not readable"))); + MXS_ERROR("%lu [dcb_read] Error : Read failed, dcb is %s.", + pthread_self(), + dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not readable"); /* */ return 0; } @@ -871,16 +846,14 @@ int dcb_read( { char errbuf[STRERROR_BUFLEN]; /* */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [dcb_read] Error : ioctl FIONREAD for dcb %p in " - "state %s fd %d failed due error %d, %s.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("%lu [dcb_read] Error : ioctl FIONREAD for dcb %p in " + "state %s fd %d failed due error %d, %s.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); /* */ return -1; } @@ -922,15 +895,13 @@ int dcb_read( */ char errbuf[STRERROR_BUFLEN]; /* */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [dcb_read] Error : Failed to allocate read buffer " - "for dcb %p fd %d, due %d, %s.", - pthread_self(), - dcb, - dcb->fd, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("%lu [dcb_read] Error : Failed to allocate read buffer " + "for dcb %p fd %d, due %d, %s.", + pthread_self(), + dcb, + dcb->fd, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); /* */ return -1; } @@ -943,16 +914,14 @@ int dcb_read( { char errbuf[STRERROR_BUFLEN]; /* */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [dcb_read] Error : Read failed, dcb %p in state " - "%s fd %d, due %d, %s.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("%lu [dcb_read] Error : Read failed, dcb %p in state " + "%s fd %d, due %d, %s.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); /* */ } gwbuf_free(buffer); @@ -960,15 +929,13 @@ int dcb_read( } nreadtotal += nsingleread; /* */ - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_read] Read %d bytes from dcb %p in state %s " - "fd %d.", - pthread_self(), - nsingleread, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_read] Read %d bytes from dcb %p in state %s " + "fd %d.", + pthread_self(), + nsingleread, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); /* */ /*< Append read data to the gwbuf */ *head = gwbuf_append(*head, buffer); @@ -997,9 +964,8 @@ int dcb_read_SSL(DCB *dcb, if (dcb->fd <= 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Read failed, dcb is %s.", - dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not readable"))); + MXS_ERROR("Read failed, dcb is %s.", + dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not readable"); return 0; } @@ -1015,13 +981,12 @@ int dcb_read_SSL(DCB *dcb, * Todo shutdown if memory allocation fails. */ char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Failed to allocate read buffer " - "for dcb %p fd %d, due %d, %s.", - dcb, - dcb->fd, - errno, - strerror_r(errno, errbuf, sizeof (errbuf))))); + MXS_ERROR("Failed to allocate read buffer " + "for dcb %p fd %d, due %d, %s.", + dcb, + dcb->fd, + errno, + strerror_r(errno, errbuf, sizeof (errbuf))); return -1; } @@ -1049,9 +1014,9 @@ int dcb_read_SSL(DCB *dcb, if (buffer) { #ifdef SS_DEBUG - skygw_log_write(LD, "%lu SSL: Truncated buffer from %d to %d bytes. " - "Read %d bytes, %d bytes waiting.\n", pthread_self(), - bufsize, GWBUF_LENGTH(buffer), n, b); + MXS_DEBUG("%lu SSL: Truncated buffer from %d to %d bytes. " + "Read %d bytes, %d bytes waiting.\n", pthread_self(), + bufsize, GWBUF_LENGTH(buffer), n, b); if (GWBUF_LENGTH(buffer) != n) { @@ -1063,14 +1028,13 @@ int dcb_read_SSL(DCB *dcb, #endif nread += n; - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [dcb_read_SSL] Read %d bytes from dcb %p in state %s " - "fd %d.", - pthread_self(), - n, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_read_SSL] Read %d bytes from dcb %p in state %s " + "fd %d.", + pthread_self(), + n, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); /*< Append read data to the gwbuf */ *head = gwbuf_append(*head, buffer); @@ -1078,12 +1042,12 @@ int dcb_read_SSL(DCB *dcb, } ss_dassert(gwbuf_length(*head) == nread); - LOGIF(LD, skygw_log_write(LD, "%lu Read a total of %d bytes from dcb %p in state %s fd %d.", - pthread_self(), - nread, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd)); + MXS_DEBUG("%lu Read a total of %d bytes from dcb %p in state %s fd %d.", + pthread_self(), + nread, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); return nread; } @@ -1153,15 +1117,13 @@ int below_water; * queue with have. */ queue = gwbuf_consume(queue, written); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Wrote %d Bytes to dcb %p in " - "state %s fd %d", - pthread_self(), - written, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Wrote %d Bytes to dcb %p in " + "state %s fd %d", + pthread_self(), + written, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); } /*< while (queue != NULL) */ } /* if (dcb->writeq) */ @@ -1215,10 +1177,8 @@ dcb_write_parameter_check(DCB *dcb, GWBUF *queue) if (dcb->fd <= 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Write failed, dcb is %s.", - dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not writable"))); + MXS_ERROR("Write failed, dcb is %s.", + dcb->fd == DCBFD_CLOSED ? "closed" : "cloned, not writable"); gwbuf_free(queue); return false; } @@ -1241,15 +1201,13 @@ dcb_write_parameter_check(DCB *dcb, GWBUF *queue) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Write aborted to dcb %p because " - "it is in state %s", - pthread_self(), - dcb->stats.n_buffered, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Write aborted to dcb %p because " + "it is in state %s", + pthread_self(), + dcb->stats.n_buffered, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); gwbuf_free(queue); return false; } @@ -1278,15 +1236,13 @@ dcb_write_when_already_queued(DCB *dcb, GWBUF *queue) atomic_add(&dcb->writeqlen, gwbuf_length(queue)); dcb->writeq = gwbuf_append(dcb->writeq, queue); dcb->stats.n_buffered++; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Append to writequeue. %d writes " - "buffered for dcb %p in state %s fd %d", - pthread_self(), - dcb->stats.n_buffered, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Append to writequeue. %d writes " + "buffered for dcb %p in state %s fd %d", + pthread_self(), + dcb->stats.n_buffered, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); } /** @@ -1304,17 +1260,15 @@ dcb_log_write_failure(DCB *dcb, GWBUF *queue, int eno) if (eno == EPIPE) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Write to dcb " - "%p in state %s fd %d failed " - "due errno %d, %s", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [dcb_write] Write to dcb " + "%p in state %s fd %d failed " + "due errno %d, %s", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } } @@ -1325,16 +1279,14 @@ dcb_log_write_failure(DCB *dcb, GWBUF *queue, int eno) eno != EWOULDBLOCK) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Write to dcb %p in " - "state %s fd %d failed due " - "errno %d, %s", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Write to dcb %p in " + "state %s fd %d failed due " + "errno %d, %s", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } @@ -1361,13 +1313,11 @@ dcb_log_write_failure(DCB *dcb, GWBUF *queue, int eno) if (dolog) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Writing to %s socket failed due %d, %s.", - pthread_self(), - dcb_isclient(dcb) ? "client" : "backend server", - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [dcb_write] Writing to %s socket failed due %d, %s.", + pthread_self(), + dcb_isclient(dcb) ? "client" : "backend server", + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } } } @@ -1447,7 +1397,7 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue) #ifdef SS_DEBUG else { - skygw_log_write(LD, "SSL error: SSL_ERROR_WANT_WRITE, retrying SSL_write..."); + MXS_DEBUG("SSL error: SSL_ERROR_WANT_WRITE, retrying SSL_write..."); } #endif } @@ -1455,15 +1405,13 @@ dcb_write_SSL(DCB *dcb, GWBUF *queue) /** Remove written bytes from the queue */ queue = gwbuf_consume(queue, w); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Wrote %d Bytes to dcb %p in " - "state %s fd %d", - pthread_self(), - w, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Wrote %d Bytes to dcb %p in " + "state %s fd %d", + pthread_self(), + w, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); } /*< while (queue != NULL) */ /*< * What wasn't successfully written is stored to write queue @@ -1495,37 +1443,31 @@ dcb_write_SSL_error_report (DCB *dcb, int ret, int ssl_errno) switch(ssl_errno) { case SSL_ERROR_WANT_READ: - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Write to dcb " - "%p in state %s fd %d failed " - "due error SSL_ERROR_WANT_READ", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Write to dcb " + "%p in state %s fd %d failed " + "due error SSL_ERROR_WANT_READ", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); break; case SSL_ERROR_WANT_WRITE: - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Write to dcb " - "%p in state %s fd %d failed " - "due error SSL_ERROR_WANT_WRITE", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_write] Write to dcb " + "%p in state %s fd %d failed " + "due error SSL_ERROR_WANT_WRITE", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); break; default: - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_write] Write to dcb " - "%p in state %s fd %d failed " - "due error %d", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - dcb->fd,ssl_errno))); + MXS_DEBUG("%lu [dcb_write] Write to dcb " + "%p in state %s fd %d failed " + "due error %d", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + dcb->fd,ssl_errno); break; } } @@ -1534,26 +1476,24 @@ dcb_write_SSL_error_report (DCB *dcb, int ret, int ssl_errno) { if (ret == -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Write to dcb %p in " - "state %s fd %d failed due to " - "SSL error %d", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - ssl_errno))); + MXS_ERROR("Write to dcb %p in " + "state %s fd %d failed due to " + "SSL error %d", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + ssl_errno); if(ssl_errno == SSL_ERROR_SSL || ssl_errno == SSL_ERROR_SYSCALL) { if(ssl_errno == SSL_ERROR_SYSCALL) { - skygw_log_write(LE,"%d:%s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("%d:%s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); } do { char errbuf[SSL_ERRBUF_LEN]; ERR_error_string_n(ssl_errno,errbuf, sizeof(errbuf)); - skygw_log_write(LE,"%d:%s",ssl_errno,errbuf); + MXS_ERROR("%d:%s", ssl_errno,errbuf); } while((ssl_errno = ERR_get_error()) != 0); } } @@ -1563,7 +1503,7 @@ dcb_write_SSL_error_report (DCB *dcb, int ret, int ssl_errno) { char errbuf[SSL_ERRBUF_LEN]; ERR_error_string_n(ssl_errno,errbuf,sizeof(errbuf)); - skygw_log_write(LE,"%d:%s",ssl_errno,errbuf); + MXS_ERROR("%d:%s", ssl_errno,errbuf); } while((ssl_errno = ERR_get_error()) != 0); } } @@ -1618,15 +1558,13 @@ int above_water; break; } char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Write to dcb %p " - "in state %s fd %d failed due errno %d, %s", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - saved_errno, - strerror_r(saved_errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Write to dcb %p " + "in state %s fd %d failed due errno %d, %s", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + saved_errno, + strerror_r(saved_errno, errbuf, sizeof(errbuf))); break; } /* @@ -1634,15 +1572,13 @@ int above_water; * queue with have. */ dcb->writeq = gwbuf_consume(dcb->writeq, w); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_drain_writeq] Wrote %d Bytes to dcb %p " - "in state %s fd %d", - pthread_self(), - w, - dcb, - STRDCBSTATE(dcb->state), - dcb->fd))); + MXS_DEBUG("%lu [dcb_drain_writeq] Wrote %d Bytes to dcb %p " + "in state %s fd %d", + pthread_self(), + w, + dcb, + STRDCBSTATE(dcb->state), + dcb->fd); n += w; } } @@ -1704,13 +1640,12 @@ dcb_drain_writeq_SSL(DCB *dcb) { break; } - skygw_log_write_flush(LOGFILE_ERROR, - "Error : Write to dcb failed due to " - "SSL error %d:", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - ssl_errno); + MXS_ERROR("Write to dcb failed due to " + "SSL error %d:", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + ssl_errno); switch(ssl_errno) { case SSL_ERROR_SSL: @@ -1719,20 +1654,20 @@ dcb_drain_writeq_SSL(DCB *dcb) { char errbuf[SSL_ERRBUF_LEN]; ERR_error_string_n(ssl_errno,errbuf,sizeof(errbuf)); - skygw_log_write(LE,"%s",errbuf); + MXS_ERROR("%s", errbuf); } if(errno != 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE,"%d:%s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("%d:%s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); } break; case SSL_ERROR_ZERO_RETURN: - skygw_log_write(LE,"Socket is closed."); + MXS_ERROR("Socket is closed."); break; default: - skygw_log_write(LE,"Unexpected error."); + MXS_ERROR("Unexpected error."); break; } break; @@ -1782,13 +1717,11 @@ dcb_close(DCB *dcb) if (DCB_STATE_UNDEFINED == dcb->state || DCB_STATE_DISCONNECTED == dcb->state) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "%lu [dcb_close] Error : Removing DCB %p but was in state %s " - "which is not legal for a call to dcb_close. ", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_ERROR("%lu [dcb_close] Error : Removing DCB %p but was in state %s " + "which is not legal for a call to dcb_close. ", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); raise(SIGABRT); } @@ -1864,11 +1797,9 @@ dcb_maybe_add_persistent(DCB *dcb) && (poolcount = dcb_persistent_clean_count(dcb, false)) < dcb->server->persistpoolmax) { DCB_CALLBACK *loopcallback; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_maybe_add_persistent] Adding DCB to persistent pool, user %s.\n", - pthread_self(), - dcb->user))); + MXS_DEBUG("%lu [dcb_maybe_add_persistent] Adding DCB to persistent pool, user %s.\n", + pthread_self(), + dcb->user); dcb->dcb_is_zombie = false; dcb->persistentstart = time(NULL); if (dcb->session) @@ -1901,19 +1832,17 @@ dcb_maybe_add_persistent(DCB *dcb) } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [dcb_maybe_add_persistent] Not adding DCB %p to persistent pool, " - "user %s, max for pool %d, error handle called %s, hung flag %s, " - "server status %d, pool count %d.\n", - pthread_self(), - dcb, - dcb->user ? dcb->user : "", - (dcb->server && dcb->server->persistpoolmax) ? dcb->server->persistpoolmax : 0, - dcb->dcb_errhandle_called ? "true" : "false", - (dcb->flags & DCBF_HUNG) ? "true" : "false", - dcb->server ? dcb->server->status : 0, - poolcount))); + MXS_DEBUG("%lu [dcb_maybe_add_persistent] Not adding DCB %p to persistent pool, " + "user %s, max for pool %d, error handle called %s, hung flag %s, " + "server status %d, pool count %d.\n", + pthread_self(), + dcb, + dcb->user ? dcb->user : "", + (dcb->server && dcb->server->persistpoolmax) ? dcb->server->persistpoolmax : 0, + dcb->dcb_errhandle_called ? "true" : "false", + (dcb->flags & DCBF_HUNG) ? "true" : "false", + dcb->server ? dcb->server->status : 0, + poolcount); } return false; } @@ -2446,12 +2375,10 @@ gw_write(DCB *dcb, const void *buf, size_t nbytes) { snprintf(s, len, "%s", (char *)str); } - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "%lu [gw_write] Wrote %d bytes : %s ", - pthread_self(), - w, - s))); + MXS_INFO("%lu [gw_write] Wrote %d bytes : %s ", + pthread_self(), + w, + s); free(s); } } @@ -2588,10 +2515,9 @@ DCB_CALLBACK *cb, *nextcb; nextcb = cb->next; spinlock_release(&dcb->cb_lock); - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [dcb_call_callback] %s", - pthread_self(), - STRDCBREASON(reason)))); + MXS_DEBUG("%lu [dcb_call_callback] %s", + pthread_self(), + STRDCBREASON(reason)); cb->cb(dcb, reason, cb->userdata); spinlock_acquire(&dcb->cb_lock); @@ -2686,9 +2612,7 @@ dcb_get_next (DCB *dcb) void dcb_call_foreach(struct server* server, DCB_REASON reason) { - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [dcb_call_foreach]", - pthread_self()))); + MXS_DEBUG("%lu [dcb_call_foreach]", pthread_self()); switch (reason) { case DCB_REASON_CLOSE: @@ -2732,9 +2656,7 @@ dcb_call_foreach(struct server* server, DCB_REASON reason) void dcb_hangup_foreach(struct server* server) { - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [dcb_hangup_foreach]", - pthread_self()))); + MXS_DEBUG("%lu [dcb_hangup_foreach]", pthread_self()); DCB *dcb; spinlock_acquire(&dcbspin); @@ -2938,13 +2860,13 @@ int dcb_create_SSL(DCB* dcb) if((dcb->ssl = SSL_new(dcb->service->ctx)) == NULL) { - skygw_log_write(LE,"Error: Failed to initialize SSL for connection."); + MXS_ERROR("Failed to initialize SSL for connection."); return -1; } if(SSL_set_fd(dcb->ssl,dcb->fd) == 0) { - skygw_log_write(LE,"Error: Failed to set file descriptor for SSL connection."); + MXS_ERROR("Failed to set file descriptor for SSL connection."); return -1; } @@ -2973,14 +2895,12 @@ int dcb_accept_SSL(DCB* dcb) { ssl_rval = SSL_accept(dcb->ssl); - LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept %d, error %d", - ssl_rval,ssl_errnum))); + MXS_DEBUG("[dcb_accept_SSL] SSL_accept %d, error %d", ssl_rval,ssl_errnum); switch(ssl_rval) { case 0: ssl_errnum = SSL_get_error(dcb->ssl,ssl_rval); - skygw_log_write(LE,"Error: SSL authentication failed (SSL error %d):", - ssl_errnum); + MXS_ERROR("SSL authentication failed (SSL error %d):", ssl_errnum); if(ssl_errnum == SSL_ERROR_SSL || ssl_errnum == SSL_ERROR_SYSCALL) @@ -2988,15 +2908,14 @@ int dcb_accept_SSL(DCB* dcb) while((err_errnum = ERR_get_error()) != 0) { ERR_error_string_n(err_errnum,errbuf,sizeof(errbuf)); - skygw_log_write(LE,"%s",errbuf); + MXS_ERROR("%s", errbuf); } } rval = -1; break; case 1: rval = 1; - LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept done for %s", - dcb->remote))); + MXS_DEBUG("[dcb_accept_SSL] SSL_accept done for %s", dcb->remote); return rval; case -1: @@ -3008,48 +2927,42 @@ int dcb_accept_SSL(DCB* dcb) /** Not all of the data has been read. Go back to the poll queue and wait for more.*/ rval = 0; - LOGIF(LD,(skygw_log_write_flush(LD,"[dcb_accept_SSL] SSL_accept ongoing for %s", - dcb->remote))); + MXS_DEBUG("[dcb_accept_SSL] SSL_accept ongoing for %s", dcb->remote); return rval; } else { rval = -1; - skygw_log_write(LE, - "Error: Fatal error in SSL_accept for %s: (SSL version: %s SSL error code: %d)", - dcb->remote, - SSL_get_version(dcb->ssl), - ssl_errnum); + MXS_ERROR("Fatal error in SSL_accept for %s: (SSL version: %s SSL error code: %d)", + dcb->remote, + SSL_get_version(dcb->ssl), + ssl_errnum); if(ssl_errnum == SSL_ERROR_SSL || ssl_errnum == SSL_ERROR_SYSCALL) { while((err_errnum = ERR_get_error()) != 0) { ERR_error_string_n(err_errnum,errbuf,sizeof(errbuf)); - skygw_log_write(LE, - "%s", - errbuf); + MXS_ERROR("%s", errbuf); } if(errno) { - skygw_log_write(LE, "Error: SSL authentication failed due to system" - " error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("SSL authentication failed due to system" + " error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))); } } } break; default: - skygw_log_write_flush(LE, - "Error: Fatal library error in SSL_accept, returned value was %d.", - ssl_rval); + MXS_ERROR("Fatal library error in SSL_accept, returned value was %d.", ssl_rval); rval = -1; break; } ioctl(fd,FIONREAD,&b); pending = SSL_pending(dcb->ssl); #ifdef SS_DEBUG - skygw_log_write_flush(LD,"[dcb_accept_SSL] fd %d: %d bytes, %d pending",fd,b,pending); + MXS_DEBUG("[dcb_accept_SSL] fd %d: %d bytes, %d pending", fd, b, pending); #endif }while((b > 0 || pending > 0) && rval != -1); @@ -3075,16 +2988,16 @@ int dcb_connect_SSL(DCB* dcb) { case 0: errnum = SSL_get_error(dcb->ssl,rval); - LOGIF(LD,(skygw_log_write_flush(LD,"SSL_connect shutdown for %s@%s", - dcb->user, - dcb->remote))); + MXS_DEBUG("SSL_connect shutdown for %s@%s", + dcb->user, + dcb->remote); return -1; break; case 1: rval = 1; - LOGIF(LD,(skygw_log_write_flush(LD,"SSL_connect done for %s@%s", - dcb->user, - dcb->remote))); + MXS_DEBUG("SSL_connect done for %s@%s", + dcb->user, + dcb->remote); return rval; case -1: @@ -3096,27 +3009,24 @@ int dcb_connect_SSL(DCB* dcb) queue and wait for more.*/ rval = 0; - LOGIF(LD,(skygw_log_write_flush(LD,"SSL_connect ongoing for %s@%s", - dcb->user, - dcb->remote))); + MXS_DEBUG("SSL_connect ongoing for %s@%s", + dcb->user, + dcb->remote); } else { rval = -1; ERR_error_string_n(errnum,errbuf,sizeof(errbuf)); - skygw_log_write_flush(LE, - "Error: Fatal error in SSL_accept for %s@%s: (SSL error code: %d) %s", - dcb->user, - dcb->remote, - errnum, - errbuf); + MXS_ERROR("Fatal error in SSL_accept for %s@%s: (SSL error code: %d) %s", + dcb->user, + dcb->remote, + errnum, + errbuf); } break; default: - skygw_log_write_flush(LE, - "Error: Fatal error in SSL_connect, returned value was %d.", - rval); + MXS_ERROR("Fatal error in SSL_connect, returned value was %d.", rval); break; } @@ -3165,14 +3075,13 @@ int dcb_bytes_readable_SSL(DCB *dcb, int nread) if (rc == -1) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : ioctl FIONREAD for dcb %p in " - "state %s fd %d failed due error %d, %s.", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - errno, - strerror_r(errno, errbuf, sizeof (errbuf))))); + MXS_ERROR("ioctl FIONREAD for dcb %p in " + "state %s fd %d failed due error %d, %s.", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + errno, + strerror_r(errno, errbuf, sizeof (errbuf))); rval = -1; } else @@ -3202,12 +3111,11 @@ int dcb_bytes_readable_SSL(DCB *dcb, int nread) #ifdef SS_DEBUG else if (nbytes != 0 || pending != 0) { - skygw_log_write_flush(LD, "Total: %d Socket: %d Pending: %d", - nread, nbytes, pending); + MXS_DEBUG("Total: %d Socket: %d Pending: %d", nread, nbytes, pending); } else { - skygw_log_write(LD, "Tried to read from socket, no data left. %d bytes read in total.", nread); + MXS_DEBUG("Tried to read from socket, no data left. %d bytes read in total.", nread); } #endif } @@ -3228,14 +3136,13 @@ void dcb_log_ssl_read_error(DCB *dcb, int ssl_errno, int rc) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Read failed, dcb %p in state " - "%s fd %d, SSL error %d: %s.", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - ssl_errno, - strerror_r(errno, errbuf, sizeof (errbuf))))); + MXS_ERROR("Read failed, dcb %p in state " + "%s fd %d, SSL error %d: %s.", + dcb, + STRDCBSTATE(dcb->state), + dcb->fd, + ssl_errno, + strerror_r(errno, errbuf, sizeof(errbuf))); if (ssl_errno == SSL_ERROR_SSL || ssl_errno == SSL_ERROR_SYSCALL) @@ -3243,9 +3150,7 @@ void dcb_log_ssl_read_error(DCB *dcb, int ssl_errno, int rc) while ((ssl_errno = ERR_get_error()) != 0) { ERR_error_string_n(ssl_errno, errbuf, STRERROR_BUFLEN); - skygw_log_write(LE, - "%s", - errbuf); + MXS_ERROR("%s", errbuf); } } } diff --git a/server/core/externcmd.c b/server/core/externcmd.c index ee6e2d28a..f3bfb4ec7 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -94,12 +94,12 @@ EXTERNCMD* externcmd_allocate(char* argstr) { if (access(cmd->argv[0], F_OK) != 0) { - skygw_log_write(LE, "Cannot find file: %s", cmd->argv[0]); + MXS_ERROR("Cannot find file: %s", cmd->argv[0]); } else { - skygw_log_write(LE, "Cannot execute file '%s'. Missing " - "execution permissions.", cmd->argv[0]); + MXS_ERROR("Cannot execute file '%s'. Missing " + "execution permissions.", cmd->argv[0]); } externcmd_free(cmd); cmd = NULL; @@ -152,8 +152,8 @@ int externcmd_execute(EXTERNCMD* cmd) if (pid < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LOGFILE_ERROR, "Failed to execute command '%s', fork failed: [%d] %s", - cmd->argv[0], errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to execute command '%s', fork failed: [%d] %s", + cmd->argv[0], errno, strerror_r(errno, errbuf, sizeof(errbuf))); rval = -1; } else if (pid == 0) @@ -166,7 +166,7 @@ int externcmd_execute(EXTERNCMD* cmd) { cmd->child = pid; cmd->n_exec++; - LOGIF(LD, skygw_log_write(LD, "[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd)); + MXS_DEBUG("[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd); } return rval; @@ -274,11 +274,11 @@ bool externcmd_can_execute(const char* argstr) } else if (access(command, F_OK) == 0) { - skygw_log_write(LE, "The executable cannot be executed: %s", command); + MXS_ERROR("The executable cannot be executed: %s", command); } else { - skygw_log_write(LE, "The executable cannot be found: %s", command); + MXS_ERROR("The executable cannot be found: %s", command); } free(command); } diff --git a/server/core/filter.c b/server/core/filter.c index 0afeda131..aef124331 100644 --- a/server/core/filter.c +++ b/server/core/filter.c @@ -345,12 +345,10 @@ DOWNSTREAM *me; if ((me = (DOWNSTREAM *)calloc(1, sizeof(DOWNSTREAM))) == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation for filter session failed " - "due to %d,%s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation for filter session failed " + "due to %d,%s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return NULL; } diff --git a/server/core/gateway.c b/server/core/gateway.c index f17e31fa6..4bc1cbe48 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -292,9 +292,7 @@ static void maxscale_ssl_id(CRYPTO_THREADID* id) */ static void sighup_handler (int i) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Refreshing configuration following SIGHUP\n"))); + MXS_NOTICE("Refreshing configuration following SIGHUP\n"); config_reload(); } @@ -304,18 +302,14 @@ static void sighup_handler (int i) */ static void sigusr1_handler (int i) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Log file flush following reception of SIGUSR1\n"))); + MXS_NOTICE("Log file flush following reception of SIGUSR1\n"); mxs_log_rotate(); } static void sigterm_handler (int i) { extern void shutdown_server(); - skygw_log_write_flush( - LOGFILE_ERROR, - "MaxScale received signal SIGTERM. Exiting."); + MXS_ERROR("MaxScale received signal SIGTERM. Exiting."); mxs_log_flush_sync(); shutdown_server(); } @@ -325,9 +319,7 @@ sigint_handler (int i) { extern void shutdown_server(); - skygw_log_write_flush( - LOGFILE_ERROR, - "MaxScale received signal SIGINT. Shutting down."); + MXS_ERROR("MaxScale received signal SIGINT. Shutting down."); mxs_log_flush_sync(); shutdown_server(); fprintf(stderr, "\n\nShutting down MaxScale\n\n"); @@ -342,28 +334,33 @@ sigchld_handler (int i) if ((child = wait(&exit_status)) == -1) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write_flush(LE, "Error: failed to wait child process: %d %s", - errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to wait child process: %d %s", + errno, strerror_r(errno, errbuf, sizeof(errbuf))); } else { if (WIFEXITED(exit_status)) { - skygw_log_write_flush(WEXITSTATUS(exit_status) != 0 ? LE : LT, - "Child process %d exited with status %d", - child, WEXITSTATUS(exit_status)); + if (WEXITSTATUS(exit_status) != 0) + { + MXS_ERROR("Child process %d exited with status %d", + child, WEXITSTATUS(exit_status)); + } + else + { + MXS_INFO("Child process %d exited with status %d", + child, WEXITSTATUS(exit_status)); + } } else if (WIFSIGNALED(exit_status)) { - skygw_log_write_flush((LE|LT), - "Child process %d was stopped by signal %d.", - child, WTERMSIG(exit_status)); + MXS_ERROR("Child process %d was stopped by signal %d.", + child, WTERMSIG(exit_status)); } else { - skygw_log_write_flush((LE|LT), - "Child process %d did not exit normally. Exit status: %d", - child, exit_status); + MXS_ERROR("Child process %d did not exit normally. Exit status: %d", + child, exit_status); } } } @@ -383,13 +380,11 @@ sigfatal_handler(int i) GATEWAY_CONF* cnf = config_get_global_options(); fprintf(stderr, "\n\nMaxScale "MAXSCALE_VERSION" received fatal signal %d\n", i); - skygw_log_write_flush( - LOGFILE_ERROR, - "Fatal: MaxScale "MAXSCALE_VERSION" received fatal signal %d. Attempting backtrace.", i); + MXS_ERROR("Fatal: MaxScale "MAXSCALE_VERSION" received fatal signal %d. Attempting backtrace.", i); - skygw_log_write_flush(LE, "Commit ID: %s System name: %s " - "Release string: %s Embedded library version: %s", - maxscale_commit, cnf->sysname, cnf->release_string, cnf->version_string); + MXS_ERROR("Commit ID: %s System name: %s " + "Release string: %s Embedded library version: %s", + maxscale_commit, cnf->sysname, cnf->release_string, cnf->version_string); { void *addrs[128]; @@ -398,9 +393,7 @@ sigfatal_handler(int i) if (symbols) { for (n = 0; n < count; n++) { - skygw_log_write_flush( - LOGFILE_ERROR, - " %s\n", symbols[n]); + MXS_ERROR(" %s\n", symbols[n]); } free(symbols); } else { @@ -446,12 +439,10 @@ static int signal_set(int sig, void (*handler)(int)) { int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed call sigaction() in %s due to %d, %s.", - program_invocation_short_name, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed call sigaction() in %s due to %d, %s.", + program_invocation_short_name, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); rc = 1; } return rc; @@ -475,13 +466,11 @@ int ntfw_cb( int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - skygw_log_write( - LOGFILE_ERROR, - "Error : Failed to remove the data directory %s of " - "MaxScale due to %d, %s.", - datadir, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to remove the data directory %s of " + "MaxScale due to %d, %s.", + datadir, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } return rc; } @@ -776,13 +765,11 @@ static void print_log_n_stderr( if (do_log) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write_flush( - LOGFILE_ERROR, - "%s %s %s %s", - log_err, - logstr, - eno == 0 ? " " : "Error :", - eno == 0 ? " " : strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_ERROR("%s %s %s %s", + log_err, + logstr, + eno == 0 ? " " : "Error :", + eno == 0 ? " " : strerror_r(eno, errbuf, sizeof(errbuf))); } if (do_stderr) { char errbuf[STRERROR_BUFLEN]; @@ -815,13 +802,11 @@ static bool file_is_readable( absolute_pathname, strerror_r(eno, errbuf, sizeof(errbuf))); } - skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : Failed to read the configuration file %s due " - "to %d, %s.", - absolute_pathname, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_WARNING("Failed to read the configuration file %s due " + "to %d, %s.", + absolute_pathname, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); mxs_log_flush_sync(); succp = false; } @@ -848,13 +833,11 @@ static bool file_is_writable( eno, strerror_r(eno, errbuf, sizeof(errbuf))); } - skygw_log_write_flush( - LOGFILE_ERROR, - "Error : unable to open file %s for write due " - "to %d, %s.", - absolute_pathname, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_ERROR("Unable to open file %s for write due " + "to %d, %s.", + absolute_pathname, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); succp = false; } return succp; @@ -909,14 +892,11 @@ static char* get_expanded_pathname( relative_path, strerror_r(eno, errbuf, sizeof(errbuf))); - skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : Failed to read the " - "directory %s, due " - "to %d, %s.", - relative_path, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_WARNING("Failed to read the directory %s, due " + "to %d, %s.", + relative_path, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); free(expanded_path); *output_path = NULL; goto return_cnf_file_buf; @@ -939,10 +919,8 @@ static char* get_expanded_pathname( ss_dassert(cnf_file_buf != NULL); char errbuf[STRERROR_BUFLEN]; - skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); free(expanded_path); expanded_path = NULL; @@ -1672,7 +1650,7 @@ int main(int argc, char **argv) snprintf(errorbuffer, sizeof(errorbuffer), "Error: Failed to pre-parse configuration file. Memory allocation failed."); - skygw_log_write(LE, errorbuffer); + MXS_ERROR("%s", errorbuffer); if (!daemon_mode) { strncat(errorbuffer, "\n", STRING_BUFFER_SIZE); @@ -1775,29 +1753,11 @@ int main(int argc, char **argv) get_cachedir()); } - LOGIF(LM, - (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Configuration file: %s", - cnf_file_path))); - LOGIF(LM, - (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Log directory: %s/", - get_logdir()))); - LOGIF(LM, - (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Data directory: %s", - get_datadir()))); - LOGIF(LM, - (skygw_log_write_flush(LOGFILE_MESSAGE, - "Module directory: %s", - get_libdir()))); - LOGIF(LM, - (skygw_log_write_flush(LOGFILE_MESSAGE, - "Service cache: %s", - get_cachedir()))); + MXS_NOTICE("Configuration file: %s", cnf_file_path); + MXS_NOTICE("Log directory: %s", get_logdir()); + MXS_NOTICE("Data directory: %s", get_datadir()); + MXS_NOTICE("Module directory: %s", get_libdir()); + MXS_NOTICE("Service cache: %s", get_cachedir()); /*< Update the server options */ for (i = 0; server_options[i]; i++) @@ -1854,15 +1814,13 @@ int main(int argc, char **argv) } } } - skygw_log_write_flush( - LOGFILE_ERROR, - "Error : mysql_library_init failed. It is a " - "mandatory component, required by router services and " - "the MaxScale core. Error %d, %s, %s : %d. Exiting.", - mysql_errno(NULL), - mysql_error(NULL), - __FILE__, - __LINE__); + MXS_ERROR("mysql_library_init failed. It is a " + "mandatory component, required by router services and " + "the MaxScale core. Error %d, %s, %s : %d. Exiting.", + mysql_errno(NULL), + mysql_error(NULL), + __FILE__, + __LINE__); rc = MAXSCALE_NOLIBRARY; goto return_main; } @@ -1873,22 +1831,14 @@ int main(int argc, char **argv) char* fprerr = "Failed to load MaxScale configuration " "file. Exiting. See the error log for details."; print_log_n_stderr(false, !daemon_mode, fprerr, fprerr, 0); - skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to load MaxScale configuration file %s. " - "Exiting.", - cnf_file_path); + MXS_ERROR("Failed to load MaxScale configuration file %s. " + "Exiting.", + cnf_file_path); rc = MAXSCALE_BADCONFIG; goto return_main; } - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "MariaDB Corporation MaxScale %s (C) MariaDB Corporation Ab 2013-2015", - MAXSCALE_VERSION))); - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "MaxScale is running in process %i", - getpid()))); + MXS_NOTICE("MariaDB Corporation MaxScale %s (C) MariaDB Corporation Ab 2013-2015", MAXSCALE_VERSION); + MXS_NOTICE("MaxScale is running in process %i", getpid()); /** Check if a MaxScale process is already running */ if (pid_file_exists()) @@ -1952,9 +1902,7 @@ int main(int argc, char **argv) { threads[thread_id] = thread_start(poll_waitevents, (void *)(thread_id + 1)); } - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "MaxScale started with %d server threads.", - config_threadcount()))); + MXS_NOTICE("MaxScale started with %d server threads.", config_threadcount()); /** * Successful start, notify the parent process that it can exit. */ @@ -1983,16 +1931,12 @@ int main(int argc, char **argv) /*< Stop all the monitors */ monitorStopAll(); - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "MaxScale is shutting down."))); + MXS_NOTICE("MaxScale is shutting down."); /** Release mysql thread context*/ mysql_thread_end(); datadir_cleanup(); - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "MaxScale shutdown completed."))); + MXS_NOTICE("MaxScale shutdown completed."); unload_all_modules(); /* Remove Pidfile */ @@ -2052,14 +1996,12 @@ static void log_flush_cb( ts1.tv_sec = timeout_ms/1000; ts1.tv_nsec = (timeout_ms%1000) * 1000000; - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "Started MaxScale log flusher."))); + MXS_NOTICE("Started MaxScale log flusher."); while (!do_exit) { mxs_log_flush(); nanosleep(&ts1, NULL); } - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "Finished MaxScale log flusher."))); + MXS_NOTICE("Finished MaxScale log flusher."); } static void unlock_pidfile() diff --git a/server/core/gw_utils.c b/server/core/gw_utils.c index 2950cdc15..6054b6372 100644 --- a/server/core/gw_utils.c +++ b/server/core/gw_utils.c @@ -74,26 +74,22 @@ setipaddress(struct in_addr *a, char *p) { hint.ai_flags = AI_PASSIVE; hint.ai_family = AF_UNSPEC; if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to obtain address for host %s, %s", - p, - gai_strerror(rc)))); + MXS_ERROR("Failed to obtain address for host %s, %s", + p, + gai_strerror(rc)); - return 0; + return 0; } } else { hint.ai_flags = AI_CANONNAME; hint.ai_family = AF_INET; if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to obtain address for host %s, %s", - p, - gai_strerror(rc)))); + MXS_ERROR("Failed to obtain address for host %s, %s", + p, + gai_strerror(rc)); - return 0; + return 0; } } @@ -115,12 +111,9 @@ setipaddress(struct in_addr *a, char *p) { if (h == NULL) { if ((a->s_addr = inet_addr(p)) == -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : gethostbyname failed for [%s]", - p))); + MXS_ERROR("gethostbyname failed for [%s]", p); - return 0; + return 0; } } else { /* take the first one */ @@ -208,11 +201,8 @@ struct hostent *hp; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to lookup host '%s'. ", - buf))); - return 0; + MXS_ERROR("Failed to lookup host '%s'.", buf); + return 0; } } } @@ -233,7 +223,7 @@ long get_processor_count() #ifdef _SC_NPROCESSORS_ONLN if ((processors = sysconf(_SC_NPROCESSORS_ONLN)) <= 0) { - skygw_log_write(LE, "Unable to establish the number of available cores. Defaulting to 4."); + MXS_WARNING("Unable to establish the number of available cores. Defaulting to 4."); processors = 4; } #else diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 50d543261..260c691f9 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -88,10 +88,8 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) mem->data = realloc(mem->data, mem->size + realsize + 1); if(mem->data == NULL) { /* out of memory! */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error in module_feedback_send(), not enough memory for realloc"))); - return 0; + MXS_ERROR("Error in module_feedback_send(), not enough memory for realloc"); + return 0; } memcpy(&(mem->data[mem->size]), contents, realsize); @@ -133,36 +131,30 @@ MODULE_INFO *mod_info = NULL; if (access(fname, F_OK) == -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to find library for " - "module: %s. Module dir: %s", - module, get_libdir()))); + MXS_ERROR("Unable to find library for " + "module: %s. Module dir: %s", + module, get_libdir()); return NULL; } if ((dlhandle = dlopen(fname, RTLD_NOW|RTLD_LOCAL)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load library for module: " - "%s\n\n\t\t %s." - "\n\n", - module, - dlerror()))); - return NULL; + MXS_ERROR("Unable to load library for module: " + "%s\n\n\t\t %s." + "\n\n", + module, + dlerror()); + return NULL; } if ((sym = dlsym(dlhandle, "version")) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Version interface not supported by " - "module: %s\n\t\t\t %s.", - module, - dlerror()))); - dlclose(dlhandle); - return NULL; + MXS_ERROR("Version interface not supported by " + "module: %s\n\t\t\t %s.", + module, + dlerror()); + dlclose(dlhandle); + return NULL; } ver = sym; version = ver(); @@ -183,42 +175,26 @@ MODULE_INFO *mod_info = NULL; if (strcmp(type, MODULE_PROTOCOL) == 0 && mod_info->modapi != MODULE_API_PROTOCOL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Module '%s' does not implement " - "the protocol API.\n", - module))); - fatal = 1; + MXS_ERROR("Module '%s' does not implement the protocol API.", module); + fatal = 1; } if (strcmp(type, MODULE_ROUTER) == 0 && mod_info->modapi != MODULE_API_ROUTER) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Module '%s' does not implement " - "the router API.\n", - module))); - fatal = 1; + MXS_ERROR("Module '%s' does not implement the router API.", module); + fatal = 1; } if (strcmp(type, MODULE_MONITOR) == 0 && mod_info->modapi != MODULE_API_MONITOR) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Module '%s' does not implement " - "the monitor API.\n", - module))); - fatal = 1; + MXS_ERROR("Module '%s' does not implement the monitor API.", module); + fatal = 1; } if (strcmp(type, MODULE_FILTER) == 0 && mod_info->modapi != MODULE_API_FILTER) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Module '%s' does not implement " - "the filter API.\n", - module))); - fatal = 1; + MXS_ERROR("Module '%s' does not implement the filter API.", module); + fatal = 1; } if (fatal) { @@ -229,24 +205,20 @@ MODULE_INFO *mod_info = NULL; if ((sym = dlsym(dlhandle, "GetModuleObject")) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Expected entry point interface missing " - "from module: %s\n\t\t\t %s.", - module, - dlerror()))); - dlclose(dlhandle); - return NULL; + MXS_ERROR("Expected entry point interface missing " + "from module: %s\n\t\t\t %s.", + module, + dlerror()); + dlclose(dlhandle); + return NULL; } ep = sym; modobj = ep(); - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "Loaded module %s: %s from %s", - module, - version, - fname))); + MXS_NOTICE("Loaded module %s: %s from %s", + module, + version, + fname); register_module(module, type, dlhandle, version, modobj, mod_info); } else @@ -448,11 +420,9 @@ MODULES *modules_list = registered; FEEDBACK_CONF *feedback_config = config_get_feedback_data(); if (!module_create_feedback_report(&buffer, modules_list, feedback_config)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory"))); + MXS_ERROR("Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory"); - return; + return; } dcb_printf(dcb, (char *)GWBUF_DATA(buffer)); gwbuf_free(buffer); @@ -568,13 +538,12 @@ module_feedback_send(void* data) { /* Configuration check */ if (feedback_config->feedback_enable == 0 || feedback_config->feedback_url == NULL || feedback_config->feedback_user_info == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error in module_feedback_send(): some mandatory parameters are not set" - " feedback_enable=%u, feedback_url=%s, feedback_user_info=%s", - feedback_config->feedback_enable, - feedback_config->feedback_url == NULL ? "NULL" : feedback_config->feedback_url, - feedback_config->feedback_user_info == NULL ? "NULL" : feedback_config->feedback_user_info))); + MXS_ERROR("Error in module_feedback_send(): some mandatory parameters are not set" + " feedback_enable=%u, feedback_url=%s, feedback_user_info=%s", + feedback_config->feedback_enable, + feedback_config->feedback_url == NULL ? "NULL" : feedback_config->feedback_url, + feedback_config->feedback_user_info == NULL ? + "NULL" : feedback_config->feedback_user_info); feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR; @@ -591,36 +560,29 @@ module_feedback_send(void* data) { /* It's not the rigt time, mark it as to be done and return */ feedback_config->feedback_last_action = _NOTIFICATION_SEND_PENDING; - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "module_feedback_send(): execution skipped, current hour [%d]" - " is not within the proper interval (from 2 AM to 4 AM)", - hour))); + MXS_INFO("module_feedback_send(): execution skipped, current hour [%d]" + " is not within the proper interval (from 2 AM to 4 AM)", + hour); return; } /* Time to run the task: if a previous run was succesfull skip next runs */ if (feedback_config->feedback_last_action == _NOTIFICATION_SEND_OK) { - /* task was done before, return */ + /* task was done before, return */ - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "module_feedback_send(): execution skipped because of previous succesful run: hour is [%d], last_action [%d]", - hour, feedback_config->feedback_last_action))); + MXS_INFO("module_feedback_send(): execution skipped because of previous " + "succesful run: hour is [%d], last_action [%d]", + hour, feedback_config->feedback_last_action); - return; + return; } - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "module_feedback_send(): task now runs: hour is [%d], last_action [%d]", - hour, feedback_config->feedback_last_action))); + MXS_INFO("module_feedback_send(): task now runs: hour is [%d], last_action [%d]", + hour, feedback_config->feedback_last_action); if (!module_create_feedback_report(&buffer, modules_list, feedback_config)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory"))); + MXS_ERROR("Error in module_create_feedback_report(): gwbuf_alloc() failed to allocate memory"); feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR; @@ -635,16 +597,12 @@ module_feedback_send(void* data) { } else { feedback_config->feedback_last_action = _NOTIFICATION_SEND_ERROR; - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Error in module_create_feedback_report(): do_http_post ret_code is %d", http_send))); + MXS_INFO("Error in module_create_feedback_report(): do_http_post ret_code is %d", http_send); } - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "module_feedback_send(): task completed: hour is [%d], last_action [%d]", - hour, - feedback_config->feedback_last_action))); + MXS_INFO("module_feedback_send(): task completed: hour is [%d], last_action [%d]", + hour, + feedback_config->feedback_last_action); gwbuf_free(buffer); @@ -822,12 +780,10 @@ do_http_post(GWBUF *buffer, void *cfg) { /* Check for errors */ if(res != CURLE_OK) { ret_code = 2; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: do_http_post(), curl call for [%s] failed due: %s, %s", - feedback_config->feedback_url, - curl_easy_strerror(res), - error_message))); + MXS_ERROR("do_http_post(), curl call for [%s] failed due: %s, %s", + feedback_config->feedback_url, + curl_easy_strerror(res), + error_message); goto cleanup; } else { curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); @@ -842,25 +798,18 @@ do_http_post(GWBUF *buffer, void *cfg) { goto cleanup; } } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: do_http_post(), Bad HTTP Code from remote server: %lu", - http_code))); - ret_code = 4; - goto cleanup; + MXS_ERROR("do_http_post(), Bad HTTP Code from remote server: %lu", http_code); + ret_code = 4; + goto cleanup; } } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: do_http_post(), curl object not initialized"))); - ret_code = 1; - goto cleanup; + MXS_ERROR("do_http_post(), curl object not initialized"); + ret_code = 1; + goto cleanup; } - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "do_http_post() ret_code [%d], HTTP code [%d]", - ret_code, http_code))); + MXS_INFO("do_http_post() ret_code [%d], HTTP code [%d]", + ret_code, http_code); cleanup: if (chunk.data) diff --git a/server/core/modutil.c b/server/core/modutil.c index b7c8c467d..0f10005e0 100644 --- a/server/core/modutil.c +++ b/server/core/modutil.c @@ -588,8 +588,7 @@ GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf) /** The next packet is a partial, split into complete and partial packets */ if((buff = gwbuf_clone_portion(packet,0,total)) == NULL) { - skygw_log_write(LOGFILE_ERROR, - "Error: Failed to partially clone buffer."); + MXS_ERROR("Failed to partially clone buffer."); return NULL; } gwbuf_consume(packet,total); @@ -735,10 +734,8 @@ static void modutil_reply_routing_error( if (buf == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Creating routing error message failed."))); - return; + MXS_ERROR("Creating routing error message failed."); + return; } /** Set flags that help router to process reply correctly */ gwbuf_set_type(buf, flags); @@ -876,8 +873,7 @@ void prepare_pcre2_patterns() else { pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - skygw_log_write(LE, "Error: Failed to compile PCRE2 pattern: %s", - errbuf); + MXS_ERROR("Failed to compile PCRE2 pattern: %s", errbuf); } if (!pattern_init) @@ -940,8 +936,7 @@ mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* { PCRE2_UCHAR errbuf[STRERROR_BUFLEN]; pcre2_get_error_message(errcode, errbuf, sizeof(errbuf)); - skygw_log_write(LE, "Error: Failed to match pattern: %s", - errbuf); + MXS_ERROR("Failed to match pattern: %s", errbuf); } err = true; } @@ -954,7 +949,7 @@ mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* if (err) { - skygw_log_write(LE, "Error: Fatal error when matching wildcard patterns."); + MXS_ERROR("Fatal error when matching wildcard patterns."); } pcre2_match_data_free(mdata_percent); diff --git a/server/core/monitor.c b/server/core/monitor.c index 3158f379a..afad7d7da 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -66,12 +66,9 @@ MONITOR *mon; if ((mon->module = load_module(module, MODULE_MONITOR)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load monitor module '%s'.", - name))); - free(mon); - return NULL; + MXS_ERROR("Unable to load monitor module '%s'.", name); + free(mon); + return NULL; } mon->state = MONITOR_STATE_ALLOC; mon->name = strdup(name); @@ -364,10 +361,8 @@ monitorSetNetworkTimeout(MONITOR *mon, int type, int value) { memcpy(&mon->connect_timeout, &value, sizeof(int)); } else { memcpy(&mon->connect_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); + MXS_WARNING("Monitor Connect Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout); } break; @@ -376,10 +371,8 @@ monitorSetNetworkTimeout(MONITOR *mon, int type, int value) { memcpy(&mon->read_timeout, &value, sizeof(int)); } else { memcpy(&mon->read_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Read Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); + MXS_WARNING("Monitor Read Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout); } break; @@ -388,17 +381,13 @@ monitorSetNetworkTimeout(MONITOR *mon, int type, int value) { memcpy(&mon->write_timeout, &value, sizeof(int)); } else { memcpy(&mon->write_timeout, &new_timeout, sizeof(int)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "warning : Monitor Write Timeout %i is greater than monitor interval ~%i seconds" - ", lowering to %i seconds", value, max_timeout, new_timeout))); + MXS_WARNING("Monitor Write Timeout %i is greater than monitor interval ~%i seconds" + ", lowering to %i seconds", value, max_timeout, new_timeout); } break; default: - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Monitor setNetworkTimeout received an unsupported action type %i", type))); - break; + MXS_ERROR("Monitor setNetworkTimeout received an unsupported action type %i", type); + break; } } @@ -486,7 +475,7 @@ bool check_monitor_permissions(MONITOR* monitor) if((mysql = mysql_init(NULL)) == NULL) { - skygw_log_write(LE,"[%s] Error: MySQL connection initialization failed.",__FUNCTION__); + MXS_ERROR("[%s] Error: MySQL connection initialization failed.", __FUNCTION__); free(dpasswd); return false; } @@ -499,12 +488,12 @@ bool check_monitor_permissions(MONITOR* monitor) * user permissions. */ if(mysql_real_connect(mysql,server->name,user,dpasswd,NULL,server->port,NULL,0) == NULL) { - skygw_log_write(LE,"%s: Error: Failed to connect to server %s(%s:%d) when" - " checking monitor user credentials and permissions.", - monitor->name, - server->unique_name, - server->name, - server->port); + MXS_ERROR("%s: Failed to connect to server %s(%s:%d) when" + " checking monitor user credentials and permissions.", + monitor->name, + server->unique_name, + server->name, + server->port); mysql_close(mysql); free(dpasswd); return false; @@ -514,13 +503,13 @@ bool check_monitor_permissions(MONITOR* monitor) { if(mysql_errno(mysql) == ER_SPECIFIC_ACCESS_DENIED_ERROR) { - skygw_log_write(LE,"%s: Error: User '%s' is missing REPLICATION CLIENT privileges. MySQL error message: %s", - monitor->name,user,mysql_error(mysql)); + MXS_ERROR("%s: User '%s' is missing REPLICATION CLIENT privileges. MySQL error message: %s", + monitor->name,user,mysql_error(mysql)); } else { - skygw_log_write(LE,"%s: Error: Monitor failed to query for slave status. MySQL error message: %s", - monitor->name,mysql_error(mysql)); + MXS_ERROR("%s: Monitor failed to query for slave status. MySQL error message: %s", + monitor->name,mysql_error(mysql)); } rval = false; } @@ -528,8 +517,8 @@ bool check_monitor_permissions(MONITOR* monitor) { if((res = mysql_use_result(mysql)) == NULL) { - skygw_log_write(LE,"%s: Error: Result retrieval failed when checking for REPLICATION CLIENT permissions: %s", - monitor->name,mysql_error(mysql)); + MXS_ERROR("%s: Result retrieval failed when checking for REPLICATION CLIENT permissions: %s", + monitor->name,mysql_error(mysql)); rval = false; } else diff --git a/server/core/poll.c b/server/core/poll.c index dfdfb53c5..1a74aeb93 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -284,25 +284,21 @@ poll_add_dcb(DCB *dcb) || DCB_STATE_ZOMBIE == dcb->state || DCB_STATE_UNDEFINED == dcb->state) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_add_dcb] Error : existing state of dcb %p " - "is %s, but this should be impossible, crashing.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p " + "is %s, but this should be impossible, crashing.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); raise(SIGABRT); } if (DCB_STATE_POLLING == dcb->state || DCB_STATE_LISTENING == dcb->state) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_add_dcb] Error : existing state of dcb %p " - "is %s, but this is probably an error, not crashing.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p " + "is %s, but this is probably an error, not crashing.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); } dcb->state = new_state; spinlock_release(&dcb->dcb_initlock); @@ -318,12 +314,10 @@ poll_add_dcb(DCB *dcb) } if (0 == rc) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_add_dcb] Added dcb %p in state %s to poll set.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_DEBUG("%lu [poll_add_dcb] Added dcb %p in state %s to poll set.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); } else dcb->state = old_state; return rc; @@ -354,13 +348,11 @@ poll_remove_dcb(DCB *dcb) if (DCB_STATE_POLLING != dcb->state && DCB_STATE_LISTENING != dcb->state) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_remove_dcb] Error : existing state of dcb %p " - "is %s, but this is probably an error, not crashing.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_ERROR("%lu [poll_remove_dcb] Error : existing state of dcb %p " + "is %s, but this is probably an error, not crashing.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); } /*< * Set state to NOPOLLING and remove dcb from poll set. @@ -409,25 +401,21 @@ poll_resolve_error(DCB *dcb, int errornum, bool adding) { if (EEXIST == errornum) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_resolve_error] Error : epoll_ctl could not add, " - "already exists for DCB %p.", - pthread_self(), - dcb))); + MXS_ERROR("%lu [poll_resolve_error] Error : epoll_ctl could not add, " + "already exists for DCB %p.", + pthread_self(), + dcb); // Assume another thread added and no serious harm done return 0; } if (ENOSPC == errornum) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_resolve_error] The limit imposed by " - "/proc/sys/fs/epoll/max_user_watches was " - "encountered while trying to register (EPOLL_CTL_ADD) a new " - "file descriptor on an epoll instance for dcb %p.", - pthread_self(), - dcb))); + MXS_ERROR("%lu [poll_resolve_error] The limit imposed by " + "/proc/sys/fs/epoll/max_user_watches was " + "encountered while trying to register (EPOLL_CTL_ADD) a new " + "file descriptor on an epoll instance for dcb %p.", + pthread_self(), + dcb); /* Failure - assume handled by callers */ return -1; } @@ -437,12 +425,10 @@ poll_resolve_error(DCB *dcb, int errornum, bool adding) /* Must be removing */ if (ENOENT == errornum) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [poll_resolve_error] Error : epoll_ctl could not remove, " - "not found, for dcb %p.", - pthread_self(), - dcb))); + MXS_ERROR("%lu [poll_resolve_error] Error : epoll_ctl could not remove, " + "not found, for dcb %p.", + pthread_self(), + dcb); // Assume another thread removed and no serious harm done return 0; } @@ -557,13 +543,11 @@ int poll_spins = 0; atomic_add(&n_waiting, -1); int eno = errno; errno = 0; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] epoll_wait returned " - "%d, errno %d", - pthread_self(), - nfds, - eno))); + MXS_DEBUG("%lu [poll_waitevents] epoll_wait returned " + "%d, errno %d", + pthread_self(), + nfds, + eno); atomic_add(&n_waiting, -1); } /* @@ -604,11 +588,9 @@ int poll_spins = 0; if (poll_spins <= number_poll_spins + 1) atomic_add(&pollStats.n_nbpollev, 1); poll_spins = 0; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] epoll_wait found %d fds", - pthread_self(), - nfds))); + MXS_DEBUG("%lu [poll_waitevents] epoll_wait found %d fds", + pthread_self(), + nfds); atomic_add(&pollStats.n_pollev, 1); if (thread_data) { @@ -757,8 +739,8 @@ poll_set_maxwait(unsigned int maxwait) * Including session id to log entries depends on this function. Assumption is * that when maxscale thread starts processing of an event it processes one * and only one session until it returns from this function. Session id is - * read to thread's local storage in macro LOGIF_MAYBE(...) and reset back - * to zero just before returning in LOGIF(...) macro. + * read to thread's local storage if LOG_MAY_BE_ENABLED(LOGFILE_TRACE) returns true + * reset back to zero just before returning in LOG_IS_ENABLED(LOGFILE_TRACE) returns true. * Thread local storage (tls_log_info_t) follows thread and is accessed every * time log is written to particular log. * @@ -842,15 +824,13 @@ unsigned long qtime; #if defined(FAKE_CODE) if (dcb_fake_write_ev[dcb->fd] != 0) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "Added fake events %d to ev %d.", - pthread_self(), - dcb_fake_write_ev[dcb->fd], - ev))); - ev |= dcb_fake_write_ev[dcb->fd]; - dcb_fake_write_ev[dcb->fd] = 0; + MXS_DEBUG("%lu [poll_waitevents] " + "Added fake events %d to ev %d.", + pthread_self(), + dcb_fake_write_ev[dcb->fd], + ev); + ev |= dcb_fake_write_ev[dcb->fd]; + dcb_fake_write_ev[dcb->fd] = 0; } #endif /* FAKE_CODE */ ss_debug(spinlock_acquire(&dcb->dcb_initlock);) @@ -861,16 +841,14 @@ unsigned long qtime; { return 0; } - ss_debug(spinlock_release(&dcb->dcb_initlock);) + ss_debug(spinlock_release(&dcb->dcb_initlock)); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] event %d dcb %p " - "role %s", - pthread_self(), - ev, - dcb, - STRDCBROLE(dcb->dcb_role)))); + MXS_DEBUG("%lu [poll_waitevents] event %d dcb %p " + "role %s", + pthread_self(), + ev, + dcb, + STRDCBROLE(dcb->dcb_role)); if (ev & EPOLLOUT) { @@ -893,28 +871,24 @@ unsigned long qtime; } } else { char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "EPOLLOUT due %d, %s. " - "dcb %p, fd %i", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf)), - dcb, - dcb->fd))); + MXS_DEBUG("%lu [poll_waitevents] " + "EPOLLOUT due %d, %s. " + "dcb %p, fd %i", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf)), + dcb, + dcb->fd); } } if (ev & EPOLLIN) { if (dcb->state == DCB_STATE_LISTENING) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "Accept in fd %d", - pthread_self(), - dcb->fd))); + MXS_DEBUG("%lu [poll_waitevents] " + "Accept in fd %d", + pthread_self(), + dcb->fd); atomic_add( &pollStats.n_accept, 1); if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) @@ -931,13 +905,11 @@ unsigned long qtime; } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "Read in dcb %p fd %d", - pthread_self(), - dcb, - dcb->fd))); + MXS_DEBUG("%lu [poll_waitevents] " + "Read in dcb %p fd %d", + pthread_self(), + dcb, + dcb->fd); atomic_add(&pollStats.n_read, 1); /** Read session id to thread's local storage */ if (LOG_MAY_BE_ENABLED(LOGFILE_TRACE)) @@ -960,26 +932,22 @@ unsigned long qtime; if (eno == 0) { eno = dcb_fake_write_errno[dcb->fd]; char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "Added fake errno %d. " - "%s", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [poll_waitevents] " + "Added fake errno %d. " + "%s", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } dcb_fake_write_errno[dcb->fd] = 0; #endif /* FAKE_CODE */ if (eno != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "EPOLLERR due %d, %s.", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [poll_waitevents] " + "EPOLLERR due %d, %s.", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } atomic_add(&pollStats.n_error, 1); /** Read session id to thread's local storage */ @@ -1000,16 +968,14 @@ unsigned long qtime; int eno = 0; eno = gw_getsockerrno(dcb->fd); char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "EPOLLHUP on dcb %p, fd %d. " - "Errno %d, %s.", - pthread_self(), - dcb, - dcb->fd, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [poll_waitevents] " + "EPOLLHUP on dcb %p, fd %d. " + "Errno %d, %s.", + pthread_self(), + dcb, + dcb->fd, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); atomic_add(&pollStats.n_hup, 1); spinlock_acquire(&dcb->dcb_initlock); if ((dcb->flags & DCBF_HUNG) == 0) @@ -1038,16 +1004,14 @@ unsigned long qtime; int eno = 0; eno = gw_getsockerrno(dcb->fd); char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [poll_waitevents] " - "EPOLLRDHUP on dcb %p, fd %d. " - "Errno %d, %s.", - pthread_self(), - dcb, - dcb->fd, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [poll_waitevents] " + "EPOLLRDHUP on dcb %p, fd %d. " + "Errno %d, %s.", + pthread_self(), + dcb, + dcb->fd, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); atomic_add(&pollStats.n_hup, 1); spinlock_acquire(&dcb->dcb_initlock); if ((dcb->flags & DCBF_HUNG) == 0) @@ -1126,7 +1090,10 @@ unsigned long qtime; } dcb->evq.processing = 0; /** Reset session id from thread's local storage */ - LOGIF(LT, tls_log_info.li_sesid = 0); + if (LOG_IS_ENABLED(LOGFILE_TRACE)) + { + tls_log_info.li_sesid = 0; + } spinlock_release(&pollqlock); return 1; @@ -1150,14 +1117,12 @@ poll_dcb_session_check(DCB *dcb, const char *function) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [%s] The dcb %p that was about to be processed by %s does not " - "have a non-null session pointer ", - pthread_self(), - __func__, - dcb, - function))); + MXS_ERROR("%lu [%s] The dcb %p that was about to be processed by %s does not " + "have a non-null session pointer ", + pthread_self(), + __func__, + dcb, + function); return false; } } diff --git a/server/core/secrets.c b/server/core/secrets.c index 01cf66315..83f0f9edf 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -82,23 +82,21 @@ secrets_readKeys(const char* path) if (!reported) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, - "Encrypted password file %s can't be accessed " - "(%s). Password encryption is not used.", - secret_file, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_NOTICE("Encrypted password file %s can't be accessed " + "(%s). Password encryption is not used.", + secret_file, + strerror_r(eno, errbuf, sizeof(errbuf))); reported = 1; } } else { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : access for secrets file " - "[%s] failed. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Access for secrets file " + "[%s] failed. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } return NULL; } @@ -109,12 +107,11 @@ secrets_readKeys(const char* path) int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Failed opening secret " - "file [%s]. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed opening secret " + "file [%s]. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; } @@ -126,12 +123,11 @@ secrets_readKeys(const char* path) errno = 0; close(fd); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : fstat for secret file %s " - "failed. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("fstat for secret file %s " + "failed. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; } @@ -141,30 +137,26 @@ secrets_readKeys(const char* path) errno = 0; close(fd); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Secrets file %s has " - "incorrect size. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Secrets file %s has " + "incorrect size. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; } if (secret_stats.st_mode != (S_IRUSR | S_IFREG)) { close(fd); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Ignoring secrets file " - "%s, invalid permissions.", - secret_file))); + MXS_ERROR("Ignoring secrets file " + "%s, invalid permissions.", + secret_file); return NULL; } if ((keys = (MAXKEYS *) malloc(sizeof(MAXKEYS))) == NULL) { close(fd); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Memory allocation failed " - "for key structure."))); + MXS_ERROR("Memory allocation failed for key structure."); return NULL; } @@ -181,14 +173,13 @@ secrets_readKeys(const char* path) close(fd); free(keys); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Read from secrets file " - "%s failed. Read %d, expected %d bytes. Error %d, %s.", - secret_file, - len, - sizeof(MAXKEYS), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Read from secrets file " + "%s failed. Read %d, expected %d bytes. Error %d, %s.", + secret_file, + len, + sizeof(MAXKEYS), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; } @@ -199,12 +190,11 @@ secrets_readKeys(const char* path) errno = 0; free(keys); char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Failed closing the " - "secrets file %s. Error %d, %s.", - secret_file, - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed closing the " + "secrets file %s. Error %d, %s.", + secret_file, + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; } ss_dassert(keys != NULL); @@ -229,7 +219,7 @@ int secrets_writeKeys(const char *path) if (strlen(path) > PATH_MAX) { - skygw_log_write(LOGFILE_ERROR, "Error: Pathname too long."); + MXS_ERROR("Pathname too long."); return 1; } @@ -240,12 +230,11 @@ int secrets_writeKeys(const char *path) if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed opening secret " - "file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("failed opening secret " + "file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return 1; } @@ -253,18 +242,16 @@ int secrets_writeKeys(const char *path) if ((randfd = open("/dev/random", O_RDONLY)) < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed opening /dev/random. Error %d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("failed opening /dev/random. Error %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); close(fd); return 1; } if (read(randfd, (void*) &randval, sizeof(unsigned int)) < 1) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed to read /dev/random."))); + MXS_ERROR("failed to read /dev/random."); close(fd); close(randfd); return 1; @@ -278,12 +265,11 @@ int secrets_writeKeys(const char *path) if (write(fd, &key, sizeof(key)) < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed writing into " - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("failed writing into " + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); close(fd); return 1; } @@ -292,23 +278,21 @@ int secrets_writeKeys(const char *path) if (close(fd) < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed closing the " - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("failed closing the " + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } if (chmod(secret_file, S_IRUSR) < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : failed to change the permissions of the" - "secret file [%s]. Error %d, %s.", - secret_file, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("failed to change the permissions of the" + "secret file [%s]. Error %d, %s.", + secret_file, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } return 0; diff --git a/server/core/server.c b/server/core/server.c index dad510c1c..41080e251 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -182,19 +182,17 @@ server_get_persistent(SERVER *server, char *user, const char *protocol) } else { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [server_get_persistent] Rejected dcb " - "%p from pool, user %s looking for %s, protocol %s " - "looking for %s, hung flag %s, error handle called %s.", - pthread_self(), - dcb, - dcb->user ? dcb->user : "NULL", - user, - dcb->protoname ? dcb->protoname : "NULL", - protocol, - (dcb->flags & DCBF_HUNG) ? "true" : "false", - dcb-> dcb_errhandle_called ? "true" : "false"))); + MXS_DEBUG("%lu [server_get_persistent] Rejected dcb " + "%p from pool, user %s looking for %s, protocol %s " + "looking for %s, hung flag %s, error handle called %s.", + pthread_self(), + dcb, + dcb->user ? dcb->user : "NULL", + user, + dcb->protoname ? dcb->protoname : "NULL", + protocol, + (dcb->flags & DCBF_HUNG) ? "true" : "false", + dcb-> dcb_errhandle_called ? "true" : "false"); } previous = dcb; dcb = dcb->nextpersistent; @@ -725,26 +723,22 @@ server_update(SERVER *server, char *protocol, char *user, char *passwd) { if (!strcmp(server->protocol, protocol)) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Update server protocol for server %s to protocol %s.", - server->name, - protocol))); - free(server->protocol); - server->protocol = strdup(protocol); + MXS_NOTICE("Update server protocol for server %s to protocol %s.", + server->name, + protocol); + free(server->protocol); + server->protocol = strdup(protocol); } if (user != NULL && passwd != NULL) { if (strcmp(server->monuser, user) == 0 || strcmp(server->monpw, passwd) == 0) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Update server monitor credentials for server %s", - server->name))); - free(server->monuser); - free(server->monpw); - serverAddMonUser(server, user, passwd); + MXS_NOTICE("Update server monitor credentials for server %s", + server->name); + free(server->monuser); + free(server->monpw); + serverAddMonUser(server, user, passwd); } } } diff --git a/server/core/service.c b/server/core/service.c index 0bacd9364..e22484c99 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -118,19 +118,17 @@ SERVICE *service; char* home = get_libdir(); char* ldpath = getenv("LD_LIBRARY_PATH"); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load %s module \"%s\".\n\t\t\t" - " Ensure that lib%s.so exists in one of the " - "following directories :\n\t\t\t " - "- %s\n%s%s", - MODULE_ROUTER, - router, - router, - home, - ldpath?"\t\t\t - ":"", - ldpath?ldpath:""))); - free(service); + MXS_ERROR("Unable to load %s module \"%s\".\n\t\t\t" + " Ensure that lib%s.so exists in one of the " + "following directories :\n\t\t\t " + "- %s\n%s%s", + MODULE_ROUTER, + router, + router, + home, + ldpath?"\t\t\t - ":"", + ldpath?ldpath:""); + free(service); return NULL; } service->name = strdup(servname); @@ -214,11 +212,8 @@ GWPROTOCOL *funcs; if (port->listener == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create listener for service %s.", - service->name))); - goto retblock; + MXS_ERROR("Failed to create listener for service %s.", service->name); + goto retblock; } if (strcmp(port->protocol, "MySQLClient") == 0) { @@ -233,13 +228,11 @@ GWPROTOCOL *funcs; if ((loaded = load_mysql_users(service)) < 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load users for " - "service %s listening at %s:%d.", - service->name, - (port->address == NULL ? "0.0.0.0" : port->address), - port->port))); + MXS_ERROR("Unable to load users for " + "service %s listening at %s:%d.", + service->name, + (port->address == NULL ? "0.0.0.0" : port->address), + port->port); { /* Try loading authentication data from file cache */ @@ -251,9 +244,7 @@ GWPROTOCOL *funcs; loaded = dbusers_load(service->users, path); if (loaded != -1) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Using cached credential information."))); + MXS_ERROR("Using cached credential information."); } } if (loaded == -1) @@ -283,10 +274,10 @@ GWPROTOCOL *funcs; if(errno != EEXIST) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s", - path, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to create directory '%s': [%d] %s", + path, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } mkdir_rval = 0; } @@ -302,10 +293,10 @@ GWPROTOCOL *funcs; if(errno != EEXIST) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LOGFILE_ERROR,"Error : Failed to create directory '%s': [%d] %s", - path, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to create directory '%s': [%d] %s", + path, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } mkdir_rval = 0; } @@ -314,12 +305,10 @@ GWPROTOCOL *funcs; } if (loaded == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Service %s: failed to load any user " - "information. Authentication will " - "probably fail as a result.", - service->name))); + MXS_ERROR("Service %s: failed to load any user " + "information. Authentication will " + "probably fail as a result.", + service->name); } /* At service start last update is set to USERS_REFRESH_TIME seconds earlier. @@ -328,10 +317,8 @@ GWPROTOCOL *funcs; service->rate_limit.last=time(NULL) - USERS_REFRESH_TIME; service->rate_limit.nloads=1; - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Loaded %d MySQL Users for service [%s].", - loaded, service->name))); + MXS_NOTICE("Loaded %d MySQL Users for service [%s].", + loaded, service->name); } } else @@ -350,12 +337,10 @@ GWPROTOCOL *funcs; dcb_close(port->listener); service->users = NULL; port->listener = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to load protocol module %s. Listener " - "for service %s not started.", - port->protocol, - service->name))); + MXS_ERROR("Unable to load protocol module %s. Listener " + "for service %s not started.", + port->protocol, + service->name); goto retblock; } memcpy(&(port->listener->func), funcs, sizeof(GWPROTOCOL)); @@ -376,10 +361,8 @@ GWPROTOCOL *funcs; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create session to service %s.", - service->name))); + MXS_ERROR("Failed to create session to service %s.", + service->name); users_free(service->users); service->users = NULL; @@ -391,12 +374,10 @@ GWPROTOCOL *funcs; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Unable to start to listen port %d for %s %s.", - port->port, - port->protocol, - service->name))); + MXS_ERROR("Unable to start to listen port %d for %s %s.", + port->port, + port->protocol, + service->name); users_free(service->users); service->users = NULL; dcb_close(port->listener); @@ -445,8 +426,8 @@ int serviceStartAllPorts(SERVICE* service) service->name, service->stats.n_failed_starts); hktask_oneshot(taskname, service_interal_restart, (void*) service, retry_after); - skygw_log_write(LM, "Failed to start service %s, retrying in %d seconds.", - service->name, retry_after); + MXS_NOTICE("Failed to start service %s, retrying in %d seconds.", + service->name, retry_after); } return listeners; } @@ -480,25 +461,21 @@ serviceStart(SERVICE *service) } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: Failed to create router instance for service. Service not started.", - service->name))); + MXS_ERROR("%s: Failed to create router instance for service. Service not started.", + service->name); service->state = SERVICE_STATE_FAILED; } } else { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "%s: SSL initialization failed. Service not started.", - service->name))); + MXS_ERROR("%s: SSL initialization failed. Service not started.", service->name); service->state = SERVICE_STATE_FAILED; } } else { - skygw_log_write_flush(LE, - "%s: Error: Inadequate user permissions for service. Service not started.", - service->name); + MXS_ERROR("%s: Inadequate user permissions for service. Service not started.", + service->name); service->state = SERVICE_STATE_FAILED; } return listeners; @@ -546,10 +523,7 @@ int n = 0,i; if(i == 0) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Failed to start service '%s'.", - ptr->name))); + MXS_ERROR("Failed to start service '%s'.", ptr->name); } ptr = ptr->next; @@ -922,7 +896,7 @@ serviceOptimizeWildcard(SERVICE *service, int action) service->optimize_wildcard = action; if(action) { - LOGIF(LM,(skygw_log_write(LOGFILE_MESSAGE,"[%s] Optimizing wildcard database grants.",service->name))); + MXS_NOTICE("[%s] Optimizing wildcard database grants.",service->name); } return 1; } @@ -1105,9 +1079,8 @@ int n = 0; if ((flist = (FILTER_DEF **)malloc(sizeof(FILTER_DEF *))) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Out of memory adding filters to service.\n"))); - return; + MXS_ERROR("Out of memory adding filters to service.\n"); + return; } ptr = strtok_r(filters, "|", &brkt); while (ptr) @@ -1116,18 +1089,14 @@ int n = 0; if ((flist = (FILTER_DEF **)realloc(flist, (n + 1) * sizeof(FILTER_DEF *))) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Out of memory adding filters to service.\n"))); - return; + MXS_ERROR("Out of memory adding filters to service."); + return; } if ((flist[n-1] = filter_find(trim(ptr))) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : Unable to find filter '%s' for service '%s'\n", - trim(ptr), service->name - ))); - n--; + MXS_WARNING("Unable to find filter '%s' for service '%s'\n", + trim(ptr), service->name); + n--; } flist[n] = NULL; ptr = strtok_r(NULL, "|", &brkt); @@ -1405,34 +1374,27 @@ void *router_obj; { if ((router_obj = load_module(router, MODULE_ROUTER)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to update router " - "for service %s to %s.", - service->name, - router))); + MXS_ERROR("Failed to update router " + "for service %s to %s.", + service->name, + router); } else { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Update router for service %s to %s.", - service->name, - router))); - free(service->routerModule); - service->routerModule = strdup(router); - service->router = router_obj; + MXS_NOTICE("Update router for service %s to %s.", + service->name, + router); + free(service->routerModule); + service->routerModule = strdup(router); + service->router = router_obj; } } if (user && (strcmp(service->credentials.name, user) != 0 || strcmp(service->credentials.authdata, auth) != 0)) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Update credentials for service %s.", - service->name))); - serviceSetUser(service, user, auth); + MXS_NOTICE("Update credentials for service %s.", service->name); + serviceSetUser(service, user, auth); } } @@ -1448,22 +1410,19 @@ int service_refresh_users(SERVICE *service) { int ret = 1; /* check for another running getUsers request */ if (! spinlock_acquire_nowait(&service->users_table_spin)) { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%s: [service_refresh_users] failed to get get lock for loading new users' table: another thread is loading users", - service->name))); + MXS_DEBUG("%s: [service_refresh_users] failed to get get lock for " + "loading new users' table: another thread is loading users", + service->name); - return 1; + return 1; } /* check if refresh rate limit has exceeded */ if ( (time(NULL) < (service->rate_limit.last + USERS_REFRESH_TIME)) || (service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME)) { spinlock_release(&service->users_table_spin); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%s: Refresh rate limit exceeded for load of users' table.", - service->name))); + MXS_ERROR("%s: Refresh rate limit exceeded for load of users' table.", + service->name); return 1; } @@ -2046,7 +2005,7 @@ int serviceInitSSL(SERVICE* service) if((service->ctx = SSL_CTX_new(service->method)) == NULL) { - skygw_log_write(LE, "Error: SSL context initialization failed."); + MXS_ERROR("SSL context initialization failed."); return -1; } @@ -2059,7 +2018,7 @@ int serviceInitSSL(SERVICE* service) rsa_512 = RSA_generate_key(512,RSA_F4,NULL,NULL); if (rsa_512 == NULL) { - skygw_log_write(LE,"Error: 512-bit RSA key generation failed."); + MXS_ERROR("512-bit RSA key generation failed."); return -1; } } @@ -2068,7 +2027,7 @@ int serviceInitSSL(SERVICE* service) rsa_1024 = RSA_generate_key(1024,RSA_F4,NULL,NULL); if (rsa_1024 == NULL) { - skygw_log_write(LE,"Error: 1024-bit RSA key generation failed."); + MXS_ERROR("1024-bit RSA key generation failed."); return -1; } } @@ -2078,26 +2037,26 @@ int serviceInitSSL(SERVICE* service) /** Load the server sertificate */ if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) { - skygw_log_write(LE,"Error: Failed to set server SSL certificate."); + MXS_ERROR("Failed to set server SSL certificate."); return -1; } /* Load the private-key corresponding to the server certificate */ if (SSL_CTX_use_PrivateKey_file(service->ctx, service->ssl_key, SSL_FILETYPE_PEM) <= 0) { - skygw_log_write(LE,"Error: Failed to set server SSL key."); + MXS_ERROR("Failed to set server SSL key."); return -1; } /* Check if the server certificate and private-key matches */ if (!SSL_CTX_check_private_key(service->ctx)) { - skygw_log_write(LE,"Error: Server SSL certificate and key do not match."); + MXS_ERROR("Server SSL certificate and key do not match."); return -1; } /* Load the RSA CA certificate into the SSL_CTX structure */ if (!SSL_CTX_load_verify_locations(service->ctx, service->ssl_ca_cert, NULL)) { - skygw_log_write(LE,"Error: Failed to set Certificate Authority file."); + MXS_ERROR("Failed to set Certificate Authority file."); return -1; } diff --git a/server/core/session.c b/server/core/session.c index f6cdbf21c..bb76808ed 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -79,12 +79,10 @@ session_alloc(SERVICE *service, DCB *client_dcb) if (session == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to allocate memory for " - "session object due error %d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to allocate memory for " + "session object due error %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); /* Does this possibly need a lock? */ /* * This is really not the right way to do this. The data in a DCB is @@ -149,13 +147,11 @@ session_alloc(SERVICE *service, DCB *client_dcb) { session->state = SESSION_STATE_TO_BE_FREED; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [%s] Error : Failed to create %s session because router" - "could not establish a new router session, see earlier error.", - pthread_self(), - __func__, - service->name))); + MXS_ERROR("%lu [%s] Error : Failed to create %s session because router" + "could not establish a new router session, see earlier error.", + pthread_self(), + __func__, + service->name); } /* @@ -181,11 +177,9 @@ session_alloc(SERVICE *service, DCB *client_dcb) && !session_setup_filters(session)) { session->state = SESSION_STATE_TO_BE_FREED; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Setting up filters failed. " - "Terminating session %s.", - service->name))); + MXS_ERROR("Setting up filters failed. " + "Terminating session %s.", + service->name); } } @@ -195,33 +189,27 @@ session_alloc(SERVICE *service, DCB *client_dcb) if (session->client->user == NULL) { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started session [%lu] for %s service ", - session->ses_id, - service->name))); + MXS_INFO("Started session [%lu] for %s service ", + session->ses_id, + service->name); } else { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Started %s client session [%lu] for '%s' from %s", - service->name, - session->ses_id, - session->client->user, - session->client->remote))); + MXS_INFO("Started %s client session [%lu] for '%s' from %s", + service->name, + session->ses_id, + session->client->user, + session->client->remote); } } else { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Start %s client session [%lu] for '%s' from %s failed, will be " - "closed as soon as all related DCBs have been closed.", - service->name, - session->ses_id, - session->client->user, - session->client->remote))); + MXS_INFO("Start %s client session [%lu] for '%s' from %s failed, will be " + "closed as soon as all related DCBs have been closed.", + service->name, + session->ses_id, + session->client->user, + session->client->remote); } spinlock_acquire(&session_spin); /** Assign a session id and increase, insert session into list */ @@ -480,11 +468,9 @@ session_free(SESSION *session) free(session->filters); } - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Stopped %s client session [%lu]", - session->service->name, - session->ses_id))); + MXS_INFO("Stopped %s client session [%lu]", + session->service->name, + session->ses_id); /** Disable trace and decrease trace logger counter */ session_disable_log(session, LT); @@ -845,33 +831,26 @@ int i; if ((session->filters = calloc(service->n_filters, sizeof(SESSION_FILTER))) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Insufficient memory to allocate session filter " - "tracking.\n"))); - return 0; + MXS_ERROR("Insufficient memory to allocate session filter " + "tracking.\n"); + return 0; } session->n_filters = service->n_filters; for (i = service->n_filters - 1; i >= 0; i--) { if (service->filters[i] == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Service '%s' contians an unresolved filter.\n", - service->name))); - return 0; + MXS_ERROR("Service '%s' contians an unresolved filter.", service->name); + return 0; } if ((head = filterApply(service->filters[i], session, &session->head)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create filter '%s' for " - "service '%s'.\n", - service->filters[i]->name, - service->name))); - return 0; + MXS_ERROR("Failed to create filter '%s' for " + "service '%s'.\n", + service->filters[i]->name, + service->name); + return 0; } session->filters[i].filter = service->filters[i]; session->filters[i].session = head->session; @@ -886,12 +865,10 @@ int i; session->filters[i].session, &session->tail)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Failed to create filter '%s' for service '%s'.\n", - service->filters[i]->name, - service->name))); - return 0; + MXS_ERROR("Failed to create filter '%s' for service '%s'.", + service->filters[i]->name, + service->name); + return 0; } /* diff --git a/server/core/users.c b/server/core/users.c index 051524328..9910fb654 100644 --- a/server/core/users.c +++ b/server/core/users.c @@ -49,13 +49,13 @@ USERS *rval; if ((rval = calloc(1, sizeof(USERS))) == NULL) { - skygw_log_write(LE,"[%s:%d] Error: Memory allocation failed.",__FUNCTION__,__LINE__); + MXS_ERROR("[%s:%d]: Memory allocation failed.", __FUNCTION__, __LINE__); return NULL; } if ((rval->data = hashtable_alloc(USERS_HASHTABLE_DEFAULT_SIZE, simple_str_hash, strcmp)) == NULL) { - skygw_log_write(LE,"[%s:%d] Error: Memory allocation failed.",__FUNCTION__,__LINE__); + MXS_ERROR("[%s:%d]: Memory allocation failed.", __FUNCTION__, __LINE__); free(rval); return NULL; } @@ -75,7 +75,7 @@ users_free(USERS *users) { if(users == NULL) { - skygw_log_write(LE,"[%s:%d] Error: NULL parameter.",__FUNCTION__,__LINE__); + MXS_ERROR("[%s:%d]: NULL parameter.", __FUNCTION__, __LINE__); return; } diff --git a/server/core/utils.c b/server/core/utils.c index 30d346964..0718770c6 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -65,23 +65,19 @@ int setnonblocking(int fd) { if ((fl = fcntl(fd, F_GETFL, 0)) == -1) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Can't GET fcntl for %i, errno = %d, %s.", - fd, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Can't GET fcntl for %i, errno = %d, %s.", + fd, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return 1; } if (fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Can't SET fcntl for %i, errno = %d, %s", - fd, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Can't SET fcntl for %i, errno = %d, %s", + fd, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return 1; } return 0; From a355e1beef815171af805bc6bdd7c873ecafd271 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 16 Nov 2015 11:38:03 +0200 Subject: [PATCH 161/179] Printf format checking added to logging function. Printf format checking added to logging function and all issues that were revealed by that fixed. --- log_manager/log_manager.h | 2 +- log_manager/test/testlog.c | 104 +++++++++--------- log_manager/test/testorder.c | 4 +- query_classifier/query_classifier.cc | 2 +- server/core/config.c | 2 +- server/core/dcb.c | 15 +-- server/core/externcmd.c | 2 +- server/core/load_utils.c | 2 +- server/core/secrets.c | 2 +- server/modules/filter/dbfwfilter.c | 2 +- server/modules/filter/regexfilter.c | 2 +- server/modules/filter/tee.c | 10 +- server/modules/monitor/mysql_mon.c | 2 +- server/modules/protocol/mysql_client.c | 10 +- server/modules/protocol/mysql_common.c | 22 ++-- server/modules/routing/binlog/blr.c | 13 ++- server/modules/routing/binlog/blr_file.c | 26 ++--- server/modules/routing/binlog/blr_master.c | 56 +++++----- server/modules/routing/binlog/blr_slave.c | 8 +- .../modules/routing/binlog/maxbinlogcheck.c | 2 +- server/modules/routing/maxinfo/maxinfo.c | 2 +- server/modules/routing/maxinfo/maxinfo_exec.c | 12 +- .../routing/readwritesplit/readwritesplit.c | 42 ++++--- .../routing/schemarouter/schemarouter.c | 49 ++++++--- .../routing/schemarouter/sharding_common.c | 3 +- .../routing/schemarouter/shardrouter.c | 4 +- 26 files changed, 209 insertions(+), 191 deletions(-) diff --git a/log_manager/log_manager.h b/log_manager/log_manager.h index e5984bb7a..074f63a4b 100644 --- a/log_manager/log_manager.h +++ b/log_manager/log_manager.h @@ -126,7 +126,7 @@ void mxs_log_set_augmentation(int bits); int mxs_log_message(int priority, const char* file, int line, const char* function, - const char* format, ...); + const char* format, ...) __attribute__((format(printf, 5, 6))); inline int mxs_log_id_to_priority(logfile_id_t id) { diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index df44490d1..6983067ea 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -173,16 +173,16 @@ int main(int argc, char* argv[]) mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("First write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); logstr = ("Second write with flush."); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); logstr = ("Third write, no flush."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); logstr = ("Fourth write, no flush. Next flush only."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); err = mxs_log_flush(); @@ -196,7 +196,7 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "My name is Tracey Tracey 47 years and 7 months."; - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -207,12 +207,12 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "My name is Philip"; - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif logstr = "Philip."; - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif @@ -221,26 +221,26 @@ int main(int argc, char* argv[]) mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("A terrible error has occurred!"); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); logstr = ("Hi, how are you?"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); logstr = ("I'm doing fine!"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); logstr = ("Rather more surprising, at least at first sight, is the fact that a reference to " "a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) " "immediately; the two forms are equivalent. Applying the operators & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); logstr = ("I was wondering, you know, it has been such a lovely weather whole morning and I " "thought that would you like to come to my place and have a little piece of cheese " "with us. Just me and my mom - and you, of course. Then, if you wish, we could " "listen to the radio and keep company for our little Steven, my mom's cat, you know."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); mxs_log_finish(); #if defined(TEST1) @@ -366,63 +366,63 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif succp = mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); - ss_dassert(succp); + ss_dassert(succp); logstr = ("\tTEST 3 - test enabling and disabling logs."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_TRACE); logstr = ("1.\tWrite once to ERROR and twice to MESSAGE log."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_TRACE); logstr = ("2.\tWrite to once to ERROR, twice to MESSAGE and " "three times to TRACE log."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_ERROR); logstr = ("3.\tWrite to once to MESSAGE and twice to TRACE log."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); skygw_log_disable(LOGFILE_TRACE); logstr = ("4.\tWrite to none."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_ERROR); skygw_log_enable(LOGFILE_MESSAGE); logstr = ("4.\tWrite once to ERROR and twice to MESSAGE log."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); mxs_log_finish(); @@ -436,32 +436,32 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = ("\tTEST 4 - test spreading logs down to other logs."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); logstr = ("1.\tWrite to ERROR and thus also to MESSAGE and TRACE logs."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); logstr = ("2.\tWrite to MESSAGE and thus to TRACE logs."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_TRACE); logstr = ("3.\tWrite to TRACE log only."); - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); logstr = ("4.\tWrite to ERROR and thus also to TRACE log. " "MESSAGE is disabled."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); logstr = ("5.\tThis should not appear anywhere since MESSAGE " "is disabled."); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); mxs_log_finish(); @@ -472,28 +472,28 @@ int main(int argc, char* argv[]) skygw_log_enable(LOGFILE_TRACE); #endif logstr = ("6.\tWrite to ERROR and thus also to MESSAGE and TRACE logs."); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); logstr = ("7.\tWrite to MESSAGE and thus to TRACE logs."); - err = skygw_log_write_flush(LOGFILE_MESSAGE, logstr); + err = skygw_log_write_flush(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); logstr = ("8.\tWrite to TRACE log only."); skygw_log_enable(LOGFILE_TRACE); - err = skygw_log_write_flush(LOGFILE_TRACE, logstr); + err = skygw_log_write_flush(LOGFILE_TRACE, "%s", logstr); ss_dassert(err == 0); skygw_log_disable(LOGFILE_MESSAGE); logstr = ("9.\tWrite to ERROR and thus also to TRACE log. " "MESSAGE is disabled"); - err = skygw_log_write_flush(LOGFILE_ERROR, logstr); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", logstr); ss_dassert(err == 0); logstr = ("10.\tThis should not appear anywhere since MESSAGE is " "disabled."); - err = skygw_log_write_flush(LOGFILE_MESSAGE, logstr); + err = skygw_log_write_flush(LOGFILE_MESSAGE, "%s", logstr); ss_dassert(err == 0); skygw_log_enable(LOGFILE_MESSAGE); @@ -542,7 +542,7 @@ static void* thr_run(void* data) mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); mxs_log_flush(); logstr = ("Hi, how are you?"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); if (err != 0) { @@ -561,10 +561,10 @@ static void* thr_run(void* data) TEST_ERROR("Error, log write failed."); } ss_dassert(err == 0); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three\n"); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -578,7 +578,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -591,7 +591,7 @@ static void* thr_run(void* data) "immediately; the two forms are equivalent. Applying the operatos & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -603,7 +603,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..and you?"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -615,7 +615,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -627,7 +627,7 @@ static void* thr_run(void* data) "immediately; the two forms are equivalent. Applying the operatos & to both parts " "of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the " "address of the i-th element beyond a."); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -635,7 +635,7 @@ static void* thr_run(void* data) ss_dassert(err == 0); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("..... and you too?"); - err = skygw_log_write(LOGFILE_MESSAGE, logstr); + err = skygw_log_write(LOGFILE_MESSAGE, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -651,7 +651,7 @@ static void* thr_run(void* data) #if !defined(SS_DEBUG) skygw_log_enable(LOGFILE_TRACE); #endif - err = skygw_log_write(LOGFILE_TRACE, logstr); + err = skygw_log_write(LOGFILE_TRACE, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -660,7 +660,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, four\n"); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); @@ -669,7 +669,7 @@ static void* thr_run(void* data) mxs_log_finish(); mxs_log_init(NULL, "/tmp", LOG_TARGET_FS); logstr = ("Testing. One, two, three, .. where was I?\n"); - err = skygw_log_write(LOGFILE_ERROR, logstr); + err = skygw_log_write(LOGFILE_ERROR, "%s", logstr); if (err != 0) { TEST_ERROR("Error, log write failed."); diff --git a/log_manager/test/testorder.c b/log_manager/test/testorder.c index 6514ecf76..4bb23074e 100644 --- a/log_manager/test/testorder.c +++ b/log_manager/test/testorder.c @@ -124,11 +124,11 @@ int main(int argc, char** argv) memset(message + block_size - 1, '\0', 1); if (interval > 0 && i % interval == 0) { - err = skygw_log_write_flush(LOGFILE_ERROR, message); + err = skygw_log_write_flush(LOGFILE_ERROR, "%s", message); } else { - err = skygw_log_write(LOGFILE_ERROR, message); + err = skygw_log_write(LOGFILE_ERROR, "%s", message); } if (err) { diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 25220cb61..25f251570 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -281,7 +281,7 @@ static THD* get_or_create_thd_for_parsing( LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Invalid status %d in embedded server. " - "Exiting."))); + "Exiting.", mysql->status))); goto return_err_with_thd; } /** Clear result variables */ diff --git a/server/core/config.c b/server/core/config.c index fe88b4b26..0596cd6bd 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -153,7 +153,7 @@ char* config_clean_string_list(char* str) PCRE2_UCHAR errbuf[STRERROR_BUFLEN]; pcre2_get_error_message(re_err, errbuf, sizeof(errbuf)); MXS_ERROR("[%s] Regular expression compilation failed at %d: %s", - __FUNCTION__, err_offset, errbuf); + __FUNCTION__, (int)err_offset, errbuf); pcre2_code_free(re); free(dest); return NULL; diff --git a/server/core/dcb.c b/server/core/dcb.c index 20ca54f18..b4a35012a 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1014,7 +1014,7 @@ int dcb_read_SSL(DCB *dcb, if (buffer) { #ifdef SS_DEBUG - MXS_DEBUG("%lu SSL: Truncated buffer from %d to %d bytes. " + MXS_DEBUG("%lu SSL: Truncated buffer from %d to %ld bytes. " "Read %d bytes, %d bytes waiting.\n", pthread_self(), bufsize, GWBUF_LENGTH(buffer), n, b); @@ -1204,10 +1204,8 @@ dcb_write_parameter_check(DCB *dcb, GWBUF *queue) MXS_DEBUG("%lu [dcb_write] Write aborted to dcb %p because " "it is in state %s", pthread_self(), - dcb->stats.n_buffered, dcb, - STRDCBSTATE(dcb->state), - dcb->fd); + STRDCBSTATE(dcb->state)); gwbuf_free(queue); return false; } @@ -1640,12 +1638,7 @@ dcb_drain_writeq_SSL(DCB *dcb) { break; } - MXS_ERROR("Write to dcb failed due to " - "SSL error %d:", - dcb, - STRDCBSTATE(dcb->state), - dcb->fd, - ssl_errno); + MXS_ERROR("Write to dcb failed due to SSL error %d:", ssl_errno); switch(ssl_errno) { case SSL_ERROR_SSL: @@ -1833,7 +1826,7 @@ dcb_maybe_add_persistent(DCB *dcb) else { MXS_DEBUG("%lu [dcb_maybe_add_persistent] Not adding DCB %p to persistent pool, " - "user %s, max for pool %d, error handle called %s, hung flag %s, " + "user %s, max for pool %ld, error handle called %s, hung flag %s, " "server status %d, pool count %d.\n", pthread_self(), dcb, diff --git a/server/core/externcmd.c b/server/core/externcmd.c index f3bfb4ec7..db12d001d 100644 --- a/server/core/externcmd.c +++ b/server/core/externcmd.c @@ -166,7 +166,7 @@ int externcmd_execute(EXTERNCMD* cmd) { cmd->child = pid; cmd->n_exec++; - MXS_DEBUG("[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd); + MXS_DEBUG("[monitor_exec_cmd] Forked child process %d : %s.", pid, cmd->argv[0]); } return rval; diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 260c691f9..3f0259776 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -808,7 +808,7 @@ do_http_post(GWBUF *buffer, void *cfg) { goto cleanup; } - MXS_INFO("do_http_post() ret_code [%d], HTTP code [%d]", + MXS_INFO("do_http_post() ret_code [%d], HTTP code [%ld]", ret_code, http_code); cleanup: diff --git a/server/core/secrets.c b/server/core/secrets.c index 83f0f9edf..3f4ff586c 100644 --- a/server/core/secrets.c +++ b/server/core/secrets.c @@ -177,7 +177,7 @@ secrets_readKeys(const char* path) "%s failed. Read %d, expected %d bytes. Error %d, %s.", secret_file, len, - sizeof(MAXKEYS), + (int)sizeof(MAXKEYS), eno, strerror_r(eno, errbuf, sizeof(errbuf))); return NULL; diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 37dc5419f..1460759b2 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -1394,7 +1394,7 @@ createInstance(char **options, FILTER_PARAMETER **params) if(file_empty) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: File is empty: %s"); + skygw_log_write(LOGFILE_ERROR,"dbfwfilter: File is empty: %s", filename); free(filename); err = true; goto retblock; diff --git a/server/modules/filter/regexfilter.c b/server/modules/filter/regexfilter.c index 732675336..519b24820 100644 --- a/server/modules/filter/regexfilter.c +++ b/server/modules/filter/regexfilter.c @@ -270,7 +270,7 @@ createInstance(char **options, FILTER_PARAMETER **params) char errbuffer[1024]; pcre2_get_error_message(errnumber, (PCRE2_UCHAR*) & errbuffer, sizeof(errbuffer)); LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: regexfilter: Compiling regular expression '%s' failed at %d: %s\n", + "Error: regexfilter: Compiling regular expression '%s' failed at %lu: %s\n", my_instance->match, erroffset, errbuffer))); free_instance(my_instance); return NULL; diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 4a9193ad1..2f68b22bd 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -986,7 +986,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) #ifdef SS_DEBUG else { - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c: [%d] Waiting for a result set from %s session.", + skygw_log_write_flush(LOGFILE_DEBUG,"tee.c: [%ld] Waiting for a result set from %s session.", my_session->d_id, branch == PARENT?"parent":"child"); } @@ -1002,7 +1002,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(my_session->eof[branch] >= min_eof) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c [%d] %s received last EOF packet", + skygw_log_write_flush(LOGFILE_DEBUG,"tee.c [%ld] %s received last EOF packet", my_session->d_id, branch == PARENT?"parent":"child"); #endif @@ -1051,7 +1051,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) { route = true; #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%d] Routing final packet of response set.",my_session->d_id); + skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%ld] Routing final packet of response set.",my_session->d_id); #endif } } @@ -1059,7 +1059,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) !my_session->waiting[CHILD]) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%d] Routing single packet response.",my_session->d_id); + skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%ld] Routing single packet response.",my_session->d_id); #endif route = true; } @@ -1068,7 +1068,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(route) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG, "tee.c:[%d] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" + skygw_log_write_flush(LOGFILE_DEBUG, "tee.c:[%ld] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" " child(waiting [%s] replies[%d] eof [%d])", my_session->d_id, my_session->tee_replybuf, diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 2b934667f..7fb50ecec 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -509,7 +509,7 @@ static MONITOR_SERVERS *build_mysql51_replication_tree(MONITOR *mon) /* get Slave_IO_Running and Slave_SQL_Running values*/ database->server->slaves[nslaves] = atol(row[0]); nslaves++; - LOGIF(LD,(skygw_log_write_flush(LD,"Found slave at %s:%d",row[1],row[2]))); + LOGIF(LD,(skygw_log_write_flush(LD,"Found slave at %s:%s",row[1],row[2]))); } database->server->slaves[nslaves] = 0; } diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 113a10e0f..60e66322c 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -932,8 +932,8 @@ int gw_read_client_event( "%lu [gw_read_client_event] after " "gw_mysql_do_authentication, fd %d, " "state = MYSQL_AUTH_FAILED.", - protocol->owner_dcb->fd, - pthread_self()))); + pthread_self(), + protocol->owner_dcb->fd))); /** * Release MYSQL_session since it is not used anymore. */ @@ -1029,11 +1029,11 @@ int gw_read_client_event( LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, - "%lu [gw_read_client_event] after " + "%lu [gw_read_client_event] after " "gw_mysql_do_authentication, fd %d, " "state = MYSQL_AUTH_FAILED.", - protocol->owner_dcb->fd, - pthread_self()))); + pthread_self(), + protocol->owner_dcb->fd))); /** * Release MYSQL_session since it is not used anymore. */ diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 0c6c45179..519191a4b 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -192,8 +192,8 @@ int gw_read_backend_handshake( "%lu [gw_read_backend_handshake] after " "dcb_read, fd %d, " "state = MYSQL_HANDSHAKE_FAILED.", - dcb->fd, - pthread_self()))); + pthread_self(), + dcb->fd))); return 1; } @@ -210,7 +210,7 @@ int gw_read_backend_handshake( LOGFILE_DEBUG, "%lu [gw_receive_backend_auth] Invalid " "authentication message from backend dcb %p " - "fd %d, ptr[4] = %p, error code %d, msg %s.", + "fd %d, ptr[4] = %d, error code %d, msg %s.", pthread_self(), dcb, dcb->fd, @@ -261,8 +261,7 @@ int gw_read_backend_handshake( "gw_mysql_get_byte3, fd %d, " "state = MYSQL_HANDSHAKE_FAILED.", pthread_self(), - dcb->fd, - pthread_self()))); + dcb->fd))); return 1; } @@ -286,8 +285,7 @@ int gw_read_backend_handshake( "gw_decode_mysql_server_handshake, fd %d, " "state = MYSQL_HANDSHAKE_FAILED.", pthread_self(), - conn->owner_dcb->fd, - pthread_self()))); + conn->owner_dcb->fd))); while((head = gwbuf_consume(head, GWBUF_LENGTH(head)))); return 1; } @@ -451,7 +449,7 @@ int gw_receive_backend_auth( LOGFILE_DEBUG, "%lu [gw_receive_backend_auth] Invalid " "authentication message from backend dcb %p " - "fd %d, ptr[4] = %p, error %s, msg %s.", + "fd %d, ptr[4] = %d, error %s, msg %s.", pthread_self(), dcb, dcb->fd, @@ -476,7 +474,7 @@ int gw_receive_backend_auth( LOGFILE_DEBUG, "%lu [gw_receive_backend_auth] Invalid " "authentication message from backend dcb %p " - "fd %d, ptr[4] = %p", + "fd %d, ptr[4] = %d", pthread_self(), dcb, dcb->fd, @@ -485,7 +483,7 @@ int gw_receive_backend_auth( LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Error : Invalid authentication message " - "from backend. Packet type : %p", + "from backend. Packet type : %d", ptr[4]))); } /*< @@ -503,7 +501,7 @@ int gw_receive_backend_auth( LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, "%lu [gw_receive_backend_auth] Read zero bytes from " - "backend dcb %p fd %d in state %s. n %d, head %p, len %d", + "backend dcb %p fd %d in state %s. n %d, head %p, len %ld", pthread_self(), dcb, dcb->fd, @@ -519,7 +517,7 @@ int gw_receive_backend_auth( LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, "%lu [gw_receive_backend_auth] Reading from backend dcb %p " - "fd %d in state %s failed. n %d, head %p, len %d", + "fd %d in state %s failed. n %d, head %p, len %ld", pthread_self(), dcb, dcb->fd, diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 5411b7dec..475d4e4eb 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -469,8 +469,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, "Warning : invalid heartbeat period %s." - " Setting it to default value %d.", - value, inst->heartbeat ))); + " Setting it to default value %ld.", + value, inst->heartbeat))); } else { inst->heartbeat = h_val; } @@ -529,8 +529,9 @@ char task_name[BLRM_TASK_NAME_LEN+1] = ""; if (inst->serverid <= 0) { skygw_log_write_flush(LOGFILE_ERROR, - "Error : Service %s, server-id is not configured. Please configure it with a unique positive integer value (1..2^32-1)", - service->name, inst->serverid); + "Error : Service %s, server-id is not configured. " + "Please configure it with a unique positive integer value (1..2^32-1)", + service->name); free(inst); return NULL; } @@ -888,7 +889,7 @@ ROUTER_SLAVE *slave = (ROUTER_SLAVE *)router_session; LOGIF(LM, (skygw_log_write_flush( LOGFILE_MESSAGE, "%s: Master %s disconnected after %ld seconds. " - "%d events read,", + "%lu events read,", router->service->name, router->service->dbref->server->name, time(0) - router->connect_time, router->stats.n_binlogs_ses))); LOGIF(LE, (skygw_log_write_flush( @@ -1463,7 +1464,7 @@ unsigned long mysql_errno; LOGIF(LM, (skygw_log_write_flush( LOGFILE_MESSAGE, "%s: Master %s disconnected after %ld seconds. " - "%d events read.", + "%lu events read.", router->service->name, router->service->dbref->server->name, time(0) - router->connect_time, router->stats.n_binlogs_ses))); blr_master_reconnect(router); diff --git a/server/modules/routing/binlog/blr_file.c b/server/modules/routing/binlog/blr_file.c index 61e061004..dc1683b9c 100644 --- a/server/modules/routing/binlog/blr_file.c +++ b/server/modules/routing/binlog/blr_file.c @@ -281,7 +281,7 @@ int fd; /* If for any reason the file's length is between 1 and 3 bytes * then report an error. */ LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "%s: binlog file %s has an invalid length %d.", + "%s: binlog file %s has an invalid length %lu.", router->service->name, path, router->current_pos))); close(fd); spinlock_release(&router->binlog_lock); @@ -459,7 +459,7 @@ struct stat statb; { case 0: LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reached end of binlog file '%s' at %d.", + "Reached end of binlog file '%s' at %lu.", file->binlogname, pos))); /* set ok indicator */ @@ -527,7 +527,7 @@ struct stat statb; { case 0: LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reached end of binlog file at %d.", + "Reached end of binlog file at %lu.", pos))); /* set ok indicator */ @@ -904,8 +904,8 @@ int fde_seen = 0; LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, "Transaction Summary for binlog '%s'\n" "\t\t\tDescription %17s%17s%17s\n\t\t\t" - "No. of Transactions %16llu\n\t\t\t" - "No. of Events %16llu %16.1f %16llu\n\t\t\t" + "No. of Transactions %16lu\n\t\t\t" + "No. of Events %16lu %16.1f %16lu\n\t\t\t" "No. of Bytes %16.1f%s%16.1f%s%16.1f%s", router->binlog_name, "Total", "Average", "Max", n_transactions, total_events, @@ -1012,7 +1012,7 @@ int fde_seen = 0; if (hdr.event_type > MAX_EVENT_TYPE_MARIADB10) { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Invalid MariaDB 10 event type 0x%x. " - "Binlog file is %s, position %d", + "Binlog file is %s, position %llu", hdr.event_type, router->binlog_name, pos))); @@ -1022,7 +1022,7 @@ int fde_seen = 0; if (hdr.event_type > MAX_EVENT_TYPE) { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Invalid event type 0x%x. " - "Binlog file is %s, position %d", + "Binlog file is %s, position %llu", hdr.event_type, router->binlog_name, pos))); @@ -1284,7 +1284,7 @@ int fde_seen = 0; if(debug) LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "- Rotate event @ %llu, next file is [%s] @ %llu", + "- Rotate event @ %llu, next file is [%s] @ %lu", pos, file, new_pos))); } @@ -1307,7 +1307,7 @@ int fde_seen = 0; if (pending_transaction > 0) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, "ERROR: Transaction cannot be @ pos %llu: " - "Another MariaDB 10 transaction (GTID %lu-%lu-%llu)" + "Another MariaDB 10 transaction (GTID %u-%u-%lu)" " was opened at %llu", pos, domainid, hdr.serverid, n_sequence, last_known_commit))); @@ -1322,7 +1322,7 @@ int fde_seen = 0; if (debug) LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, - "> MariaDB 10 Transaction (GTID %lu-%lu-%llu)" + "> MariaDB 10 Transaction (GTID %u-%u-%lu)" " starts @ pos %llu", domainid, hdr.serverid, n_sequence, pos))); } @@ -1416,7 +1416,7 @@ int fde_seen = 0; /* pos and next_pos sanity checks */ if (hdr.next_pos > 0 && hdr.next_pos < pos) { LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Binlog %s: next pos %llu < pos %llu, truncating to %llu", + "Binlog %s: next pos %u < pos %llu, truncating to %llu", router->binlog_name, hdr.next_pos, pos, @@ -1445,7 +1445,7 @@ int fde_seen = 0; if (hdr.next_pos > 0 && hdr.next_pos != (pos + hdr.event_size)) { LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, - "Binlog %s: next pos %llu != (pos %llu + event_size %llu), truncating to %llu", + "Binlog %s: next pos %u != (pos %llu + event_size %u), truncating to %llu", router->binlog_name, hdr.next_pos, pos, @@ -1489,7 +1489,7 @@ int fde_seen = 0; } else { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Current event type %lu @ %llu has nex pos = %llu : exiting", hdr.event_type, pos, hdr.next_pos))); + "Current event type %d @ %llu has nex pos = %u : exiting", hdr.event_type, pos, hdr.next_pos))); break; } diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 5e8fd7ee1..7126b6a20 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -397,7 +397,7 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = ""; LOGIF(LE, (skygw_log_write( LOGFILE_ERROR, - "%s: Received error: %u, '%s' from master during '%s' phase " + "%s: Received error: %lu, '%s' from master during '%s' phase " "of the master state machine.", router->service->name, mysql_errno, msg_err, @@ -868,11 +868,11 @@ int n_bufs = -1, pn_bufs = -1; if ((msg = malloc(len)) == NULL) { LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, - "Insufficient memory to buffer event " - "of %d bytes. Binlog %s @ %d.", - len, router->binlog_name, - router->current_pos))); + LOGFILE_ERROR, + "Insufficient memory to buffer event " + "of %d bytes. Binlog %s @ %lu.", + len, router->binlog_name, + router->current_pos))); break; } @@ -892,10 +892,10 @@ int n_bufs = -1, pn_bufs = -1; if (remainder) { LOGIF(LE,(skygw_log_write( - LOGFILE_ERROR, + LOGFILE_ERROR, "Expected entire message in buffer " "chain, but failed to create complete " - "message as expected. %s @ %d", + "message as expected. %s @ %lu", router->binlog_name, router->current_pos))); free(msg); @@ -916,7 +916,7 @@ int n_bufs = -1, pn_bufs = -1; router->stats.n_residuals++; LOGIF(LD,(skygw_log_write( LOGFILE_DEBUG, - "Residual data left after %d records. %s @ %d", + "Residual data left after %lu records. %s @ %lu", router->stats.n_binlogs, router->binlog_name, router->current_pos))); break; @@ -967,7 +967,7 @@ int n_bufs = -1, pn_bufs = -1; LOGIF(LE,(skygw_log_write( LOGFILE_ERROR, "Packet length is %d, but event size is %d, " - "binlog file %s position %d " + "binlog file %s position %lu " "reslen is %d and preslen is %d, " "length of previous event %d. %s", len, hdr.event_size, @@ -1033,7 +1033,7 @@ int n_bufs = -1, pn_bufs = -1; LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, "%s: Checksum error in event " "from master, " - "binlog %s @ %d. " + "binlog %s @ %lu. " "Closing master connection.", router->service->name, router->binlog_name, @@ -1091,7 +1091,7 @@ int n_bufs = -1, pn_bufs = -1; LOGIF(LE,(skygw_log_write_flush(LOGFILE_ERROR, "Error: a MariaDB 10 transaction " "is already open " - "@ %lu (GTID %lu-%lu-%llu) and " + "@ %lu (GTID %u-%u-%lu) and " "a new one starts @ %lu", router->binlog_position, domainid, hdr.serverid, n_sequence, @@ -1177,7 +1177,7 @@ int n_bufs = -1, pn_bufs = -1; // Fake format description message LOGIF(LD,(skygw_log_write(LOGFILE_DEBUG, "Replication fake event. " - "Binlog %s @ %d.", + "Binlog %s @ %lu.", router->binlog_name, router->current_pos))); router->stats.n_fakeevents++; @@ -1223,7 +1223,7 @@ int n_bufs = -1, pn_bufs = -1; LOGIF(LD,(skygw_log_write( LOGFILE_DEBUG, "Replication heartbeat. " - "Binlog %s @ %d.", + "Binlog %s @ %lu.", router->binlog_name, router->current_pos))); @@ -1359,7 +1359,7 @@ int n_bufs = -1, pn_bufs = -1; /* Some events have been sent */ LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, "Some events were not distributed to slaves for a pending transaction " - "in %s at %lu. Last distributed even at %lu, last event from master at %lu", + "in %s at %lu. Last distributed even at %llu, last event from master at %lu", router->binlog_name, router->binlog_position, pos, @@ -1391,7 +1391,7 @@ int n_bufs = -1, pn_bufs = -1; "Artificial event not written " "to disk or distributed. " "Type 0x%x, Length %d, Binlog " - "%s @ %d.", + "%s @ %lu.", hdr.event_type, hdr.event_size, router->binlog_name, @@ -1446,7 +1446,7 @@ int n_bufs = -1, pn_bufs = -1; spinlock_release(&router->lock); LOGIF(LE,(skygw_log_write(LOGFILE_ERROR, - "Error packet in binlog stream.%s @ %d.", + "Error packet in binlog stream.%s @ %lu.", router->binlog_name, router->current_pos))); @@ -1691,7 +1691,7 @@ int action; * try to resolve the issue. */ LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Slave %d is ahead of expected position %s@%d. " + "Slave %d is ahead of expected position %s@%lu. " "Expected position %d", slave->serverid, slave->binlogfile, (unsigned long)slave->binlog_pos, @@ -1925,7 +1925,7 @@ int event_limit; if (pos > end_pos) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Reading saved events, the specified pos %lu " + "Error: Reading saved events, the specified pos %llu " "is ahead of current pos %lu for file %s", pos, router->current_pos, router->binlog_name))); return NULL; @@ -1938,14 +1938,14 @@ int event_limit; { case 0: LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "Reading saved events: reached end of binlog file at %d.", pos))); + "Reading saved events: reached end of binlog file at %llu.", pos))); break; case -1: { char err_msg[STRERROR_BUFLEN]; LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: failed to read binlog " - "file %s at position %d" + "file %s at position %llu" " (%s).", router->binlog_name, pos, strerror_r(errno, err_msg, sizeof(err_msg))))); @@ -1960,7 +1960,7 @@ int event_limit; LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: short read when reading the header. " "Expected 19 bytes but got %d bytes. " - "Binlog file is %s, position %d", + "Binlog file is %s, position %llu", n, router->binlog_name, pos))); break; } @@ -1981,7 +1981,7 @@ int event_limit; { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: invalid event type 0x%x. " - "Binlog file is %s, position %d", + "Binlog file is %s, position %llu", hdr->event_type, router->binlog_name, pos))); return NULL; @@ -1991,7 +1991,7 @@ int event_limit; { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: failed to allocate memory for binlog entry, " - "size %d at %d.", + "size %d at %llu.", hdr->event_size, pos))); return NULL; } @@ -2007,14 +2007,14 @@ int event_limit; { char err_msg[STRERROR_BUFLEN]; LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, - "Error: Reading saved events: the event at %ld in %s. " + "Error: Reading saved events: the event at %llu in %s. " "%s, expected %d bytes.", pos, router->binlog_name, strerror_r(errno, err_msg, sizeof(err_msg)), hdr->event_size - 19))); } else { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: short read when reading " - "the event at %ld in %s. " + "the event at %llu in %s. " "Expected %d bytes got %d bytes.", pos, router->binlog_name, hdr->event_size - 19, n))); @@ -2023,7 +2023,7 @@ int event_limit; LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Error: Reading saved events: binlog event " "is close to the end of the binlog file, " - "current file size is %u.", end_pos))); + "current file size is %llu.", end_pos))); } } @@ -2155,7 +2155,7 @@ char *event_desc = NULL; if (router->master_state == BLRM_BINLOGDUMP && router->lastEventReceived > 0) { if ((t_now - router->stats.lastReply) > (router->heartbeat + BLR_NET_LATENCY_WAIT_TIME)) { LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "ERROR: No event received from master %s:%d in heartbeat period (%d seconds), last event (%s %d) received %lu seconds ago. Assuming connection is dead and reconnecting.", + "ERROR: No event received from master %s:%d in heartbeat period (%lu seconds), last event (%s %d) received %lu seconds ago. Assuming connection is dead and reconnecting.", router->service->dbref->server->name, router->service->dbref->server->port, router->heartbeat, diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index 7ed44eb78..0adbaef02 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -1988,7 +1988,7 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; blr_close_binlog(router, slave->file); if (hkheartbeat - beat1 > 1) LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "blr_close_binlog took %d maxscale beats", + LOGFILE_ERROR, "blr_close_binlog took %lu maxscale beats", hkheartbeat - beat1))); blr_slave_rotate(router, slave, GWBUF_DATA(record)); beat1 = hkheartbeat; @@ -2025,7 +2025,7 @@ char read_errmsg[BINLOG_ERROR_MSG_LEN+1]; } if (hkheartbeat - beat1 > 1) LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, "blr_open_binlog took %d beats", + LOGFILE_ERROR, "blr_open_binlog took %lu beats", hkheartbeat - beat1))); } slave->stats.n_bytes += gwbuf_length(head); @@ -2947,7 +2947,7 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) LOGFILE_ERROR, "Warning: a transaction is still opened at pos %lu" " File %s will be truncated. " - "Next binlog file is %s at pos %lu, " + "Next binlog file is %s at pos %d, " "START SLAVE is required again.", router->last_safe_pos, router->prevbinlog, @@ -3334,7 +3334,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router, char *command, char *error router->binlog_name))); } - LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_POS is [%u]", + LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, "%s: New MASTER_LOG_POS is [%lu]", router->service->name, router->current_pos))); } diff --git a/server/modules/routing/binlog/maxbinlogcheck.c b/server/modules/routing/binlog/maxbinlogcheck.c index 3116bc845..6706c0b65 100644 --- a/server/modules/routing/binlog/maxbinlogcheck.c +++ b/server/modules/routing/binlog/maxbinlogcheck.c @@ -192,7 +192,7 @@ int main(int argc, char **argv) { mxs_log_flush_sync(); LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, - "Check retcode: %i, Binlog Pos = %llu", ret, inst->binlog_position))); + "Check retcode: %i, Binlog Pos = %lu", ret, inst->binlog_position))); mxs_log_flush_sync(); mxs_log_finish(); diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index edb13e94b..bea41c218 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -620,7 +620,7 @@ MAXINFO_TREE *tree; PARSE_ERROR err; LOGIF(LT, (skygw_log_write(LOGFILE_TRACE, - "maxinfo: SQL statement: '%s' for 0x%x.", + "maxinfo: SQL statement: '%s' for 0x%p.", sql, session->dcb))); if (strcmp(sql, "select @@version_comment limit 1") == 0) { diff --git a/server/modules/routing/maxinfo/maxinfo_exec.c b/server/modules/routing/maxinfo/maxinfo_exec.c index b3c59c1dd..8672c29e6 100644 --- a/server/modules/routing/maxinfo/maxinfo_exec.c +++ b/server/modules/routing/maxinfo/maxinfo_exec.c @@ -293,7 +293,7 @@ char errmsg[120]; tree->value[80] = 0; sprintf(errmsg, "Unsupported show command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, errmsg))); + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "%s", errmsg))); } /** @@ -345,7 +345,7 @@ exec_flush(DCB *dcb, MAXINFO_TREE *tree) } sprintf(errmsg, "Unsupported flush command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - skygw_log_write(LE, errmsg); + skygw_log_write(LE, "%s", errmsg); } /** @@ -425,7 +425,7 @@ exec_set(DCB *dcb, MAXINFO_TREE *tree) } sprintf(errmsg, "Unsupported set command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - skygw_log_write(LE, errmsg); + skygw_log_write(LE, "%s", errmsg); } /** @@ -505,7 +505,7 @@ exec_clear(DCB *dcb, MAXINFO_TREE *tree) } sprintf(errmsg, "Unsupported clear command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - skygw_log_write(LE, errmsg); + skygw_log_write(LE, "%s", errmsg); } extern void shutdown_server(); @@ -627,7 +627,7 @@ exec_shutdown(DCB *dcb, MAXINFO_TREE *tree) } sprintf(errmsg, "Unsupported shutdown command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - skygw_log_write(LE, errmsg); + skygw_log_write(LE, "%s", errmsg); } /** @@ -735,7 +735,7 @@ exec_restart(DCB *dcb, MAXINFO_TREE *tree) } sprintf(errmsg, "Unsupported restart command '%s'", tree->value); maxinfo_send_error(dcb, 0, errmsg); - skygw_log_write(LE, errmsg); + skygw_log_write(LE, "%s", errmsg); } /** diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 086dc4514..9d44a095b 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3024,10 +3024,21 @@ static void clientReply ( } else { + char* sql = modutil_get_SQL(bref->bref_pending_cmd); + + if (sql) + { LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing query \"%s\" failed.", - bref->bref_pending_cmd))); + LOGFILE_ERROR, + "Routing query \"%s\" failed.", sql))); + free(sql); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Failed to route query."))); + } } gwbuf_free(bref->bref_pending_cmd); bref->bref_pending_cmd = NULL; @@ -3123,9 +3134,9 @@ static void bref_clear_state( if(prev2 <= 0) { skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -3154,10 +3165,11 @@ static void bref_set_state( ss_dassert(prev1 >= 0); if(prev1 < 0) { - skygw_log_write(LE,"[%s] Error: negative number of connections waiting for results in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + skygw_log_write(LE,"[%s] Error: negative number of connections waiting for " + "results in backend %s:%u", + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } /** Increase global operation count */ prev2 = atomic_add( @@ -3166,9 +3178,9 @@ static void bref_set_state( if(prev2 < 0) { skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -4410,7 +4422,7 @@ static void tracelog_routed_query( "%lu [%s] %d bytes long buf, \"%s\" -> %s:%d %s dcb %p", pthread_self(), funcname, - buflen, + (int)buflen, querystr, b->backend_server->name, b->backend_server->port, @@ -4432,7 +4444,7 @@ static void tracelog_routed_query( "%lu [%s] %d bytes long buf, \"%s\" -> %s:%d %s dcb %p", pthread_self(), funcname, - buflen, + (int)buflen, querystr, b->backend_server->name, b->backend_server->port, diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 8dc7ec873..6473f49c2 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -420,7 +420,8 @@ showdb_response_t parse_showdb_response(ROUTER_CLIENT_SES* rses, backend_ref_t* { duplicate_found = true; skygw_log_write(LE, "Error: Database '%s' found on servers '%s' and '%s' for user %s@%s.", - data, target, hashtable_fetch(rses->shardmap->hash, data), + data, target, + (char*)hashtable_fetch(rses->shardmap->hash, data), rses->rses_client_dcb->user, rses->rses_client_dcb->remote); } @@ -854,7 +855,7 @@ createInstance(SERVICE *service, char **options) PCRE2_UCHAR errbuf[512]; pcre2_get_error_message(errcode, errbuf, sizeof(errbuf)); skygw_log_write(LE, "Error: Regex compilation failed at %d for regex '%s': %s", - erroffset, param->value, errbuf); + (int)erroffset, param->value, errbuf); hashtable_free(router->ignored_dbs); free(router); return NULL; @@ -2865,10 +2866,21 @@ static void clientReply(ROUTER* instance, } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing query \"%s\" failed.", - bref->bref_pending_cmd))); + char* sql = modutil_get_SQL(bref->bref_pending_cmd); + + if (sql) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Routing query \"%s\" failed.", sql))); + free(sql); + } + else + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Routing query failed."))); + } } gwbuf_free(bref->bref_pending_cmd); bref->bref_pending_cmd = NULL; @@ -2963,9 +2975,9 @@ static void bref_clear_state( if(prev2 <= 0) { skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -2994,10 +3006,11 @@ static void bref_set_state( ss_dassert(prev1 >= 0); if(prev1 < 0) { - skygw_log_write(LE,"[%s] Error: negative number of connections waiting for results in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + skygw_log_write(LE,"[%s] Error: negative number of connections waiting " + "for results in backend %s:%u", + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } /** Increase global operation count */ prev2 = atomic_add( @@ -3006,9 +3019,9 @@ static void bref_set_state( if(prev2 < 0) { skygw_log_write(LE,"[%s] Error: negative current operation count in backend %s:%u", - __FUNCTION__, - &bref->bref_backend->backend_server->name, - &bref->bref_backend->backend_server->port); + __FUNCTION__, + bref->bref_backend->backend_server->name, + bref->bref_backend->backend_server->port); } } } @@ -3785,7 +3798,7 @@ static void tracelog_routed_query( "%lu [%s] %d bytes long buf, \"%s\" -> %s:%d %s dcb %p", pthread_self(), funcname, - buflen, + (int)buflen, querystr, b->backend_server->name, b->backend_server->port, @@ -3807,7 +3820,7 @@ static void tracelog_routed_query( "%lu [%s] %d bytes long buf, \"%s\" -> %s:%d %s dcb %p", pthread_self(), funcname, - buflen, + (int)buflen, querystr, b->backend_server->name, b->backend_server->port, diff --git a/server/modules/routing/schemarouter/sharding_common.c b/server/modules/routing/schemarouter/sharding_common.c index 201b7ec44..e68d35a2c 100644 --- a/server/modules/routing/schemarouter/sharding_common.c +++ b/server/modules/routing/schemarouter/sharding_common.c @@ -146,7 +146,8 @@ bool change_current_db(char* dest, skygw_log_write_flush(LOGFILE_ERROR, "change_current_db: failed to change database: Query buffer too large"); skygw_log_write_flush(LOGFILE_TRACE, - "change_current_db: failed to change database: Query buffer too large [%d bytes]",GWBUF_LENGTH(buf)); + "change_current_db: failed to change database: " + "Query buffer too large [%ld bytes]", GWBUF_LENGTH(buf)); succp = false; goto retblock; } diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 8e7dd479f..c0279395b 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -968,8 +968,8 @@ createInstance(SERVICE *service, char **options) { skygw_log_write(LOGFILE_ERROR, "Error : Memory reallocation failed."); LOGIF(LD,(skygw_log_write(LOGFILE_DEBUG, "shardrouter.c: realloc returned NULL. " - "service count[%d] buffer size [%u] tried to allocate [%u]", - sz, sizeof(SERVICE*)*(sz), sizeof(SERVICE*)*(sz * 2)))); + "service count[%d] buffer size [%lu] tried to allocate [%lu]", + sz, sizeof(SERVICE*) * (sz), sizeof(SERVICE*) * (sz * 2)))); free(res_svc); free(router); return NULL; From ab6dae897dde09e895e1f913a395c2e8b2ad1b23 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 13:01:09 +0200 Subject: [PATCH 162/179] Removed unnecessary locking when modifying server status Server lock was used when the server status was modified even though only one thread should ever be modifying the server status. --- server/core/server.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/core/server.c b/server/core/server.c index 41080e251..8623eaa2e 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -665,7 +665,6 @@ char *status = NULL; void server_set_status(SERVER *server, int bit) { - spinlock_acquire(&server->lock); server->status |= bit; /** clear error logged flag before the next failure */ @@ -673,7 +672,6 @@ server_set_status(SERVER *server, int bit) { server->master_err_is_logged = false; } - spinlock_release(&server->lock); } /** @@ -685,9 +683,7 @@ server_set_status(SERVER *server, int bit) void server_clear_status(SERVER *server, int bit) { - spinlock_acquire(&server->lock); server->status &= ~bit; - spinlock_release(&server->lock); } /** From 40dc49c8873241edc5da633c15c6880079d9877c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 10:38:55 +0200 Subject: [PATCH 163/179] Filters are now loaded and created at startup Previously filter instances were created when the first session was made. This caused filter configuration errors to be noticed only after MaxScale was successfully started. Now filters are loaded and the instance is created when a service applies its filters. --- server/core/filter.c | 57 +++++++++++++++++++++++++---------------- server/core/service.c | 11 ++++++-- server/include/filter.h | 1 + 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/server/core/filter.c b/server/core/filter.c index aef124331..837e204c9 100644 --- a/server/core/filter.c +++ b/server/core/filter.c @@ -304,6 +304,40 @@ int i; spinlock_release(&filter->spin); } +/** + * Load a filter module for use and create an instance of it for a service. + * @param filter Filter definition + * @return True if module was successfully loaded, false if an error occurred + */ +bool filter_load(FILTER_DEF* filter) +{ + bool rval = false; + if (filter) + { + if (filter->obj == NULL) + { + /* Filter not yet loaded */ + if ((filter->obj = load_module(filter->module, MODULE_FILTER)) == NULL) + { + MXS_ERROR("Failed to load filter module '%s'.", filter->module); + return false; + } + } + + if ((filter->filter = (filter->obj->createInstance)(filter->options, + filter->parameters))) + { + rval = true; + } + else + { + MXS_ERROR("Failed to create filter '%s' instance.", filter->name); + } + + } + return rval; +} + /** * Connect the downstream filter chain for a filter. * @@ -319,29 +353,8 @@ int i; DOWNSTREAM * filterApply(FILTER_DEF *filter, SESSION *session, DOWNSTREAM *downstream) { -DOWNSTREAM *me; + DOWNSTREAM *me; - if (filter == NULL) - return NULL; - - if (filter->obj == NULL) - { - /* Filter not yet loaded */ - if ((filter->obj = load_module(filter->module, - MODULE_FILTER)) == NULL) - { - return NULL; - } - } - - if (filter->filter == NULL) - { - if ((filter->filter = (filter->obj->createInstance)(filter->options, - filter->parameters)) == NULL) - { - return NULL; - } - } if ((me = (DOWNSTREAM *)calloc(1, sizeof(DOWNSTREAM))) == NULL) { char errbuf[STRERROR_BUFLEN]; diff --git a/server/core/service.c b/server/core/service.c index e22484c99..4f2453a90 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -1092,12 +1092,19 @@ int n = 0; MXS_ERROR("Out of memory adding filters to service."); return; } - if ((flist[n-1] = filter_find(trim(ptr))) == NULL) + char *filter_name = trim(ptr); + if ((flist[n-1] = filter_find(filter_name)) == NULL) { MXS_WARNING("Unable to find filter '%s' for service '%s'\n", - trim(ptr), service->name); + filter_name, service->name); n--; } + else if (!filter_load(flist[n - 1])) + { + MXS_ERROR("Failed to load filter '%s' for service '%s'.", + filter_name, service->name); + } + flist[n] = NULL; ptr = strtok_r(NULL, "|", &brkt); } diff --git a/server/include/filter.h b/server/include/filter.h index ad0b9a21a..853e1628c 100644 --- a/server/include/filter.h +++ b/server/include/filter.h @@ -107,6 +107,7 @@ typedef struct filter_def { FILTER_DEF *filter_alloc(char *, char *); void filter_free(FILTER_DEF *); +bool filter_load(FILTER_DEF* filter); FILTER_DEF *filter_find(char *); void filterAddOption(FILTER_DEF *, char *); void filterAddParameter(FILTER_DEF *, char *, char *); From 1bd16db593e4767831ca5b13859e208e45532cb4 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 16 Nov 2015 12:54:10 +0200 Subject: [PATCH 164/179] query_classifier: LOGIF and skygw_log_write replaced. The use of LOgIF and skygw_log_write replaced with the equivalent MXS_[ERROR|WARNING|NOTICE|INFO|DEBUG] macros. --- query_classifier/query_classifier.cc | 154 ++++++++++----------------- 1 file changed, 57 insertions(+), 97 deletions(-) diff --git a/query_classifier/query_classifier.cc b/query_classifier/query_classifier.cc index 25f251570..8cefd370d 100644 --- a/query_classifier/query_classifier.cc +++ b/query_classifier/query_classifier.cc @@ -256,32 +256,24 @@ static THD* get_or_create_thd_for_parsing( thd = (THD *)create_embedded_thd(client_flags); if (thd == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create thread context for parsing. " - "Exiting."))); - goto return_thd; + MXS_ERROR("Failed to create thread context for parsing."); + goto return_thd; } mysql->thd = thd; init_embedded_mysql(mysql, client_flags); failp = check_embedded_connection(mysql, db); if (failp) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Call to check_embedded_connection failed. " - "Exiting."))); - goto return_err_with_thd; + MXS_ERROR("Call to check_embedded_connection failed."); + goto return_err_with_thd; } thd->clear_data_list(); /** Check that we are calling the client functions in right order */ if (mysql->status != MYSQL_STATUS_READY) { set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Invalid status %d in embedded server. " - "Exiting.", mysql->status))); + MXS_ERROR("Invalid status %d in embedded server.", + mysql->status); goto return_err_with_thd; } /** Clear result variables */ @@ -369,19 +361,15 @@ static bool create_parse_tree( failp = thd->set_db(virtual_db, strlen(virtual_db)); if (failp) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to set database in thread context."))); + MXS_ERROR("Failed to set database in thread context."); } failp = parse_sql(thd, &parser_state, NULL); if (failp) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [readwritesplit:create_parse_tree] failed to " - "create parse tree.", - pthread_self()))); + MXS_DEBUG("%lu [readwritesplit:create_parse_tree] failed to " + "create parse tree.", + pthread_self()); } return_here: return failp; @@ -440,18 +428,12 @@ static skygw_query_type_t resolve_query_type( if (sql_command_flags[lex->sql_command] & CF_IMPLICT_COMMIT_BEGIN) { - skygw_log_write( - LOGFILE_TRACE, - "Implicit COMMIT before executing the " - "next command."); + MXS_INFO("Implicit COMMIT before executing the next command."); } else if (sql_command_flags[lex->sql_command] & CF_IMPLICIT_COMMIT_END) { - skygw_log_write( - LOGFILE_TRACE, - "Implicit COMMIT after executing the " - "next command."); + MXS_INFO("Implicit COMMIT after executing the next command."); } } @@ -466,10 +448,8 @@ static skygw_query_type_t resolve_query_type( { if (LOG_IS_ENABLED(LOGFILE_TRACE)) { - skygw_log_write( - LOGFILE_TRACE, - "Disable autocommit : implicit START TRANSACTION" - " before executing the next command."); + MXS_INFO("Disable autocommit : implicit START TRANSACTION" + " before executing the next command."); } type |= QUERY_TYPE_DISABLE_AUTOCOMMIT; type |= QUERY_TYPE_BEGIN_TRX; @@ -641,12 +621,10 @@ static skygw_query_type_t resolve_query_type( Item::Type itype; itype = item->type(); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] Item %s:%s", - pthread_self(), - item->name, - STRITEMTYPE(itype)))); + MXS_DEBUG("%lu [resolve_query_type] Item %s:%s", + pthread_self(), + item->name, + STRITEMTYPE(itype)); if (itype == Item::SUBSELECT_ITEM) { continue; @@ -707,50 +685,40 @@ static skygw_query_type_t resolve_query_type( * belongs to this category. */ func_qtype |= QUERY_TYPE_WRITE; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype FUNC_SP, stored proc " - "or unknown function.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype FUNC_SP, stored proc " + "or unknown function.", + pthread_self()); break; case Item_func::UDF_FUNC: func_qtype |= QUERY_TYPE_WRITE; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype UDF_FUNC, user-defined " - "function.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype UDF_FUNC, user-defined " + "function.", + pthread_self()); break; case Item_func::NOW_FUNC: func_qtype |= QUERY_TYPE_LOCAL_READ; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype NOW_FUNC, could be " - "executed in MaxScale.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype NOW_FUNC, could be " + "executed in MaxScale.", + pthread_self()); break; /** System session variable */ case Item_func::GSYSVAR_FUNC: func_qtype |= QUERY_TYPE_SYSVAR_READ; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype GSYSVAR_FUNC, system " - "variable read.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype GSYSVAR_FUNC, system " + "variable read.", + pthread_self()); break; /** User-defined variable read */ case Item_func::GUSERVAR_FUNC: func_qtype |= QUERY_TYPE_USERVAR_READ; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype GUSERVAR_FUNC, user " - "variable read.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype GUSERVAR_FUNC, user " + "variable read.", + pthread_self()); break; /** User-defined variable modification */ case Item_func::SUSERVAR_FUNC: @@ -760,12 +728,10 @@ static skygw_query_type_t resolve_query_type( * 15.9.14 */ func_qtype |= QUERY_TYPE_GSYSVAR_WRITE; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype SUSERVAR_FUNC, user " - "variable write.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype SUSERVAR_FUNC, user " + "variable write.", + pthread_self()); break; case Item_func::UNKNOWN_FUNC: @@ -783,21 +749,17 @@ static skygw_query_type_t resolve_query_type( * type, for example, rand(), soundex(), * repeat() . */ - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "functype UNKNOWN_FUNC, " - "typically some system function.", - pthread_self()))); + MXS_DEBUG("%lu [resolve_query_type] " + "functype UNKNOWN_FUNC, " + "typically some system function.", + pthread_self()); break; default: - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [resolve_query_type] " - "Functype %d.", - pthread_self(), - ftype))); - break; + MXS_DEBUG("%lu [resolve_query_type] " + "Functype %d.", + pthread_self(), + ftype); + break; } /**< switch */ /**< Set new query type */ type |= func_qtype; @@ -1204,7 +1166,7 @@ inline void add_str(char** buf, int* buflen, int* bufsize, char* str) *bufsize = (*bufsize) * 2 + isize; char *tmp = (char*)realloc(*buf,(*bufsize)* sizeof(char)); if(tmp == NULL){ - skygw_log_write_flush (LE,"Error: memory reallocation failed"); + MXS_ERROR("Error: memory reallocation failed."); free(*buf); *buf = NULL; *bufsize = 0; @@ -1247,7 +1209,7 @@ char* skygw_get_affected_fields(GWBUF* buf) lex->current_select = lex->all_selects_list; if((where = (char*)malloc(sizeof(char)*1)) == NULL) { - skygw_log_write_flush(LE,"Error: Memory allocation failed."); + MXS_ERROR("Memory allocation failed."); return NULL; } *where = '\0'; @@ -1445,13 +1407,11 @@ parsing_info_t* parsing_info_init( ss_dassert(mysql != NULL); if (mysql == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : call to mysql_real_connect failed due %d, %s.", - mysql_errno(mysql), - mysql_error(mysql)))); + MXS_ERROR("Call to mysql_real_connect failed due %d, %s.", + mysql_errno(mysql), + mysql_error(mysql)); - goto retblock; + goto retblock; } /** Set methods and authentication to mysql */ mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_skygw"); From f3a4bedbf5b8e6d2f2365539751031cbbe61fdcf Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 13:14:34 +0200 Subject: [PATCH 165/179] Mysqlmon formatting changes Fixed indentation, bracket alignment and other minor things. --- server/modules/monitor/mysql_mon.c | 1935 ++++++++++++++-------------- 1 file changed, 1003 insertions(+), 932 deletions(-) diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index 7fb50ecec..f1c922581 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -56,23 +56,23 @@ #include #include -static void monitorMain(void *); +static void monitorMain(void *); static char *version_str = "V1.4.0"; -MODULE_INFO info = { - MODULE_API_MONITOR, - MODULE_GA, - MONITOR_VERSION, - "A MySQL Master/Slave replication monitor" +MODULE_INFO info = { + MODULE_API_MONITOR, + MODULE_GA, + MONITOR_VERSION, + "A MySQL Master/Slave replication monitor" }; -static void *startMonitor(void *,void*); -static void stopMonitor(void *); -static void diagnostics(DCB *, void *); -static void defaultId(void *, unsigned long); -static MONITOR_SERVERS *getServerByNodeId(MONITOR_SERVERS *, long); -static MONITOR_SERVERS *getSlaveOfNodeId(MONITOR_SERVERS *, long); +static void *startMonitor(void *, void*); +static void stopMonitor(void *); +static void diagnostics(DCB *, void *); +static void defaultId(void *, unsigned long); +static MONITOR_SERVERS *getServerByNodeId(MONITOR_SERVERS *, long); +static MONITOR_SERVERS *getSlaveOfNodeId(MONITOR_SERVERS *, long); static MONITOR_SERVERS *get_replication_tree(MONITOR *, int); static void set_master_heartbeat(MYSQL_MONITOR *, MONITOR_SERVERS *); static void set_slave_heartbeat(MONITOR *, MONITOR_SERVERS *); @@ -82,10 +82,10 @@ void check_maxscale_schema_replication(MONITOR *monitor); static bool report_version_err = true; static const char* hb_table_name = "maxscale_schema.replication_heartbeat"; -static MONITOR_OBJECT MyObject = { - startMonitor, - stopMonitor, - diagnostics +static MONITOR_OBJECT MyObject = { + startMonitor, + stopMonitor, + diagnostics }; /** @@ -96,7 +96,7 @@ static MONITOR_OBJECT MyObject = { char * version() { - return version_str; + return version_str; } /** @@ -106,10 +106,9 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise the MySQL Monitor module %s.", - version_str))); + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, + "Initialise the MySQL Monitor module %s.", + version_str))); } /** @@ -123,7 +122,7 @@ ModuleInit() MONITOR_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -135,78 +134,78 @@ GetModuleObject() * @param opt Configuration parameters * @return A handle to use when interacting with the monitor */ -static void * +static void * startMonitor(void *arg, void* opt) { - MONITOR* monitor = (MONITOR*)arg; - MYSQL_MONITOR *handle = (MYSQL_MONITOR*)monitor->handle; - CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - bool have_events = false,script_error = false; + MONITOR* monitor = (MONITOR*) arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR*) monitor->handle; + CONFIG_PARAMETER* params = (CONFIG_PARAMETER*) opt; + bool have_events = false, script_error = false; if (handle) { - handle->shutdown = 0; + handle->shutdown = 0; } else { - if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) - return NULL; - handle->shutdown = 0; - handle->id = config_get_gateway_id(); - handle->replicationHeartbeat = 0; - handle->detectStaleMaster = 0; - handle->master = NULL; - handle->script = NULL; - handle->mysql51_replication = false; - memset(handle->events,false,sizeof(handle->events)); - spinlock_init(&handle->lock); + if ((handle = (MYSQL_MONITOR *) malloc(sizeof(MYSQL_MONITOR))) == NULL) + return NULL; + handle->shutdown = 0; + handle->id = config_get_gateway_id(); + handle->replicationHeartbeat = 0; + handle->detectStaleMaster = 0; + handle->master = NULL; + handle->script = NULL; + handle->mysql51_replication = false; + memset(handle->events, false, sizeof(handle->events)); + spinlock_init(&handle->lock); } - while(params) + while (params) { - if(!strcmp(params->name,"detect_stale_master")) - handle->detectStaleMaster = config_truth_value(params->value); - else if(!strcmp(params->name,"detect_replication_lag")) - handle->replicationHeartbeat = config_truth_value(params->value); - else if (!strcmp(params->name, "script")) - { - if (externcmd_can_execute(params->value)) + if (!strcmp(params->name, "detect_stale_master")) + handle->detectStaleMaster = config_truth_value(params->value); + else if (!strcmp(params->name, "detect_replication_lag")) + handle->replicationHeartbeat = config_truth_value(params->value); + else if (!strcmp(params->name, "script")) { - free(handle->script); - handle->script = strdup(params->value); + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } } - else + else if (!strcmp(params->name, "events")) { - script_error = true; + if (mon_parse_event_string((bool*) & handle->events, sizeof(handle->events), params->value) != 0) + script_error = true; + else + have_events = true; } + else if (!strcmp(params->name, "mysql51_replication")) + { + handle->mysql51_replication = config_truth_value(params->value); + } + params = params->next; } - else if(!strcmp(params->name,"events")) - { - if(mon_parse_event_string((bool*)&handle->events,sizeof(handle->events),params->value) != 0) - script_error = true; - else - have_events = true; - } - else if(!strcmp(params->name,"mysql51_replication")) - { - handle->mysql51_replication = config_truth_value(params->value); - } - params = params->next; - } - if(script_error) + if (script_error) { - skygw_log_write(LE,"Error: Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.",monitor->name); - free(handle->script); - handle->script = NULL; + skygw_log_write(LE, "Error: Errors were found in the script configuration parameters " + "for the monitor '%s'. The script will not be used.", monitor->name); + free(handle->script); + handle->script = NULL; } /** If no specific events are given, enable them all */ - if(!have_events) + if (!have_events) { - memset(handle->events,true,sizeof(handle->events)); + memset(handle->events, true, sizeof(handle->events)); } - handle->tid = (THREAD)thread_start(monitorMain, monitor); + handle->tid = (THREAD) thread_start(monitorMain, monitor); return handle; } @@ -215,14 +214,14 @@ startMonitor(void *arg, void* opt) * * @param arg Handle on thr running monior */ -static void +static void stopMonitor(void *arg) { - MONITOR* mon = (MONITOR*)arg; - MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; + MONITOR* mon = (MONITOR*) arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) mon->handle; handle->shutdown = 1; - thread_wait((void *)handle->tid); + thread_wait((void *) handle->tid); } /** @@ -233,44 +232,44 @@ stopMonitor(void *arg) */ static void diagnostics(DCB *dcb, void *arg) { - MONITOR* mon = (MONITOR*)arg; - MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; - MONITOR_SERVERS *db; - char *sep; + MONITOR* mon = (MONITOR*) arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) mon->handle; + MONITOR_SERVERS *db; + char *sep; switch (handle->status) { - case MONITOR_RUNNING: - dcb_printf(dcb, "\tMonitor running\n"); - break; - case MONITOR_STOPPING: - dcb_printf(dcb, "\tMonitor stopping\n"); - break; - case MONITOR_STOPPED: - dcb_printf(dcb, "\tMonitor stopped\n"); - break; + case MONITOR_RUNNING: + dcb_printf(dcb, "\tMonitor running\n"); + break; + case MONITOR_STOPPING: + dcb_printf(dcb, "\tMonitor stopping\n"); + break; + case MONITOR_STOPPED: + dcb_printf(dcb, "\tMonitor stopped\n"); + break; } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); - dcb_printf(dcb,"\tMaxScale MonitorId:\t%lu\n", handle->id); - dcb_printf(dcb,"\tReplication lag:\t%s\n", (handle->replicationHeartbeat == 1) ? "enabled" : "disabled"); - dcb_printf(dcb,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); + dcb_printf(dcb, "\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb, "\tMaxScale MonitorId:\t%lu\n", handle->id); + dcb_printf(dcb, "\tReplication lag:\t%s\n", (handle->replicationHeartbeat == 1) ? "enabled" : "disabled"); + dcb_printf(dcb, "\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); + dcb_printf(dcb, "\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb, "\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb, "\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); dcb_printf(dcb, "\tMonitored servers: "); - + db = mon->databases; sep = ""; while (db) { - dcb_printf(dcb, - "%s%s:%d", - sep, - db->server->name, - db->server->port); - sep = ", "; - db = db->next; + dcb_printf(dcb, + "%s%s:%d", + sep, + db->server->name, + db->server->port); + sep = ", "; + db = db->next; } dcb_printf(dcb, "\n"); } @@ -282,52 +281,58 @@ static inline void monitor_mysql100_db(MONITOR_SERVERS* database) MYSQL_ROW row; if (mysql_query(database->con, "SHOW ALL SLAVES STATUS") == 0 - && (result = mysql_store_result(database->con)) != NULL) + && (result = mysql_store_result(database->con)) != NULL) { - int i = 0; - long master_id = -1; + int i = 0; + long master_id = -1; - if(mysql_field_count(database->con) < 42) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: \"SHOW ALL SLAVES STATUS\" " - "returned less than the expected amount of columns. Expected 42 columns." - " MySQL Version: %s",version_str); - return; - } + if (mysql_field_count(database->con) < 42) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: \"SHOW ALL SLAVES STATUS\" " + "returned less than the expected amount of columns. Expected 42 columns." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - if (strncmp(row[12], "Yes", 3) == 0 - && strncmp(row[13], "Yes", 3) == 0) { - isslave += 1; - } + while ((row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + if (strncmp(row[12], "Yes", 3) == 0 + && strncmp(row[13], "Yes", 3) == 0) + { + isslave += 1; + } - /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building - * the replication tree, slaves ids will be added to master(s) and we will have at least the - * root master server. - * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' - */ - if (strncmp(row[12], "Yes", 3) == 0) { - /* get Master_Server_Id values */ - master_id = atol(row[41]); - if (master_id == 0) - master_id = -1; - } + /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building + * the replication tree, slaves ids will be added to master(s) and we will have at least the + * root master server. + * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' + */ + if (strncmp(row[12], "Yes", 3) == 0) + { + /* get Master_Server_Id values */ + master_id = atol(row[41]); + if (master_id == 0) + master_id = -1; + } - i++; - } - /* store master_id of current node */ - memcpy(&database->server->master_id, &master_id, sizeof(long)); + i++; + } + /* store master_id of current node */ + memcpy(&database->server->master_id, &master_id, sizeof(long)); - mysql_free_result(result); + mysql_free_result(result); - /* If all configured slaves are running set this node as slave */ - if (isslave > 0 && isslave == i) - isslave = 1; - else - isslave = 0; + /* If all configured slaves are running set this node as slave */ + if (isslave > 0 && isslave == i) + { + isslave = 1; + } + else + { + isslave = 0; + } } /* Remove addition info */ @@ -341,13 +346,15 @@ static inline void monitor_mysql100_db(MONITOR_SERVERS* database) /* Set the Slave Role */ if (isslave) { - monitor_set_pending_status(database, SERVER_SLAVE); - /* Avoid any possible stale Master state */ - monitor_clear_pending_status(database, SERVER_MASTER); - } else { - /* Avoid any possible Master/Slave stale state */ - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_clear_pending_status(database, SERVER_MASTER); + monitor_set_pending_status(database, SERVER_SLAVE); + /* Avoid any possible stale Master state */ + monitor_clear_pending_status(database, SERVER_MASTER); + } + else + { + /* Avoid any possible Master/Slave stale state */ + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_clear_pending_status(database, SERVER_MASTER); } } @@ -358,42 +365,44 @@ static inline void monitor_mysql55_db(MONITOR_SERVERS* database) MYSQL_ROW row; if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0 - && (result = mysql_store_result(database->con)) != NULL) + && (result = mysql_store_result(database->con)) != NULL) { - long master_id = -1; - if(mysql_field_count(database->con) < 40) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" " - "returned less than the expected amount of columns. Expected 40 columns." - " MySQL Version: %s",version_str); - return; - } + long master_id = -1; + if (mysql_field_count(database->con) < 40) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: \"SHOW SLAVE STATUS\" " + "returned less than the expected amount of columns. Expected 40 columns." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - if (strncmp(row[10], "Yes", 3) == 0 - && strncmp(row[11], "Yes", 3) == 0) { - isslave = 1; - } + while ((row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + if (strncmp(row[10], "Yes", 3) == 0 + && strncmp(row[11], "Yes", 3) == 0) + { + isslave = 1; + } - /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building - * the replication tree, slaves ids will be added to master(s) and we will have at least the - * root master server. - * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' - */ - if (strncmp(row[10], "Yes", 3) == 0) { - /* get Master_Server_Id values */ - master_id = atol(row[39]); - if (master_id == 0) - master_id = -1; - } - } - /* store master_id of current node */ - memcpy(&database->server->master_id, &master_id, sizeof(long)); + /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building + * the replication tree, slaves ids will be added to master(s) and we will have at least the + * root master server. + * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' + */ + if (strncmp(row[10], "Yes", 3) == 0) + { + /* get Master_Server_Id values */ + master_id = atol(row[39]); + if (master_id == 0) + master_id = -1; + } + } + /* store master_id of current node */ + memcpy(&database->server->master_id, &master_id, sizeof(long)); - mysql_free_result(result); + mysql_free_result(result); } /* Remove addition info */ @@ -407,13 +416,15 @@ static inline void monitor_mysql55_db(MONITOR_SERVERS* database) /* Set the Slave Role */ if (isslave) { - monitor_set_pending_status(database, SERVER_SLAVE); - /* Avoid any possible stale Master state */ - monitor_clear_pending_status(database, SERVER_MASTER); - } else { - /* Avoid any possible Master/Slave stale state */ - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_clear_pending_status(database, SERVER_MASTER); + monitor_set_pending_status(database, SERVER_SLAVE); + /* Avoid any possible stale Master state */ + monitor_clear_pending_status(database, SERVER_MASTER); + } + else + { + /* Avoid any possible Master/Slave stale state */ + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_clear_pending_status(database, SERVER_MASTER); } } @@ -424,27 +435,28 @@ static inline void monitor_mysql51_db(MONITOR_SERVERS* database) MYSQL_ROW row; if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0 - && (result = mysql_store_result(database->con)) != NULL) + && (result = mysql_store_result(database->con)) != NULL) { - if(mysql_field_count(database->con) < 38) - { - mysql_free_result(result); + if (mysql_field_count(database->con) < 38) + { + mysql_free_result(result); - skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" " - "returned less than the expected amount of columns. Expected 38 columns." - " MySQL Version: %s",version_str); - return; - } + skygw_log_write(LE, "Error: \"SHOW SLAVE STATUS\" " + "returned less than the expected amount of columns. Expected 38 columns." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - if (strncmp(row[10], "Yes", 3) == 0 - && strncmp(row[11], "Yes", 3) == 0) { - isslave = 1; - } - } - mysql_free_result(result); + while ((row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + if (strncmp(row[10], "Yes", 3) == 0 + && strncmp(row[11], "Yes", 3) == 0) + { + isslave = 1; + } + } + mysql_free_result(result); } /* Remove addition info */ @@ -458,13 +470,15 @@ static inline void monitor_mysql51_db(MONITOR_SERVERS* database) /* Set the Slave Role */ if (isslave) { - monitor_set_pending_status(database, SERVER_SLAVE); - /* Avoid any possible stale Master state */ - monitor_clear_pending_status(database, SERVER_MASTER); - } else { - /* Avoid any possible Master/Slave stale state */ - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_clear_pending_status(database, SERVER_MASTER); + monitor_set_pending_status(database, SERVER_SLAVE); + /* Avoid any possible stale Master state */ + monitor_clear_pending_status(database, SERVER_MASTER); + } + else + { + /* Avoid any possible Master/Slave stale state */ + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_clear_pending_status(database, SERVER_MASTER); } } @@ -479,87 +493,88 @@ static inline void monitor_mysql51_db(MONITOR_SERVERS* database) static MONITOR_SERVERS *build_mysql51_replication_tree(MONITOR *mon) { MONITOR_SERVERS* database = mon->databases; - MONITOR_SERVERS *ptr,*rval = NULL; + MONITOR_SERVERS *ptr, *rval = NULL; int i; - while(database) + while (database) { - bool ismaster = false; - MYSQL_RES* result; - MYSQL_ROW row; - int nslaves = 0; - if(database->con) - { - if (mysql_query(database->con, "SHOW SLAVE HOSTS") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 4) - { - mysql_free_result(result); - skygw_log_write_flush(LE,"Error: \"SHOW SLAVE HOSTS\" " - "returned less than the expected amount of columns. Expected 4 columns." - " MySQL Version: %s",version_str); - return NULL; - } + bool ismaster = false; + MYSQL_RES* result; + MYSQL_ROW row; + int nslaves = 0; + if (database->con) + { + if (mysql_query(database->con, "SHOW SLAVE HOSTS") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 4) + { + mysql_free_result(result); + skygw_log_write_flush(LE, "Error: \"SHOW SLAVE HOSTS\" " + "returned less than the expected amount of columns. Expected 4 columns." + " MySQL Version: %s", version_str); + return NULL; + } - if(mysql_num_rows(result) > 0) - { - ismaster = true; - while (nslaves < MONITOR_MAX_NUM_SLAVES && (row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - database->server->slaves[nslaves] = atol(row[0]); - nslaves++; - LOGIF(LD,(skygw_log_write_flush(LD,"Found slave at %s:%s",row[1],row[2]))); - } - database->server->slaves[nslaves] = 0; - } + if (mysql_num_rows(result) > 0) + { + ismaster = true; + while (nslaves < MONITOR_MAX_NUM_SLAVES && (row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + database->server->slaves[nslaves] = atol(row[0]); + nslaves++; + LOGIF(LD, (skygw_log_write_flush(LD, "Found slave at %s:%s", row[1], row[2]))); + } + database->server->slaves[nslaves] = 0; + } - mysql_free_result(result); - } + mysql_free_result(result); + } - - /* Set the Slave Role */ - if (ismaster) - { - LOGIF(LD,(skygw_log_write(LD,"Master server found at %s:%d with %d slaves", - database->server->name, - database->server->port, - nslaves))); - monitor_set_pending_status(database, SERVER_MASTER); - if(rval == NULL || rval->server->node_id > database->server->node_id) - rval = database; - } - } - database = database->next; + + /* Set the Slave Role */ + if (ismaster) + { + LOGIF(LD, (skygw_log_write(LD, "Master server found at %s:%d with %d slaves", + database->server->name, + database->server->port, + nslaves))); + monitor_set_pending_status(database, SERVER_MASTER); + if (rval == NULL || rval->server->node_id > database->server->node_id) + rval = database; + } + } + database = database->next; } database = mon->databases; /** Set master server IDs */ - while(database) + while (database) { - ptr = mon->databases; + ptr = mon->databases; - while(ptr) - { - for(i = 0;ptr->server->slaves[i];i++) - { - if(ptr->server->slaves[i] == database->server->node_id) - { - database->server->master_id = ptr->server->node_id; - break; - } - } - ptr = ptr->next; - } - if(database->server->master_id <= 0 && SERVER_IS_SLAVE(database->server)) - { - monitor_set_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER); - } - database = database->next; + while (ptr) + { + for (i = 0; ptr->server->slaves[i]; i++) + { + if (ptr->server->slaves[i] == database->server->node_id) + { + database->server->master_id = ptr->server->node_id; + break; + } + } + ptr = ptr->next; + } + if (database->server->master_id <= 0 && SERVER_IS_SLAVE(database->server)) + { + monitor_set_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER); + } + database = database->next; } return rval; } + /** * Monitor an individual server * @@ -570,71 +585,71 @@ static void monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) { MYSQL_MONITOR* handle = mon->handle; - MYSQL_ROW row; - MYSQL_RES *result; - int isslave = 0; - char *uname = mon->user; + MYSQL_ROW row; + MYSQL_RES *result; + int isslave = 0; + char *uname = mon->user; unsigned long int server_version = 0; - char *server_string; + char *server_string; if (database->server->monuser != NULL) { - uname = database->server->monuser; + uname = database->server->monuser; } if (uname == NULL) - return; + return; /* Don't probe servers in maintenance mode */ if (SERVER_IN_MAINT(database->server)) - return; + return; /** Store previous status */ database->mon_prev_status = database->server->status; if (database->con == NULL || mysql_ping(database->con) != 0) { - connect_result_t rval; - if ((rval = mon_connect_to_db(mon, database)) == MONITOR_CONN_OK) - { - server_clear_status(database->server, SERVER_AUTH_ERROR); - monitor_clear_pending_status(database, SERVER_AUTH_ERROR); - } - else - { - /* The current server is not running - * - * Store server NOT running in server and monitor server pending struct - * - */ - if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR) - { - server_set_status(database->server, SERVER_AUTH_ERROR); - monitor_set_pending_status(database, SERVER_AUTH_ERROR); - } - server_clear_status(database->server, SERVER_RUNNING); - monitor_clear_pending_status(database, SERVER_RUNNING); - - /* Also clear M/S state in both server and monitor server pending struct */ - server_clear_status(database->server, SERVER_SLAVE); - server_clear_status(database->server, SERVER_MASTER); - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_clear_pending_status(database, SERVER_MASTER); - - /* Clean addition status too */ - server_clear_status(database->server, SERVER_SLAVE_OF_EXTERNAL_MASTER); - server_clear_status(database->server, SERVER_STALE_STATUS); - monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER); - monitor_clear_pending_status(database, SERVER_STALE_STATUS); - - /* Log connect failure only once */ - if (mon_status_changed(database) && mon_print_fail_status(database)) + connect_result_t rval; + if ((rval = mon_connect_to_db(mon, database)) == MONITOR_CONN_OK) { - mon_log_connect_error(database, rval); + server_clear_status(database->server, SERVER_AUTH_ERROR); + monitor_clear_pending_status(database, SERVER_AUTH_ERROR); } + else + { + /* The current server is not running + * + * Store server NOT running in server and monitor server pending struct + * + */ + if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR) + { + server_set_status(database->server, SERVER_AUTH_ERROR); + monitor_set_pending_status(database, SERVER_AUTH_ERROR); + } + server_clear_status(database->server, SERVER_RUNNING); + monitor_clear_pending_status(database, SERVER_RUNNING); - return; - } + /* Also clear M/S state in both server and monitor server pending struct */ + server_clear_status(database->server, SERVER_SLAVE); + server_clear_status(database->server, SERVER_MASTER); + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_clear_pending_status(database, SERVER_MASTER); + + /* Clean addition status too */ + server_clear_status(database->server, SERVER_SLAVE_OF_EXTERNAL_MASTER); + server_clear_status(database->server, SERVER_STALE_STATUS); + monitor_clear_pending_status(database, SERVER_SLAVE_OF_EXTERNAL_MASTER); + monitor_clear_pending_status(database, SERVER_STALE_STATUS); + + /* Log connect failure only once */ + if (mon_status_changed(database) && mon_print_fail_status(database)) + { + mon_log_connect_error(database, rval); + } + + return; + } } /* Store current status in both server and monitor server pending struct */ server_set_status(database->server, SERVER_RUNNING); @@ -644,61 +659,61 @@ monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) server_version = mysql_get_server_version(database->con); /* get server version string */ - server_string = (char *)mysql_get_server_info(database->con); + server_string = (char *) mysql_get_server_info(database->con); if (server_string) { server_set_version_string(database->server, server_string); } - + /* get server_id form current node */ if (mysql_query(database->con, "SELECT @@server_id") == 0 - && (result = mysql_store_result(database->con)) != NULL) + && (result = mysql_store_result(database->con)) != NULL) { - long server_id = -1; + long server_id = -1; - if(mysql_field_count(database->con) != 1) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for 'SELECT @@server_id'. Expected 1 column." - " MySQL Version: %s",version_str); - return; - } + if (mysql_field_count(database->con) != 1) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for 'SELECT @@server_id'. Expected 1 column." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - server_id = strtol(row[0], NULL, 10); - if ((errno == ERANGE && (server_id == LONG_MAX - || server_id == LONG_MIN)) || (errno != 0 && server_id == 0)) - { - server_id = -1; - } - database->server->node_id = server_id; - } - mysql_free_result(result); + while ((row = mysql_fetch_row(result))) + { + server_id = strtol(row[0], NULL, 10); + if ((errno == ERANGE && (server_id == LONG_MAX + || server_id == LONG_MIN)) || (errno != 0 && server_id == 0)) + { + server_id = -1; + } + database->server->node_id = server_id; + } + mysql_free_result(result); } /* Check first for MariaDB 10.x.x and get status for multi-master replication */ if (server_version >= 100000) { - monitor_mysql100_db(database); + monitor_mysql100_db(database); } - else if(server_version >= 5*10000 + 5*100) + else if (server_version >= 5 * 10000 + 5 * 100) { - monitor_mysql55_db(database); + monitor_mysql55_db(database); } else { - if(handle->mysql51_replication) - { - monitor_mysql51_db(database); - } - else if(report_version_err) - { - report_version_err = false; - skygw_log_write(LE,"Error: MySQL version is lower than 5.5 and 'mysql51_replication' option is not enabled," - " replication tree cannot be resolved. To enable MySQL 5.1 replication detection, " - "add 'mysql51_replication=true' to the monitor section."); - } + if (handle->mysql51_replication) + { + monitor_mysql51_db(database); + } + else if (report_version_err) + { + report_version_err = false; + skygw_log_write(LE, "Error: MySQL version is lower than 5.5 and 'mysql51_replication' option is not enabled," + " replication tree cannot be resolved. To enable MySQL 5.1 replication detection, " + "add 'mysql51_replication=true' to the monitor section."); + } } } @@ -712,295 +727,302 @@ static void monitorMain(void *arg) { MONITOR* mon = (MONITOR*) arg; -MYSQL_MONITOR *handle; -MONITOR_SERVERS *ptr; -int replication_heartbeat; -int detect_stale_master; -int num_servers=0; -MONITOR_SERVERS *root_master = NULL; -size_t nrounds = 0; -int log_no_master = 1; -bool heartbeat_checked = false; + MYSQL_MONITOR *handle; + MONITOR_SERVERS *ptr; + int replication_heartbeat; + int detect_stale_master; + int num_servers = 0; + MONITOR_SERVERS *root_master = NULL; + size_t nrounds = 0; + int log_no_master = 1; + bool heartbeat_checked = false; -spinlock_acquire(&mon->lock); -handle = (MYSQL_MONITOR *)mon->handle; -spinlock_release(&mon->lock); -replication_heartbeat = handle->replicationHeartbeat; -detect_stale_master = handle->detectStaleMaster; + spinlock_acquire(&mon->lock); + handle = (MYSQL_MONITOR *) mon->handle; + spinlock_release(&mon->lock); + replication_heartbeat = handle->replicationHeartbeat; + detect_stale_master = handle->detectStaleMaster; - if (mysql_thread_init()) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Fatal : mysql_thread_init failed in monitor " - "module. Exiting.\n"))); - return; - } - handle->status = MONITOR_RUNNING; - - while (1) - { - if (handle->shutdown) - { - handle->status = MONITOR_STOPPING; - mysql_thread_end(); - handle->status = MONITOR_STOPPED; - return; - } - /** Wait base interval */ - thread_millisleep(MON_BASE_INTERVAL_MS); + if (mysql_thread_init()) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Fatal : mysql_thread_init failed in monitor " + "module. Exiting.\n"))); + return; + } + handle->status = MONITOR_RUNNING; - if (handle->replicationHeartbeat && !heartbeat_checked) - { - check_maxscale_schema_replication(mon); - heartbeat_checked = true; - } + while (1) + { + if (handle->shutdown) + { + handle->status = MONITOR_STOPPING; + mysql_thread_end(); + handle->status = MONITOR_STOPPED; + return; + } + /** Wait base interval */ + thread_millisleep(MON_BASE_INTERVAL_MS); - /** - * Calculate how far away the monitor interval is from its full - * cycle and if monitor interval time further than the base - * interval, then skip monitoring checks. Excluding the first - * round. - */ - if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= - MON_BASE_INTERVAL_MS) - { - nrounds += 1; - continue; - } - nrounds += 1; - /* reset num_servers */ - num_servers = 0; + if (handle->replicationHeartbeat && !heartbeat_checked) + { + check_maxscale_schema_replication(mon); + heartbeat_checked = true; + } - /* start from the first server in the list */ - ptr = mon->databases; + /** + * Calculate how far away the monitor interval is from its full + * cycle and if monitor interval time further than the base + * interval, then skip monitoring checks. Excluding the first + * round. + */ + if (nrounds != 0 && + ((nrounds * MON_BASE_INTERVAL_MS) % mon->interval) >= + MON_BASE_INTERVAL_MS) + { + nrounds += 1; + continue; + } + nrounds += 1; + /* reset num_servers */ + num_servers = 0; - while (ptr) - { - ptr->mon_prev_status = ptr->server->status; + /* start from the first server in the list */ + ptr = mon->databases; - /* copy server status into monitor pending_status */ - ptr->pending_status = ptr->server->status; + while (ptr) + { + ptr->mon_prev_status = ptr->server->status; - /* monitor current node */ - monitorDatabase(mon, ptr); + /* copy server status into monitor pending_status */ + ptr->pending_status = ptr->server->status; - /* reset the slave list of current node */ - if (ptr->server->slaves) { - free(ptr->server->slaves); - } - /* create a new slave list */ - ptr->server->slaves = (long *) calloc(MONITOR_MAX_NUM_SLAVES, sizeof(long)); + /* monitor current node */ + monitorDatabase(mon, ptr); - num_servers++; + /* reset the slave list of current node */ + if (ptr->server->slaves) + { + free(ptr->server->slaves); + } + /* create a new slave list */ + ptr->server->slaves = (long *) calloc(MONITOR_MAX_NUM_SLAVES, sizeof(long)); - if (mon_status_changed(ptr)) - { - if (SRV_MASTER_STATUS(ptr->mon_prev_status)) - { - /** Master failed, can't recover */ - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Server %s:%d lost the master status.", - ptr->server->name, - ptr->server->port))); - } - /** - * Here we say: If the server's state changed - * so that it isn't running or some other way - * lost cluster membership, call call-back function - * of every DCB for which such callback was - * registered for this kind of issue (DCB_REASON_...) - */ - if (!(SERVER_IS_RUNNING(ptr->server)) || - !(SERVER_IS_IN_CLUSTER(ptr->server))) - { - dcb_hangup_foreach(ptr->server); - } + num_servers++; - - - - } - - if (mon_status_changed(ptr)) - { -#if defined(SS_DEBUG) - LOGIF(LT, (skygw_log_write_flush( - LOGFILE_TRACE, - "Backend server %s:%d state : %s", - ptr->server->name, - ptr->server->port, - STRSRVSTATUS(ptr->server)))); -#else - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Backend server %s:%d state : %s", - ptr->server->name, - ptr->server->port, - STRSRVSTATUS(ptr->server)))); -#endif - } - - if (SERVER_IS_DOWN(ptr->server)) - { - /** Increase this server'e error count */ - ptr->mon_err_count += 1; - } - else - { - /** Reset this server's error count */ - ptr->mon_err_count = 0; - } - - ptr = ptr->next; - } - - ptr = mon->databases; - /* if only one server is configured, that's is Master */ - if (num_servers == 1) { - if (SERVER_IS_RUNNING(ptr->server)) { - ptr->server->depth = 0; - /* status cleanup */ - monitor_clear_pending_status(ptr, SERVER_SLAVE); - - /* master status set */ - monitor_set_pending_status(ptr, SERVER_MASTER); - - ptr->server->depth = 0; - handle->master = ptr; - root_master = ptr; - } - } else { - /* Compute the replication tree */ - if(handle->mysql51_replication) - root_master = build_mysql51_replication_tree(mon); - else - root_master = get_replication_tree(mon, num_servers); - - } - - /* Update server status from monitor pending status on that server*/ - - ptr = mon->databases; - while (ptr) - { - if (! SERVER_IN_MAINT(ptr->server)) { - /* If "detect_stale_master" option is On, let's use the previus master */ - if (detect_stale_master && - root_master && - (!strcmp(ptr->server->name, root_master->server->name) && - ptr->server->port == root_master->server->port) && - (ptr->server->status & SERVER_MASTER) && - !(ptr->pending_status & SERVER_MASTER)) - { - /** - * In this case server->status will not be updated from pending_statu - * Set the STALE bit for this server in server struct - */ - server_set_status(ptr->server, SERVER_STALE_STATUS); - - /* log it once */ - if (mon_status_changed(ptr)) { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "[mysql_mon]: root server " - "[%s:%i] is no longer Master," - " let's use it again even " - " if it could be a stale master," - " you have been warned!", - ptr->server->name, - ptr->server->port))); - } - } else { - ptr->server->status = ptr->pending_status; - } - } - ptr = ptr->next; - } - - ptr = mon->databases; - monitor_event_t evtype; - while(ptr) - { - /** Execute monitor script if a server state has changed */ - if(mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if(isMySQLEvent(evtype)) - { - skygw_log_write(LOGFILE_TRACE,"Server changed state: %s[%s:%u]: %s", - ptr->server->unique_name, - ptr->server->name,ptr->server->port, - mon_get_event_name(ptr)); - if(handle->script && handle->events[evtype]) - { - monitor_launch_script(mon,ptr,handle->script); - } - } - } - ptr = ptr->next; - } - - /* log master detection failure of first master becomes available after failure */ - if (root_master && - mon_status_changed(root_master) && - !(root_master->server->status & SERVER_STALE_STATUS)) - { - if (root_master->pending_status & (SERVER_MASTER) && SERVER_IS_RUNNING(root_master->server)) { - if (!(root_master->mon_prev_status & SERVER_STALE_STATUS) && - !(root_master->server->status & SERVER_MAINT)) - { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Info : A Master Server is now available: %s:%i", - root_master->server->name, - root_master->server->port))); - } - } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No Master can be determined. Last known was %s:%i", - root_master->server->name, - root_master->server->port))); - } - log_no_master = 1; - } else { - if (!root_master && log_no_master) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : No Master can be determined"))); - log_no_master = 0; - } - } - - /* Do now the heartbeat replication set/get for MySQL Replication Consistency */ - if (replication_heartbeat && - root_master && - (SERVER_IS_MASTER(root_master->server) || - SERVER_IS_RELAY_SERVER(root_master->server))) - { - set_master_heartbeat(handle, root_master); - ptr = mon->databases; - - while (ptr) { - if( (! SERVER_IN_MAINT(ptr->server)) && SERVER_IS_RUNNING(ptr->server)) - { - if (ptr->server->node_id != root_master->server->node_id && - (SERVER_IS_SLAVE(ptr->server) || - SERVER_IS_RELAY_SERVER(ptr->server))) - { - set_slave_heartbeat(mon, ptr); - } - } - ptr = ptr->next; - } + if (mon_status_changed(ptr)) + { + if (SRV_MASTER_STATUS(ptr->mon_prev_status)) + { + /** Master failed, can't recover */ + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, + "Server %s:%d lost the master status.", + ptr->server->name, + ptr->server->port))); } - } /*< while (1) */ + /** + * Here we say: If the server's state changed + * so that it isn't running or some other way + * lost cluster membership, call call-back function + * of every DCB for which such callback was + * registered for this kind of issue (DCB_REASON_...) + */ + if (!(SERVER_IS_RUNNING(ptr->server)) || + !(SERVER_IS_IN_CLUSTER(ptr->server))) + { + dcb_hangup_foreach(ptr->server); + } + + + + + } + + if (mon_status_changed(ptr)) + { +#if defined(SS_DEBUG) + LOGIF(LT, (skygw_log_write_flush(LOGFILE_TRACE, + "Backend server %s:%d state : %s", + ptr->server->name, + ptr->server->port, + STRSRVSTATUS(ptr->server)))); +#else + LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, + "Backend server %s:%d state : %s", + ptr->server->name, + ptr->server->port, + STRSRVSTATUS(ptr->server)))); +#endif + } + + if (SERVER_IS_DOWN(ptr->server)) + { + /** Increase this server'e error count */ + ptr->mon_err_count += 1; + } + else + { + /** Reset this server's error count */ + ptr->mon_err_count = 0; + } + + ptr = ptr->next; + } + + ptr = mon->databases; + /* if only one server is configured, that's is Master */ + if (num_servers == 1) + { + if (SERVER_IS_RUNNING(ptr->server)) + { + ptr->server->depth = 0; + /* status cleanup */ + monitor_clear_pending_status(ptr, SERVER_SLAVE); + + /* master status set */ + monitor_set_pending_status(ptr, SERVER_MASTER); + + ptr->server->depth = 0; + handle->master = ptr; + root_master = ptr; + } + } + else + { + /* Compute the replication tree */ + if (handle->mysql51_replication) + root_master = build_mysql51_replication_tree(mon); + else + root_master = get_replication_tree(mon, num_servers); + + } + + /* Update server status from monitor pending status on that server*/ + + ptr = mon->databases; + while (ptr) + { + if (!SERVER_IN_MAINT(ptr->server)) + { + /* If "detect_stale_master" option is On, let's use the previus master */ + if (detect_stale_master && + root_master && + (!strcmp(ptr->server->name, root_master->server->name) && + ptr->server->port == root_master->server->port) && + (ptr->server->status & SERVER_MASTER) && + !(ptr->pending_status & SERVER_MASTER)) + { + /** + * In this case server->status will not be updated from pending_statu + * Set the STALE bit for this server in server struct + */ + server_set_status(ptr->server, SERVER_STALE_STATUS); + + /* log it once */ + if (mon_status_changed(ptr)) + { + LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, + "[mysql_mon]: root server " + "[%s:%i] is no longer Master," + " let's use it again even " + " if it could be a stale master," + " you have been warned!", + ptr->server->name, + ptr->server->port))); + } + } + else + { + ptr->server->status = ptr->pending_status; + } + } + ptr = ptr->next; + } + + ptr = mon->databases; + monitor_event_t evtype; + while (ptr) + { + /** Execute monitor script if a server state has changed */ + if (mon_status_changed(ptr)) + { + evtype = mon_get_event_type(ptr); + if (isMySQLEvent(evtype)) + { + skygw_log_write(LOGFILE_TRACE, "Server changed state: %s[%s:%u]: %s", + ptr->server->unique_name, + ptr->server->name, ptr->server->port, + mon_get_event_name(ptr)); + if (handle->script && handle->events[evtype]) + { + monitor_launch_script(mon, ptr, handle->script); + } + } + } + ptr = ptr->next; + } + + /* log master detection failure of first master becomes available after failure */ + if (root_master && + mon_status_changed(root_master) && + !(root_master->server->status & SERVER_STALE_STATUS)) + { + if (root_master->pending_status & (SERVER_MASTER) && SERVER_IS_RUNNING(root_master->server)) + { + if (!(root_master->mon_prev_status & SERVER_STALE_STATUS) && + !(root_master->server->status & SERVER_MAINT)) + { + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, + "Info : A Master Server is now available: %s:%i", + root_master->server->name, + root_master->server->port))); + } + } + else + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Error : No Master can be determined. Last known was %s:%i", + root_master->server->name, + root_master->server->port))); + } + log_no_master = 1; + } + else + { + if (!root_master && log_no_master) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Error : No Master can be determined"))); + log_no_master = 0; + } + } + + /* Do now the heartbeat replication set/get for MySQL Replication Consistency */ + if (replication_heartbeat && + root_master && + (SERVER_IS_MASTER(root_master->server) || + SERVER_IS_RELAY_SERVER(root_master->server))) + { + set_master_heartbeat(handle, root_master); + ptr = mon->databases; + + while (ptr) + { + if ((!SERVER_IN_MAINT(ptr->server)) && SERVER_IS_RUNNING(ptr->server)) + { + if (ptr->server->node_id != root_master->server->node_id && + (SERVER_IS_SLAVE(ptr->server) || + SERVER_IS_RELAY_SERVER(ptr->server))) + { + set_slave_heartbeat(mon, ptr); + } + } + ptr = ptr->next; + } + } + } /*< while (1) */ } - + /** * Set the default id to use in the monitor. * @@ -1009,10 +1031,10 @@ detect_stale_master = handle->detectStaleMaster; */ static void defaultId(void *arg, unsigned long id) - { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->id, &id, sizeof(unsigned long)); - } +{ + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) arg; + memcpy(&handle->id, &id, sizeof(unsigned long)); +} /** * Enable/Disable the MySQL Replication hearbeat, detecting slave lag behind master. @@ -1023,8 +1045,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; static void replicationHeartbeat(void *arg, int enable) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->replicationHeartbeat, &enable, sizeof(int)); + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) arg; + memcpy(&handle->replicationHeartbeat, &enable, sizeof(int)); } /** @@ -1038,8 +1060,8 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; static void detectStaleMaster(void *arg, int enable) { -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; - memcpy(&handle->detectStaleMaster, &enable, sizeof(int)); + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) arg; + memcpy(&handle->detectStaleMaster, &enable, sizeof(int)); } /** @@ -1050,17 +1072,19 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg; * @return The server with the required server_id */ static MONITOR_SERVERS * -getServerByNodeId(MONITOR_SERVERS *ptr, long node_id) { - SERVER *current; - while (ptr) +getServerByNodeId(MONITOR_SERVERS *ptr, long node_id) +{ + SERVER *current; + while (ptr) + { + current = ptr->server; + if (current->node_id == node_id) { - current = ptr->server; - if (current->node_id == node_id) { - return ptr; - } - ptr = ptr->next; + return ptr; } - return NULL; + ptr = ptr->next; + } + return NULL; } /** @@ -1071,17 +1095,19 @@ getServerByNodeId(MONITOR_SERVERS *ptr, long node_id) { * @return The slave server of this node_id */ static MONITOR_SERVERS * -getSlaveOfNodeId(MONITOR_SERVERS *ptr, long node_id) { - SERVER *current; - while (ptr) +getSlaveOfNodeId(MONITOR_SERVERS *ptr, long node_id) +{ + SERVER *current; + while (ptr) + { + current = ptr->server; + if (current->master_id == node_id) { - current = ptr->server; - if (current->master_id == node_id) { - return ptr; - } - ptr = ptr->next; + return ptr; } - return NULL; + ptr = ptr->next; + } + return NULL; } /******* @@ -1092,107 +1118,113 @@ getSlaveOfNodeId(MONITOR_SERVERS *ptr, long node_id) { * @param handle The monitor handle * @param database The number database server */ -static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) { - unsigned long id = handle->id; - time_t heartbeat; - time_t purge_time; - char heartbeat_insert_query[512]=""; - char heartbeat_purge_query[512]=""; +static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *database) +{ + unsigned long id = handle->id; + time_t heartbeat; + time_t purge_time; + char heartbeat_insert_query[512] = ""; + char heartbeat_purge_query[512] = ""; - if (handle->master == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: set_master_heartbeat called without an available Master server"))); - return; - } + if (handle->master == NULL) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: set_master_heartbeat called without an available Master server"))); + return; + } - /* create the maxscale_schema database */ - if (mysql_query(database->con, "CREATE DATABASE IF NOT EXISTS maxscale_schema")) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: Error creating maxscale_schema database in Master server" - ": %s", mysql_error(database->con)))); + /* create the maxscale_schema database */ + if (mysql_query(database->con, "CREATE DATABASE IF NOT EXISTS maxscale_schema")) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: Error creating maxscale_schema database in Master server" + ": %s", mysql_error(database->con)))); - database->server->rlag = -1; - } + database->server->rlag = -1; + } - /* create repl_heartbeat table in maxscale_schema database */ - if (mysql_query(database->con, "CREATE TABLE IF NOT EXISTS " - "maxscale_schema.replication_heartbeat " - "(maxscale_id INT NOT NULL, " - "master_server_id INT NOT NULL, " - "master_timestamp INT UNSIGNED NOT NULL, " - "PRIMARY KEY ( master_server_id, maxscale_id ) ) " - "ENGINE=MYISAM DEFAULT CHARSET=latin1")) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: Error creating maxscale_schema.replication_heartbeat table in Master server" - ": %s", mysql_error(database->con)))); + /* create repl_heartbeat table in maxscale_schema database */ + if (mysql_query(database->con, "CREATE TABLE IF NOT EXISTS " + "maxscale_schema.replication_heartbeat " + "(maxscale_id INT NOT NULL, " + "master_server_id INT NOT NULL, " + "master_timestamp INT UNSIGNED NOT NULL, " + "PRIMARY KEY ( master_server_id, maxscale_id ) ) " + "ENGINE=MYISAM DEFAULT CHARSET=latin1")) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: Error creating maxscale_schema.replication_heartbeat table in Master server" + ": %s", mysql_error(database->con)))); - database->server->rlag = -1; - } + database->server->rlag = -1; + } - /* auto purge old values after 48 hours*/ - purge_time = time(0) - (3600 * 48); + /* auto purge old values after 48 hours*/ + purge_time = time(0) - (3600 * 48); - sprintf(heartbeat_purge_query, "DELETE FROM maxscale_schema.replication_heartbeat WHERE master_timestamp < %lu", purge_time); + sprintf(heartbeat_purge_query, "DELETE FROM maxscale_schema.replication_heartbeat WHERE master_timestamp < %lu", purge_time); - if (mysql_query(database->con, heartbeat_purge_query)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: Error deleting from maxscale_schema.replication_heartbeat table: [%s], %s", - heartbeat_purge_query, - mysql_error(database->con)))); - } + if (mysql_query(database->con, heartbeat_purge_query)) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: Error deleting from maxscale_schema.replication_heartbeat table: [%s], %s", + heartbeat_purge_query, + mysql_error(database->con)))); + } - heartbeat = time(0); + heartbeat = time(0); - /* set node_ts for master as time(0) */ - database->server->node_ts = heartbeat; + /* set node_ts for master as time(0) */ + database->server->node_ts = heartbeat; - sprintf(heartbeat_insert_query, "UPDATE maxscale_schema.replication_heartbeat SET master_timestamp = %lu WHERE master_server_id = %li AND maxscale_id = %lu", heartbeat, handle->master->server->node_id, id); + sprintf(heartbeat_insert_query, "UPDATE maxscale_schema.replication_heartbeat SET master_timestamp = %lu WHERE master_server_id = %li AND maxscale_id = %lu", heartbeat, handle->master->server->node_id, id); - /* Try to insert MaxScale timestamp into master */ - if (mysql_query(database->con, heartbeat_insert_query)) { + /* Try to insert MaxScale timestamp into master */ + if (mysql_query(database->con, heartbeat_insert_query)) + { - database->server->rlag = -1; + database->server->rlag = -1; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: Error updating maxscale_schema.replication_heartbeat table: [%s], %s", - heartbeat_insert_query, - mysql_error(database->con)))); - } else { - if (mysql_affected_rows(database->con) == 0) { - heartbeat = time(0); - sprintf(heartbeat_insert_query, "REPLACE INTO maxscale_schema.replication_heartbeat (master_server_id, maxscale_id, master_timestamp ) VALUES ( %li, %lu, %lu)", handle->master->server->node_id, id, heartbeat); + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: Error updating maxscale_schema.replication_heartbeat table: [%s], %s", + heartbeat_insert_query, + mysql_error(database->con)))); + } + else + { + if (mysql_affected_rows(database->con) == 0) + { + heartbeat = time(0); + sprintf(heartbeat_insert_query, "REPLACE INTO maxscale_schema.replication_heartbeat (master_server_id, maxscale_id, master_timestamp ) VALUES ( %li, %lu, %lu)", handle->master->server->node_id, id, heartbeat); - if (mysql_query(database->con, heartbeat_insert_query)) { + if (mysql_query(database->con, heartbeat_insert_query)) + { - database->server->rlag = -1; + database->server->rlag = -1; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: Error inserting into maxscale_schema.replication_heartbeat table: [%s], %s", - heartbeat_insert_query, - mysql_error(database->con)))); - } else { - /* Set replication lag to 0 for the master */ - database->server->rlag = 0; + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: Error inserting into maxscale_schema.replication_heartbeat table: [%s], %s", + heartbeat_insert_query, + mysql_error(database->con)))); + } + else + { + /* Set replication lag to 0 for the master */ + database->server->rlag = 0; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "[mysql_mon]: heartbeat table inserted data for %s:%i", database->server->name, database->server->port))); - } - } else { - /* Set replication lag as 0 for the master */ - database->server->rlag = 0; + LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, + "[mysql_mon]: heartbeat table inserted data for %s:%i", database->server->name, database->server->port))); + } + } + else + { + /* Set replication lag as 0 for the master */ + database->server->rlag = 0; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "[mysql_mon]: heartbeat table updated for Master %s:%i", database->server->name, database->server->port))); - } - } + LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, + "[mysql_mon]: heartbeat table updated for Master %s:%i", database->server->name, database->server->port))); + } + } } /******* @@ -1203,97 +1235,108 @@ static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *databas * @param handle The monitor handle * @param database The number database server */ -static void set_slave_heartbeat(MONITOR* mon, MONITOR_SERVERS *database) { - MYSQL_MONITOR *handle = (MYSQL_MONITOR*)mon->handle; - unsigned long id = handle->id; - time_t heartbeat; - char select_heartbeat_query[256] = ""; - MYSQL_ROW row; - MYSQL_RES *result; +static void set_slave_heartbeat(MONITOR* mon, MONITOR_SERVERS *database) +{ + MYSQL_MONITOR *handle = (MYSQL_MONITOR*) mon->handle; + unsigned long id = handle->id; + time_t heartbeat; + char select_heartbeat_query[256] = ""; + MYSQL_ROW row; + MYSQL_RES *result; - if (handle->master == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: set_slave_heartbeat called without an available Master server"))); - return; - } + if (handle->master == NULL) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: set_slave_heartbeat called without an available Master server"))); + return; + } - /* Get the master_timestamp value from maxscale_schema.replication_heartbeat table */ + /* Get the master_timestamp value from maxscale_schema.replication_heartbeat table */ - sprintf(select_heartbeat_query, "SELECT master_timestamp " - "FROM maxscale_schema.replication_heartbeat " - "WHERE maxscale_id = %lu AND master_server_id = %li", - id, handle->master->server->node_id); + sprintf(select_heartbeat_query, "SELECT master_timestamp " + "FROM maxscale_schema.replication_heartbeat " + "WHERE maxscale_id = %lu AND master_server_id = %li", + id, handle->master->server->node_id); - /* if there is a master then send the query to the slave with master_id */ - if (handle->master !=NULL && (mysql_query(database->con, select_heartbeat_query) == 0 - && (result = mysql_store_result(database->con)) != NULL)) { - int rows_found = 0; + /* if there is a master then send the query to the slave with master_id */ + if (handle->master != NULL && (mysql_query(database->con, select_heartbeat_query) == 0 + && (result = mysql_store_result(database->con)) != NULL)) + { + int rows_found = 0; - while ((row = mysql_fetch_row(result))) { - int rlag = -1; - time_t slave_read; + while ((row = mysql_fetch_row(result))) + { + int rlag = -1; + time_t slave_read; - rows_found = 1; + rows_found = 1; - heartbeat = time(0); - slave_read = strtoul(row[0], NULL, 10); + heartbeat = time(0); + slave_read = strtoul(row[0], NULL, 10); - if ((errno == ERANGE && (slave_read == LONG_MAX || slave_read == LONG_MIN)) || (errno != 0 && slave_read == 0)) { - slave_read = 0; - } + if ((errno == ERANGE && (slave_read == LONG_MAX || slave_read == LONG_MIN)) || (errno != 0 && slave_read == 0)) + { + slave_read = 0; + } - if (slave_read) { - /* set the replication lag */ - rlag = heartbeat - slave_read; - } + if (slave_read) + { + /* set the replication lag */ + rlag = heartbeat - slave_read; + } - /* set this node_ts as master_timestamp read from replication_heartbeat table */ - database->server->node_ts = slave_read; + /* set this node_ts as master_timestamp read from replication_heartbeat table */ + database->server->node_ts = slave_read; - if (rlag >= 0) { - /* store rlag only if greater than monitor sampling interval */ - database->server->rlag = (rlag > (mon->interval / 1000)) ? rlag : 0; - } else { - database->server->rlag = -1; - } + if (rlag >= 0) + { + /* store rlag only if greater than monitor sampling interval */ + database->server->rlag = (rlag > (mon->interval / 1000)) ? rlag : 0; + } + else + { + database->server->rlag = -1; + } - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "[mysql_mon]: replication heartbeat: " - "Slave %s:%i has %i seconds lag", - database->server->name, - database->server->port, - database->server->rlag))); - } - if (!rows_found) { - database->server->rlag = -1; - database->server->node_ts = 0; - } + LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, + "[mysql_mon]: replication heartbeat: " + "Slave %s:%i has %i seconds lag", + database->server->name, + database->server->port, + database->server->rlag))); + } + if (!rows_found) + { + database->server->rlag = -1; + database->server->node_ts = 0; + } - mysql_free_result(result); - } else { - database->server->rlag = -1; - database->server->node_ts = 0; + mysql_free_result(result); + } + else + { + database->server->rlag = -1; + database->server->node_ts = 0; - if (handle->master->server->node_id < 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: error: replication heartbeat: " - "master_server_id NOT available for %s:%i", - database->server->name, - database->server->port))); - } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "[mysql_mon]: error: replication heartbeat: " - "failed selecting from hearthbeat table of %s:%i : [%s], %s", - database->server->name, - database->server->port, - select_heartbeat_query, - mysql_error(database->con)))); - } - } + if (handle->master->server->node_id < 0) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: error: replication heartbeat: " + "master_server_id NOT available for %s:%i", + database->server->name, + database->server->port))); + } + else + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "[mysql_mon]: error: replication heartbeat: " + "failed selecting from hearthbeat table of %s:%i : [%s], %s", + database->server->name, + database->server->port, + select_heartbeat_query, + mysql_error(database->con)))); + } + } } /******* @@ -1307,107 +1350,133 @@ static void set_slave_heartbeat(MONITOR* mon, MONITOR_SERVERS *database) { * @return The server at root level with SERVER_MASTER bit */ -static MONITOR_SERVERS *get_replication_tree(MONITOR *mon, int num_servers) { - MYSQL_MONITOR* handle = (MYSQL_MONITOR*)mon->handle; - MONITOR_SERVERS *ptr; - MONITOR_SERVERS *backend; - SERVER *current; - int depth=0; - long node_id; - int root_level; +static MONITOR_SERVERS *get_replication_tree(MONITOR *mon, int num_servers) +{ + MYSQL_MONITOR* handle = (MYSQL_MONITOR*) mon->handle; + MONITOR_SERVERS *ptr; + MONITOR_SERVERS *backend; + SERVER *current; + int depth = 0; + long node_id; + int root_level; - ptr = mon->databases; - root_level = num_servers; + ptr = mon->databases; + root_level = num_servers; - while (ptr) - { - /* The server could be in SERVER_IN_MAINT - * that means SERVER_IS_RUNNING returns 0 - * Let's check only for SERVER_IS_DOWN: server is not running - */ - if (SERVER_IS_DOWN(ptr->server)) { - ptr = ptr->next; - continue; - } - depth = 0; - current = ptr->server; + while (ptr) + { + /* The server could be in SERVER_IN_MAINT + * that means SERVER_IS_RUNNING returns 0 + * Let's check only for SERVER_IS_DOWN: server is not running + */ + if (SERVER_IS_DOWN(ptr->server)) + { + ptr = ptr->next; + continue; + } + depth = 0; + current = ptr->server; - node_id = current->master_id; - if (node_id < 1) { - MONITOR_SERVERS *find_slave; - find_slave = getSlaveOfNodeId(mon->databases, current->node_id); + node_id = current->master_id; + if (node_id < 1) + { + MONITOR_SERVERS *find_slave; + find_slave = getSlaveOfNodeId(mon->databases, current->node_id); - if (find_slave == NULL) { - current->depth = -1; - ptr = ptr->next; + if (find_slave == NULL) + { + current->depth = -1; + ptr = ptr->next; - continue; - } else { - current->depth = 0; - } - } else { - depth++; - } + continue; + } + else + { + current->depth = 0; + } + } + else + { + depth++; + } - while(depth <= num_servers) { - /* set the root master at lowest depth level */ - if (current->depth > -1 && current->depth < root_level) { - root_level = current->depth; - handle->master = ptr; - } - backend = getServerByNodeId(mon->databases, node_id); + while (depth <= num_servers) + { + /* set the root master at lowest depth level */ + if (current->depth > -1 && current->depth < root_level) + { + root_level = current->depth; + handle->master = ptr; + } + backend = getServerByNodeId(mon->databases, node_id); - if (backend) { - node_id = backend->server->master_id; - } else { - node_id = -1; - } + if (backend) + { + node_id = backend->server->master_id; + } + else + { + node_id = -1; + } - if (node_id > 0) { - current->depth = depth + 1; - depth++; + if (node_id > 0) + { + current->depth = depth + 1; + depth++; - } else { - MONITOR_SERVERS *master; - current->depth = depth; + } + else + { + MONITOR_SERVERS *master; + current->depth = depth; - master = getServerByNodeId(mon->databases, current->master_id); - if (master && master->server && master->server->node_id > 0) { - add_slave_to_master(master->server->slaves, MONITOR_MAX_NUM_SLAVES, current->node_id); - master->server->depth = current->depth -1; - monitor_set_pending_status(master, SERVER_MASTER); - handle->master = master; - } else { - if (current->master_id > 0) { - /* this server is slave of another server not in MaxScale configuration - * we cannot use it as a real slave. - */ - monitor_clear_pending_status(ptr, SERVER_SLAVE); - monitor_set_pending_status(ptr, SERVER_SLAVE_OF_EXTERNAL_MASTER); - } - } - break; - } + master = getServerByNodeId(mon->databases, current->master_id); + if (master && master->server && master->server->node_id > 0) + { + add_slave_to_master(master->server->slaves, MONITOR_MAX_NUM_SLAVES, current->node_id); + master->server->depth = current->depth - 1; + monitor_set_pending_status(master, SERVER_MASTER); + handle->master = master; + } + else + { + if (current->master_id > 0) + { + /* this server is slave of another server not in MaxScale configuration + * we cannot use it as a real slave. + */ + monitor_clear_pending_status(ptr, SERVER_SLAVE); + monitor_set_pending_status(ptr, SERVER_SLAVE_OF_EXTERNAL_MASTER); + } + } + break; + } - } + } - ptr = ptr->next; - } + ptr = ptr->next; + } - /* - * Return the root master - */ + /* + * Return the root master + */ - if (handle->master != NULL) { - /* If the root master is in MAINT, return NULL */ - if (SERVER_IN_MAINT(handle->master->server)) { - return NULL; - } else { - return handle->master; - } - } else { - return NULL; - } + if (handle->master != NULL) + { + /* If the root master is in MAINT, return NULL */ + if (SERVER_IN_MAINT(handle->master->server)) + { + return NULL; + } + else + { + return handle->master; + } + } + else + { + return NULL; + } } /******* @@ -1419,30 +1488,33 @@ static MONITOR_SERVERS *get_replication_tree(MONITOR *mon, int num_servers) { * @param node_id The node_id of the slave to be inserted * @return 1 for inserted value and 0 otherwise */ -static int add_slave_to_master(long *slaves_list, int list_size, long node_id) { - int i; - for (i = 0; i< list_size; i++) { - if (slaves_list[i] == 0) { - memcpy(&slaves_list[i], &node_id, sizeof(long)); - return 1; - } +static int add_slave_to_master(long *slaves_list, int list_size, long node_id) +{ + for (int i = 0; i < list_size; i++) + { + if (slaves_list[i] == 0) + { + memcpy(&slaves_list[i], &node_id, sizeof(long)); + return 1; } - return 0; + } + return 0; } static monitor_event_t mysql_events[] = { - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - MAX_MONITOR_EVENT + MASTER_DOWN_EVENT, + MASTER_UP_EVENT, + SLAVE_DOWN_EVENT, + SLAVE_UP_EVENT, + SERVER_DOWN_EVENT, + SERVER_UP_EVENT, + LOST_MASTER_EVENT, + LOST_SLAVE_EVENT, + NEW_MASTER_EVENT, + NEW_SLAVE_EVENT, + MAX_MONITOR_EVENT }; + /** * Check if the MySQL monitor is monitoring this event type. * @param event Event to check @@ -1451,10 +1523,10 @@ static monitor_event_t mysql_events[] = { bool isMySQLEvent(monitor_event_t event) { int i; - for(i = 0;mysql_events[i] != MAX_MONITOR_EVENT;i++) + for (i = 0; mysql_events[i] != MAX_MONITOR_EVENT; i++) { - if(event == mysql_events[i]) - return true; + if (event == mysql_events[i]) + return true; } return false; } @@ -1593,7 +1665,6 @@ bool check_replicate_wild_do_table(MONITOR_SERVERS* database) return rval; } - /** * Check if replicate_wild_ignore_table is defined and if it matches * maxscale_schema.replication_heartbeat. From 6dea82631d6b283f397f56d4347f423ca8555af4 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 13:29:12 +0200 Subject: [PATCH 166/179] Galeramon formatting changes Fixed indentation, bracket alignment and other minor things. --- server/modules/monitor/galeramon.c | 893 +++++++++++++++-------------- 1 file changed, 470 insertions(+), 423 deletions(-) diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index c986943f9..6755294e6 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -44,29 +44,29 @@ #include #include -static void monitorMain(void *); +static void monitorMain(void *); static char *version_str = "V2.0.0"; -MODULE_INFO info = { - MODULE_API_MONITOR, - MODULE_GA, - MONITOR_VERSION, - "A Galera cluster monitor" +MODULE_INFO info = { + MODULE_API_MONITOR, + MODULE_GA, + MONITOR_VERSION, + "A Galera cluster monitor" }; -static void *startMonitor(void *,void*); -static void stopMonitor(void *); -static void diagnostics(DCB *, void *); -static MONITOR_SERVERS *get_candidate_master(MONITOR*); -static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *, MONITOR_SERVERS *, int); -static void disableMasterFailback(void *, int); +static void *startMonitor(void *, void*); +static void stopMonitor(void *); +static void diagnostics(DCB *, void *); +static MONITOR_SERVERS *get_candidate_master(MONITOR*); +static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *, MONITOR_SERVERS *, int); +static void disableMasterFailback(void *, int); bool isGaleraEvent(monitor_event_t event); -static MONITOR_OBJECT MyObject = { - startMonitor, - stopMonitor, - diagnostics +static MONITOR_OBJECT MyObject = { + startMonitor, + stopMonitor, + diagnostics }; /** @@ -77,7 +77,7 @@ static MONITOR_OBJECT MyObject = { char * version() { - return version_str; + return version_str; } /** @@ -87,10 +87,9 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise the MySQL Galera Monitor module %s.\n", - version_str))); + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, + "Initialise the MySQL Galera Monitor module %s.\n", + version_str))); } /** @@ -104,7 +103,7 @@ ModuleInit() MONITOR_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -114,79 +113,94 @@ GetModuleObject() * * @return A handle to use when interacting with the monitor */ -static void * -startMonitor(void *arg,void* opt) +static void * +startMonitor(void *arg, void* opt) { MONITOR* mon = arg; GALERA_MONITOR *handle = mon->handle; - CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - bool have_events = false,script_error = false; + CONFIG_PARAMETER* params = (CONFIG_PARAMETER*) opt; + bool have_events = false, script_error = false; if (handle != NULL) { - handle->shutdown = 0; + handle->shutdown = 0; } else { - if ((handle = (GALERA_MONITOR *)malloc(sizeof(GALERA_MONITOR))) == NULL) - return NULL; - handle->shutdown = 0; - handle->id = MONITOR_DEFAULT_ID; - handle->disableMasterFailback = 0; - handle->availableWhenDonor = 0; - handle->disableMasterRoleSetting = 0; - handle->master = NULL; - handle->script = NULL; - handle->use_priority = false; - memset(handle->events,false,sizeof(handle->events)); - spinlock_init(&handle->lock); + if ((handle = (GALERA_MONITOR *) malloc(sizeof(GALERA_MONITOR))) == NULL) + { + return NULL; + } + handle->shutdown = 0; + handle->id = MONITOR_DEFAULT_ID; + handle->disableMasterFailback = 0; + handle->availableWhenDonor = 0; + handle->disableMasterRoleSetting = 0; + handle->master = NULL; + handle->script = NULL; + handle->use_priority = false; + memset(handle->events, false, sizeof(handle->events)); + spinlock_init(&handle->lock); } - while(params) + while (params) { - if(!strcmp(params->name,"disable_master_failback")) - handle->disableMasterFailback = config_truth_value(params->value); - else if(!strcmp(params->name,"available_when_donor")) - handle->availableWhenDonor = config_truth_value(params->value); - else if(!strcmp(params->name,"disable_master_role_setting")) - handle->disableMasterRoleSetting = config_truth_value(params->value); - else if(!strcmp(params->name,"use_priority")) - handle->use_priority = config_truth_value(params->value); - else if(!strcmp(params->name,"script")) - { - if (externcmd_can_execute(params->value)) + if (!strcmp(params->name, "disable_master_failback")) { - free(handle->script); - handle->script = strdup(params->value); + handle->disableMasterFailback = config_truth_value(params->value); } - else + else if (!strcmp(params->name, "available_when_donor")) { - script_error = true; + handle->availableWhenDonor = config_truth_value(params->value); } - } - else if(!strcmp(params->name,"events")) - { - if(mon_parse_event_string((bool*)&handle->events,sizeof(handle->events),params->value) != 0) - script_error = true; - else - have_events = true; - } - params = params->next; + else if (!strcmp(params->name, "disable_master_role_setting")) + { + handle->disableMasterRoleSetting = config_truth_value(params->value); + } + else if (!strcmp(params->name, "use_priority")) + { + handle->use_priority = config_truth_value(params->value); + } + else if (!strcmp(params->name, "script")) + { + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } + } + else if (!strcmp(params->name, "events")) + { + if (mon_parse_event_string((bool*) & handle->events, + sizeof(handle->events), params->value) != 0) + { + script_error = true; + } + else + { + have_events = true; + } + } + params = params->next; } - if(script_error) + if (script_error) { - skygw_log_write(LE,"Error: Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.",mon->name); - free(handle->script); - handle->script = NULL; + skygw_log_write(LE, "Error: Errors were found in the script configuration parameters " + "for the monitor '%s'. The script will not be used.", mon->name); + free(handle->script); + handle->script = NULL; } /** If no specific events are given, enable them all */ - if(!have_events) + if (!have_events) { - memset(handle->events,true,sizeof(handle->events)); + memset(handle->events, true, sizeof(handle->events)); } - handle->tid = (THREAD)thread_start(monitorMain, mon); + handle->tid = (THREAD) thread_start(monitorMain, mon); return handle; } @@ -195,14 +209,14 @@ startMonitor(void *arg,void* opt) * * @param arg Handle on thr running monior */ -static void +static void stopMonitor(void *arg) { - MONITOR* mon = (MONITOR*)arg; -GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; + MONITOR* mon = (MONITOR*) arg; + GALERA_MONITOR *handle = (GALERA_MONITOR *) mon->handle; - handle->shutdown = 1; - thread_wait((void *)handle->tid); + handle->shutdown = 1; + thread_wait((void *) handle->tid); } /** @@ -214,42 +228,42 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; static void diagnostics(DCB *dcb, void *arg) { - MONITOR* mon = (MONITOR*)arg; -GALERA_MONITOR *handle = (GALERA_MONITOR *)mon->handle; -MONITOR_SERVERS *db; -char *sep; + MONITOR* mon = (MONITOR*) arg; + GALERA_MONITOR *handle = (GALERA_MONITOR *) mon->handle; + MONITOR_SERVERS *db; + char *sep; - switch (handle->status) - { - case MONITOR_RUNNING: - dcb_printf(dcb, "\tMonitor running\n"); - break; - case MONITOR_STOPPING: - dcb_printf(dcb, "\tMonitor stopping\n"); - break; - case MONITOR_STOPPED: - dcb_printf(dcb, "\tMonitor stopped\n"); - break; - } + switch (handle->status) + { + case MONITOR_RUNNING: + dcb_printf(dcb, "\tMonitor running\n"); + break; + case MONITOR_STOPPING: + dcb_printf(dcb, "\tMonitor stopping\n"); + break; + case MONITOR_STOPPED: + dcb_printf(dcb, "\tMonitor stopped\n"); + break; + } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); - dcb_printf(dcb,"\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on"); - dcb_printf(dcb,"\tAvailable when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off"); - dcb_printf(dcb,"\tMaster Role Setting Disabled:\t%s\n", (handle->disableMasterRoleSetting == 1) ? "on" : "off"); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); - dcb_printf(dcb, "\tMonitored servers: "); + dcb_printf(dcb, "\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb, "\tMaster Failback:\t%s\n", (handle->disableMasterFailback == 1) ? "off" : "on"); + dcb_printf(dcb, "\tAvailable when Donor:\t%s\n", (handle->availableWhenDonor == 1) ? "on" : "off"); + dcb_printf(dcb, "\tMaster Role Setting Disabled:\t%s\n", (handle->disableMasterRoleSetting == 1) ? "on" : "off"); + dcb_printf(dcb, "\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb, "\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb, "\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); + dcb_printf(dcb, "\tMonitored servers: "); - db = mon->databases; - sep = ""; - while (db) - { - dcb_printf(dcb, "%s%s:%d", sep, db->server->name, db->server->port); - sep = ", "; - db = db->next; - } - dcb_printf(dcb, "\n"); + db = mon->databases; + sep = ""; + while (db) + { + dcb_printf(dcb, "%s%s:%d", sep, db->server->name, db->server->port); + sep = ", "; + db = db->next; + } + dcb_printf(dcb, "\n"); } /** @@ -261,19 +275,19 @@ char *sep; static void monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) { - GALERA_MONITOR* handle = (GALERA_MONITOR*)mon->handle; -MYSQL_ROW row; -MYSQL_RES *result,*result2; -int isjoined = 0; -unsigned long int server_version = 0; -char *server_string; + GALERA_MONITOR* handle = (GALERA_MONITOR*) mon->handle; + MYSQL_ROW row; + MYSQL_RES *result, *result2; + int isjoined = 0; + unsigned long int server_version = 0; + char *server_string; - /* Don't even probe server flagged as in maintenance */ - if (SERVER_IN_MAINT(database->server)) - return; + /* Don't even probe server flagged as in maintenance */ + if (SERVER_IN_MAINT(database->server)) + return; - /** Store previous status */ - database->mon_prev_status = database->server->status; + /** Store previous status */ + database->mon_prev_status = database->server->status; server_clear_status(database->server, SERVER_RUNNING); @@ -305,89 +319,94 @@ char *server_string; return; } - /* If we get this far then we have a working connection */ - server_set_status(database->server, SERVER_RUNNING); + /* If we get this far then we have a working connection */ + server_set_status(database->server, SERVER_RUNNING); - /* get server version string */ - server_string = (char *)mysql_get_server_info(database->con); + /* get server version string */ + server_string = (char *) mysql_get_server_info(database->con); if (server_string) { server_set_version_string(database->server, server_string); } - /* Check if the the Galera FSM shows this node is joined to the cluster */ - if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW STATUS LIKE 'wsrep_local_state'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } + /* Check if the the Galera FSM shows this node is joined to the cluster */ + if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_state'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW STATUS LIKE 'wsrep_local_state'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - if (strcmp(row[1], "4") == 0) - isjoined = 1; - - /* Check if the node is a donor and is using xtrabackup, in this case it can stay alive */ - else if (strcmp(row[1], "2") == 0 && handle->availableWhenDonor == 1) { - if (mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0 - && (result2 = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - mysql_free_result(result2); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW VARIABLES LIKE 'wsrep_sst_method'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } - while ((row = mysql_fetch_row(result2))) - { - if (strncmp(row[1], "xtrabackup", 10) == 0) - isjoined = 1; - } - mysql_free_result(result2); - } - } - } - mysql_free_result(result); - } + while ((row = mysql_fetch_row(result))) + { + if (strcmp(row[1], "4") == 0) + isjoined = 1; - /* Check the the Galera node index in the cluster */ - if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_index'") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - long local_index = -1; + /* Check if the node is a donor and is using xtrabackup, in this case it can stay alive */ + else if (strcmp(row[1], "2") == 0 && handle->availableWhenDonor == 1) + { + if (mysql_query(database->con, "SHOW VARIABLES LIKE 'wsrep_sst_method'") == 0 + && (result2 = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + mysql_free_result(result2); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW VARIABLES LIKE 'wsrep_sst_method'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } + while ((row = mysql_fetch_row(result2))) + { + if (strncmp(row[1], "xtrabackup", 10) == 0) + isjoined = 1; + } + mysql_free_result(result2); + } + } + } + mysql_free_result(result); + } - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW STATUS LIKE 'wsrep_local_index'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } + /* Check the the Galera node index in the cluster */ + if (mysql_query(database->con, "SHOW STATUS LIKE 'wsrep_local_index'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + long local_index = -1; - while ((row = mysql_fetch_row(result))) - { - local_index = strtol(row[1], NULL, 10); - if ((errno == ERANGE && (local_index == LONG_MAX - || local_index == LONG_MIN)) || (errno != 0 && local_index == 0)) - { - local_index = -1; - } - database->server->node_id = local_index; - } - mysql_free_result(result); - } + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW STATUS LIKE 'wsrep_local_index'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } - if (isjoined) - server_set_status(database->server, SERVER_JOINED); - else - server_clear_status(database->server, SERVER_JOINED); + while ((row = mysql_fetch_row(result))) + { + local_index = strtol(row[1], NULL, 10); + if ((errno == ERANGE && (local_index == LONG_MAX + || local_index == LONG_MIN)) || (errno != 0 && local_index == 0)) + { + local_index = -1; + } + database->server->node_id = local_index; + } + mysql_free_result(result); + } + + if (isjoined) + { + server_set_status(database->server, SERVER_JOINED); + } + else + { + server_clear_status(database->server, SERVER_JOINED); + } } /** @@ -398,205 +417,217 @@ char *server_string; static void monitorMain(void *arg) { - MONITOR* mon = (MONITOR*)arg; -GALERA_MONITOR *handle; -MONITOR_SERVERS *ptr; -size_t nrounds = 0; -MONITOR_SERVERS *candidate_master = NULL; -int master_stickiness; -int is_cluster=0; -int log_no_members = 1; -monitor_event_t evtype; + MONITOR* mon = (MONITOR*) arg; + GALERA_MONITOR *handle; + MONITOR_SERVERS *ptr; + size_t nrounds = 0; + MONITOR_SERVERS *candidate_master = NULL; + int master_stickiness; + int is_cluster = 0; + int log_no_members = 1; + monitor_event_t evtype; spinlock_acquire(&mon->lock); - handle = (GALERA_MONITOR *)mon->handle; + handle = (GALERA_MONITOR *) mon->handle; spinlock_release(&mon->lock); master_stickiness = handle->disableMasterFailback; - if (mysql_thread_init()) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Fatal : mysql_thread_init failed in monitor " - "module. Exiting.\n"))); - return; - } - handle->status = MONITOR_RUNNING; - - while (1) - { - if (handle->shutdown) - { - handle->status = MONITOR_STOPPING; - mysql_thread_end(); - handle->status = MONITOR_STOPPED; - return; - } - /** Wait base interval */ - thread_millisleep(MON_BASE_INTERVAL_MS); - /** - * Calculate how far away the monitor interval is from its full - * cycle and if monitor interval time further than the base - * interval, then skip monitoring checks. Excluding the first - * round. - */ + if (mysql_thread_init()) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Fatal : mysql_thread_init failed in monitor " + "module. Exiting.\n"))); + return; + } + handle->status = MONITOR_RUNNING; - if (nrounds != 0 && ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= MON_BASE_INTERVAL_MS) - { - nrounds += 1; - continue; - } + while (1) + { + if (handle->shutdown) + { + handle->status = MONITOR_STOPPING; + mysql_thread_end(); + handle->status = MONITOR_STOPPED; + return; + } + /** Wait base interval */ + thread_millisleep(MON_BASE_INTERVAL_MS); + /** + * Calculate how far away the monitor interval is from its full + * cycle and if monitor interval time further than the base + * interval, then skip monitoring checks. Excluding the first + * round. + */ - nrounds += 1; + if (nrounds != 0 && ((nrounds * MON_BASE_INTERVAL_MS) % mon->interval) >= MON_BASE_INTERVAL_MS) + { + nrounds += 1; + continue; + } - /* reset cluster members counter */ - is_cluster=0; + nrounds += 1; - ptr = mon->databases; + /* reset cluster members counter */ + is_cluster = 0; - while (ptr) - { - ptr->mon_prev_status = ptr->server->status; + ptr = mon->databases; - monitorDatabase(mon, ptr); + while (ptr) + { + ptr->mon_prev_status = ptr->server->status; - /* clear bits for non member nodes */ - if ( ! SERVER_IN_MAINT(ptr->server) && (! SERVER_IS_JOINED(ptr->server))) { - ptr->server->depth = -1; + monitorDatabase(mon, ptr); - /* clear M/S status */ - server_clear_status(ptr->server, SERVER_SLAVE); - server_clear_status(ptr->server, SERVER_MASTER); - - /* clear master sticky status */ - server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); - } + /* clear bits for non member nodes */ + if (!SERVER_IN_MAINT(ptr->server) && (!SERVER_IS_JOINED(ptr->server))) + { + ptr->server->depth = -1; - /* Log server status change */ - if (mon_status_changed(ptr)) - { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Backend server %s:%d state : %s", - ptr->server->name, - ptr->server->port, - STRSRVSTATUS(ptr->server)))); - } - - if (!(SERVER_IS_RUNNING(ptr->server)) || - !(SERVER_IS_IN_CLUSTER(ptr->server))) - { - dcb_hangup_foreach(ptr->server); - } + /* clear M/S status */ + server_clear_status(ptr->server, SERVER_SLAVE); + server_clear_status(ptr->server, SERVER_MASTER); - if (SERVER_IS_DOWN(ptr->server)) - { - /** Increase this server'e error count */ - dcb_hangup_foreach(ptr->server); - ptr->mon_err_count += 1; + /* clear master sticky status */ + server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); + } - } - else - { - /** Reset this server's error count */ - ptr->mon_err_count = 0; - } + /* Log server status change */ + if (mon_status_changed(ptr)) + { + LOGIF(LD, (skygw_log_write_flush(LOGFILE_DEBUG, + "Backend server %s:%d state : %s", + ptr->server->name, + ptr->server->port, + STRSRVSTATUS(ptr->server)))); + } - ptr = ptr->next; - } + if (!(SERVER_IS_RUNNING(ptr->server)) || + !(SERVER_IS_IN_CLUSTER(ptr->server))) + { + dcb_hangup_foreach(ptr->server); + } - /* - * Let's select a master server: - * it could be the candidate master following MIN(node_id) rule or - * the server that was master in the previous monitor polling cycle - * Decision depends on master_stickiness value set in configuration - */ + if (SERVER_IS_DOWN(ptr->server)) + { + /** Increase this server'e error count */ + dcb_hangup_foreach(ptr->server); + ptr->mon_err_count += 1; - /* get the candidate master, following MIN(node_id) rule */ - candidate_master = get_candidate_master(mon); + } + else + { + /** Reset this server's error count */ + ptr->mon_err_count = 0; + } - /* Select the master, based on master_stickiness */ - if (1 == handle->disableMasterRoleSetting) { - handle->master = NULL; + ptr = ptr->next; + } + + /* + * Let's select a master server: + * it could be the candidate master following MIN(node_id) rule or + * the server that was master in the previous monitor polling cycle + * Decision depends on master_stickiness value set in configuration + */ + + /* get the candidate master, following MIN(node_id) rule */ + candidate_master = get_candidate_master(mon); + + /* Select the master, based on master_stickiness */ + if (1 == handle->disableMasterRoleSetting) + { + handle->master = NULL; + } + else + { + handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness); + } + + ptr = mon->databases; + + while (ptr) + { + if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) + { + ptr = ptr->next; + continue; + } + + if (handle->master) + { + if (ptr != handle->master) + { + /* set the Slave role */ + server_set_status(ptr->server, SERVER_SLAVE); + server_clear_status(ptr->server, SERVER_MASTER); + + /* clear master stickiness */ + server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); } - else { - handle->master = set_cluster_master(handle->master, candidate_master, master_stickiness); + else + { + /* set the Master role */ + server_set_status(handle->master->server, SERVER_MASTER); + server_clear_status(handle->master->server, SERVER_SLAVE); + + if (candidate_master && handle->master->server->node_id != candidate_master->server->node_id) + { + /* set master stickiness */ + server_set_status(handle->master->server, SERVER_MASTER_STICKINESS); + } + else + { + /* clear master stickiness */ + server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); + } } + } - ptr = mon->databases; + is_cluster++; - while (ptr) { - if (!SERVER_IS_JOINED(ptr->server) || SERVER_IN_MAINT(ptr->server)) { - ptr = ptr->next; - continue; - } + ptr = ptr->next; + } - if (handle->master) { - if (ptr != handle->master) { - /* set the Slave role */ - server_set_status(ptr->server, SERVER_SLAVE); - server_clear_status(ptr->server, SERVER_MASTER); - - /* clear master stickiness */ - server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); - } else { - /* set the Master role */ - server_set_status(handle->master->server, SERVER_MASTER); - server_clear_status(handle->master->server, SERVER_SLAVE); - - if (candidate_master && handle->master->server->node_id != candidate_master->server->node_id) { - /* set master stickiness */ - server_set_status(handle->master->server, SERVER_MASTER_STICKINESS); - } else { - /* clear master stickiness */ - server_clear_status(ptr->server, SERVER_MASTER_STICKINESS); - } - } - } - - is_cluster++; - - ptr = ptr->next; - } - - if (is_cluster == 0 && log_no_members) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: there are no cluster members"))); - log_no_members = 0; - } else { - if (is_cluster > 0 && log_no_members == 0) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Info: found cluster members"))); - log_no_members = 1; - } - } + if (is_cluster == 0 && log_no_members) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Error: there are no cluster members"))); + log_no_members = 0; + } + else + { + if (is_cluster > 0 && log_no_members == 0) + { + LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, + "Info: found cluster members"))); + log_no_members = 1; + } + } - ptr = mon->databases; + ptr = mon->databases; - while(ptr) - { + while (ptr) + { - /** Execute monitor script if a server state has changed */ - if(mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if(isGaleraEvent(evtype)) - { - skygw_log_write(LOGFILE_TRACE,"Server changed state: %s[%s:%u]: %s", - ptr->server->unique_name, - ptr->server->name,ptr->server->port, - mon_get_event_name(ptr)); - if(handle->script && handle->events[evtype]) - { - monitor_launch_script(mon,ptr,handle->script); - } - } - } - ptr = ptr->next; - } - } + /** Execute monitor script if a server state has changed */ + if (mon_status_changed(ptr)) + { + evtype = mon_get_event_type(ptr); + if (isGaleraEvent(evtype)) + { + skygw_log_write(LOGFILE_TRACE, "Server changed state: %s[%s:%u]: %s", + ptr->server->unique_name, + ptr->server->name, ptr->server->port, + mon_get_event_name(ptr)); + if (handle->script && handle->events[evtype]) + { + monitor_launch_script(mon, ptr, handle->script); + } + } + } + ptr = ptr->next; + } + } } /** @@ -608,45 +639,50 @@ monitor_event_t evtype; * @param servers The monitored servers list * @return The candidate master on success, NULL on failure */ -static MONITOR_SERVERS *get_candidate_master(MONITOR* mon) { - MONITOR_SERVERS *moitor_servers = mon->databases; - MONITOR_SERVERS *candidate_master = NULL; - GALERA_MONITOR* handle = mon->handle; - long min_id = -1; - int minval = INT_MAX; - int currval; - char* value; - /* set min_id to the lowest value of moitor_servers->server->node_id */ - while(moitor_servers) { - if (!SERVER_IN_MAINT(moitor_servers->server) && SERVER_IS_JOINED(moitor_servers->server)) { +static MONITOR_SERVERS *get_candidate_master(MONITOR* mon) +{ + MONITOR_SERVERS *moitor_servers = mon->databases; + MONITOR_SERVERS *candidate_master = NULL; + GALERA_MONITOR* handle = mon->handle; + long min_id = -1; + int minval = INT_MAX; + int currval; + char* value; + /* set min_id to the lowest value of moitor_servers->server->node_id */ + while (moitor_servers) + { + if (!SERVER_IN_MAINT(moitor_servers->server) && SERVER_IS_JOINED(moitor_servers->server)) + { - moitor_servers->server->depth = 0; + moitor_servers->server->depth = 0; - if(handle->use_priority && (value = serverGetParameter(moitor_servers->server,"priority")) != NULL) - { - currval = atoi(value); - if(currval < minval && currval > 0) - { - minval = currval; - candidate_master = moitor_servers; - } - } - else if(moitor_servers->server->node_id >= 0 && - (!handle->use_priority || /** Server priority disabled*/ - candidate_master == NULL || /** No candidate chosen */ - serverGetParameter(candidate_master->server,"priority") == NULL)) /** Candidate has no priority */ - { - if (min_id < 0 || moitor_servers->server->node_id < min_id) { - min_id = moitor_servers->server->node_id; - candidate_master = moitor_servers; - } - } - } - moitor_servers = moitor_servers->next; - } + if (handle->use_priority && (value = serverGetParameter(moitor_servers->server, "priority")) != NULL) + { + currval = atoi(value); + if (currval < minval && currval > 0) + { + minval = currval; + candidate_master = moitor_servers; + } + } + else if (moitor_servers->server->node_id >= 0 && + (!handle->use_priority || /** Server priority disabled*/ + candidate_master == NULL || /** No candidate chosen */ + serverGetParameter(candidate_master->server, "priority") == NULL)) /** Candidate has no priority */ + { + if (min_id < 0 || moitor_servers->server->node_id < min_id) + { + min_id = moitor_servers->server->node_id; + candidate_master = moitor_servers; + } + } + } + moitor_servers = moitor_servers->next; + } - return candidate_master; + return candidate_master; } + /** * set the master server in the cluster * @@ -661,23 +697,31 @@ static MONITOR_SERVERS *get_candidate_master(MONITOR* mon) { * @param candidate_master The candidate master server accordingly to the selection rule * @return The master node pointer (could be NULL) */ -static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *current_master, MONITOR_SERVERS *candidate_master, int master_stickiness) { - /* - * if current master is not set or master_stickiness is not enable - * just return candidate_master. - */ - if (current_master == NULL || master_stickiness == 0) { - return candidate_master; - } else { - /* - * if current_master is still a cluster member use it - * - */ - if (SERVER_IS_JOINED(current_master->server) && (! SERVER_IN_MAINT(current_master->server))) { - return current_master; - } else - return candidate_master; - } +static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *current_master, MONITOR_SERVERS *candidate_master, int master_stickiness) +{ + /* + * if current master is not set or master_stickiness is not enable + * just return candidate_master. + */ + if (current_master == NULL || master_stickiness == 0) + { + return candidate_master; + } + else + { + /* + * if current_master is still a cluster member use it + * + */ + if (SERVER_IS_JOINED(current_master->server) && (!SERVER_IN_MAINT(current_master->server))) + { + return current_master; + } + else + { + return candidate_master; + } + } } /** @@ -694,8 +738,8 @@ static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *current_master, MONI static void disableMasterFailback(void *arg, int disable) { -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; - memcpy(&handle->disableMasterFailback, &disable, sizeof(int)); + GALERA_MONITOR *handle = (GALERA_MONITOR *) arg; + memcpy(&handle->disableMasterFailback, &disable, sizeof(int)); } /** @@ -710,8 +754,8 @@ GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; static void availableWhenDonor(void *arg, int disable) { -GALERA_MONITOR *handle = (GALERA_MONITOR *)arg; - memcpy(&handle->availableWhenDonor, &disable, sizeof(int)); + GALERA_MONITOR *handle = (GALERA_MONITOR *) arg; + memcpy(&handle->availableWhenDonor, &disable, sizeof(int)); } static monitor_event_t galera_events[] = { @@ -735,6 +779,7 @@ static monitor_event_t galera_events[] = { NEW_DONOR_EVENT, MAX_MONITOR_EVENT }; + /** * Check if the Galera monitor is monitoring this event type. * @param event Event to check @@ -743,10 +788,12 @@ static monitor_event_t galera_events[] = { bool isGaleraEvent(monitor_event_t event) { int i; - for(i = 0;galera_events[i] != MAX_MONITOR_EVENT;i++) + for (i = 0; galera_events[i] != MAX_MONITOR_EVENT; i++) { - if(event == galera_events[i]) - return true; + if (event == galera_events[i]) + { + return true; + } } return false; } From f9c99761d680994957ce292ec09fff79a2853125 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 13:37:32 +0200 Subject: [PATCH 167/179] Monitor_common formatting changes Cleaned up monitor_common.c and monitor_common.h --- server/modules/monitor/monitor_common.c | 428 +++++++++++++----------- server/modules/monitor/monitor_common.h | 59 ++-- 2 files changed, 267 insertions(+), 220 deletions(-) diff --git a/server/modules/monitor/monitor_common.c b/server/modules/monitor/monitor_common.c index c3180d188..8638fd2c1 100644 --- a/server/modules/monitor/monitor_common.c +++ b/server/modules/monitor/monitor_common.c @@ -29,7 +29,7 @@ monitor_event_t mon_name_to_event(char* tok); */ void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit) { - ptr->pending_status |= bit; + ptr->pending_status |= bit; } /** @@ -40,103 +40,102 @@ void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit) */ void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) { - ptr->pending_status &= ~bit; + ptr->pending_status &= ~bit; } - - monitor_event_t mon_get_event_type(MONITOR_SERVERS* node) +monitor_event_t mon_get_event_type(MONITOR_SERVERS* node) { unsigned int prev = node->mon_prev_status; - if((prev & (SERVER_MASTER|SERVER_RUNNING)) == (SERVER_MASTER|SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) + if ((prev & (SERVER_MASTER | SERVER_RUNNING)) == (SERVER_MASTER | SERVER_RUNNING) && + SERVER_IS_DOWN(node->server)) { - return MASTER_DOWN_EVENT; + return MASTER_DOWN_EVENT; } - if((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) + if ((prev & (SERVER_RUNNING)) == 0 && + SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) { - return MASTER_UP_EVENT; + return MASTER_UP_EVENT; } - if((prev & (SERVER_SLAVE|SERVER_RUNNING)) == (SERVER_SLAVE|SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) + if ((prev & (SERVER_SLAVE | SERVER_RUNNING)) == (SERVER_SLAVE | SERVER_RUNNING) && + SERVER_IS_DOWN(node->server)) { - return SLAVE_DOWN_EVENT; + return SLAVE_DOWN_EVENT; } - if((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) + if ((prev & (SERVER_RUNNING)) == 0 && + SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) { - return SLAVE_UP_EVENT; + return SLAVE_UP_EVENT; } /** Galera specific events */ - if((prev & (SERVER_JOINED|SERVER_RUNNING)) == (SERVER_JOINED|SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) + if ((prev & (SERVER_JOINED | SERVER_RUNNING)) == (SERVER_JOINED | SERVER_RUNNING) && + SERVER_IS_DOWN(node->server)) { - return SYNCED_DOWN_EVENT; + return SYNCED_DOWN_EVENT; } - if((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_JOINED(node->server)) + if ((prev & (SERVER_RUNNING)) == 0 && + SERVER_IS_RUNNING(node->server) && SERVER_IS_JOINED(node->server)) { - return SYNCED_UP_EVENT; + return SYNCED_UP_EVENT; } /** NDB events*/ - if((prev & (SERVER_NDB|SERVER_RUNNING)) == (SERVER_NDB|SERVER_RUNNING) && - SERVER_IS_DOWN(node->server)) + if ((prev & (SERVER_NDB | SERVER_RUNNING)) == (SERVER_NDB | SERVER_RUNNING) && + SERVER_IS_DOWN(node->server)) { - return NDB_DOWN_EVENT; + return NDB_DOWN_EVENT; } - if((prev & (SERVER_RUNNING)) == 0 && - SERVER_IS_RUNNING(node->server) && SERVER_IS_NDB(node->server)) + if ((prev & (SERVER_RUNNING)) == 0 && + SERVER_IS_RUNNING(node->server) && SERVER_IS_NDB(node->server)) { - return NDB_UP_EVENT; + return NDB_UP_EVENT; } - if((prev & (SERVER_RUNNING)) == SERVER_RUNNING && - SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) + if ((prev & (SERVER_RUNNING)) == SERVER_RUNNING && + SERVER_IS_RUNNING(node->server) && SERVER_IS_MASTER(node->server)) { - return NEW_MASTER_EVENT; + return NEW_MASTER_EVENT; } - if((prev & (SERVER_RUNNING)) == SERVER_RUNNING && - SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) + if ((prev & (SERVER_RUNNING)) == SERVER_RUNNING && + SERVER_IS_RUNNING(node->server) && SERVER_IS_SLAVE(node->server)) { - return NEW_SLAVE_EVENT; + return NEW_SLAVE_EVENT; } /** Status loss events */ - if((prev & (SERVER_RUNNING|SERVER_MASTER)) == (SERVER_RUNNING|SERVER_MASTER) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_MASTER(node->server)) + if ((prev & (SERVER_RUNNING | SERVER_MASTER)) == (SERVER_RUNNING | SERVER_MASTER) && + SERVER_IS_RUNNING(node->server) && !SERVER_IS_MASTER(node->server)) { - return LOST_MASTER_EVENT; + return LOST_MASTER_EVENT; } - if((prev & (SERVER_RUNNING|SERVER_SLAVE)) == (SERVER_RUNNING|SERVER_SLAVE) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_SLAVE(node->server)) + if ((prev & (SERVER_RUNNING | SERVER_SLAVE)) == (SERVER_RUNNING | SERVER_SLAVE) && + SERVER_IS_RUNNING(node->server) && !SERVER_IS_SLAVE(node->server)) { - return LOST_SLAVE_EVENT; + return LOST_SLAVE_EVENT; } - if((prev & (SERVER_RUNNING|SERVER_JOINED)) == (SERVER_RUNNING|SERVER_JOINED) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_JOINED(node->server)) + if ((prev & (SERVER_RUNNING | SERVER_JOINED)) == (SERVER_RUNNING | SERVER_JOINED) && + SERVER_IS_RUNNING(node->server) && !SERVER_IS_JOINED(node->server)) { - return LOST_SYNCED_EVENT; + return LOST_SYNCED_EVENT; } - if((prev & (SERVER_RUNNING|SERVER_NDB)) == (SERVER_RUNNING|SERVER_NDB) && - SERVER_IS_RUNNING(node->server) && !SERVER_IS_NDB(node->server)) + if ((prev & (SERVER_RUNNING | SERVER_NDB)) == (SERVER_RUNNING | SERVER_NDB) && + SERVER_IS_RUNNING(node->server) && !SERVER_IS_NDB(node->server)) { - return LOST_NDB_EVENT; + return LOST_NDB_EVENT; } /** Generic server failure */ - if((prev & SERVER_RUNNING) == 0 && - SERVER_IS_RUNNING(node->server)) + if ((prev & SERVER_RUNNING) == 0 && + SERVER_IS_RUNNING(node->server)) { - return SERVER_UP_EVENT; + return SERVER_UP_EVENT; } - if((prev & SERVER_RUNNING) == SERVER_RUNNING && - SERVER_IS_DOWN(node->server)) + if ((prev & SERVER_RUNNING) == SERVER_RUNNING && + SERVER_IS_DOWN(node->server)) { - return SERVER_DOWN_EVENT; + return SERVER_DOWN_EVENT; } /** Something else, most likely a state that does not matter. @@ -147,83 +146,83 @@ void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit) char* mon_get_event_name(MONITOR_SERVERS* node) { - switch(mon_get_event_type(node)) + switch (mon_get_event_type(node)) { -case UNDEFINED_MONITOR_EVENT: - return "undefined"; + case UNDEFINED_MONITOR_EVENT: + return "undefined"; -case MASTER_DOWN_EVENT: - return "master_down"; + case MASTER_DOWN_EVENT: + return "master_down"; -case MASTER_UP_EVENT: - return "master_up"; + case MASTER_UP_EVENT: + return "master_up"; -case SLAVE_DOWN_EVENT: - return "slave_down"; + case SLAVE_DOWN_EVENT: + return "slave_down"; -case SLAVE_UP_EVENT: - return "slave_up"; + case SLAVE_UP_EVENT: + return "slave_up"; -case SERVER_DOWN_EVENT: - return "server_down"; + case SERVER_DOWN_EVENT: + return "server_down"; -case SERVER_UP_EVENT: - return "server_up"; + case SERVER_UP_EVENT: + return "server_up"; -case SYNCED_DOWN_EVENT: - return "synced_down"; + case SYNCED_DOWN_EVENT: + return "synced_down"; -case SYNCED_UP_EVENT: - return "synced_up"; + case SYNCED_UP_EVENT: + return "synced_up"; -case DONOR_DOWN_EVENT: - return "donor_down"; + case DONOR_DOWN_EVENT: + return "donor_down"; -case DONOR_UP_EVENT: - return "donor_up"; + case DONOR_UP_EVENT: + return "donor_up"; -case NDB_DOWN_EVENT: - return "ndb_down"; + case NDB_DOWN_EVENT: + return "ndb_down"; -case NDB_UP_EVENT: - return "ndb_up"; + case NDB_UP_EVENT: + return "ndb_up"; -case LOST_MASTER_EVENT: - return "lost_master"; + case LOST_MASTER_EVENT: + return "lost_master"; -case LOST_SLAVE_EVENT: - return "lost_slave"; + case LOST_SLAVE_EVENT: + return "lost_slave"; -case LOST_SYNCED_EVENT: - return "lost_synced"; + case LOST_SYNCED_EVENT: + return "lost_synced"; -case LOST_DONOR_EVENT: - return "lost_donor"; + case LOST_DONOR_EVENT: + return "lost_donor"; -case LOST_NDB_EVENT: - return "lost_ndb"; + case LOST_NDB_EVENT: + return "lost_ndb"; -case NEW_MASTER_EVENT: - return "new_master"; + case NEW_MASTER_EVENT: + return "new_master"; -case NEW_SLAVE_EVENT: - return "new_slave"; + case NEW_SLAVE_EVENT: + return "new_slave"; -case NEW_SYNCED_EVENT: - return "new_synced"; + case NEW_SYNCED_EVENT: + return "new_synced"; -case NEW_DONOR_EVENT: - return "new_donor"; + case NEW_DONOR_EVENT: + return "new_donor"; - case NEW_NDB_EVENT: - return "new_ndb"; + case NEW_NDB_EVENT: + return "new_ndb"; - default: - return "MONITOR_EVENT_FAILURE"; + default: + return "MONITOR_EVENT_FAILURE"; } - + } /** @@ -240,7 +239,7 @@ void mon_append_node_names(MONITOR_SERVERS* start, char* dest, int len) char arr[MAX_SERVER_NAME_LEN + 32]; // Some extra space for port while (ptr && slen < len) { - if(SERVER_IS_RUNNING(ptr->server)) + if (SERVER_IS_RUNNING(ptr->server)) { if (!first) { @@ -262,23 +261,25 @@ void mon_append_node_names(MONITOR_SERVERS* start, char* dest, int len) * @return true if status has changed or false */ bool mon_status_changed( - MONITOR_SERVERS* mon_srv) + MONITOR_SERVERS* mon_srv) { - bool succp; + bool succp; - /** This is the first time the server was set with a status*/ - if (mon_srv->mon_prev_status == -1) - return false; + /** This is the first time the server was set with a status*/ + if (mon_srv->mon_prev_status == -1) + { + return false; + } - if (mon_srv->mon_prev_status != mon_srv->server->status) - { - succp = true; - } - else - { - succp = false; - } - return succp; + if (mon_srv->mon_prev_status != mon_srv->server->status) + { + succp = true; + } + else + { + succp = false; + } + return succp; } /** @@ -288,20 +289,20 @@ bool mon_status_changed( * @return true if failed status can be logged or false */ bool mon_print_fail_status( - MONITOR_SERVERS* mon_srv) + MONITOR_SERVERS* mon_srv) { - bool succp; - int errcount = mon_srv->mon_err_count; + bool succp; + int errcount = mon_srv->mon_err_count; - if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0) - { - succp = true; - } - else - { - succp = false; - } - return succp; + if (SERVER_IS_DOWN(mon_srv->server) && errcount == 0) + { + succp = true; + } + else + { + succp = false; + } + return succp; } /** @@ -350,26 +351,28 @@ void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script) * @return 0 on success. 1 when an error has occurred or an unexpected event was * found. */ -int mon_parse_event_string(bool* events, size_t count,char* string) +int mon_parse_event_string(bool* events, size_t count, char* string) { - char *tok,*saved; + char *tok, *saved; monitor_event_t event; - tok = strtok_r(string,",| ",&saved); + tok = strtok_r(string, ",| ", &saved); - if(tok == NULL) - return -1; - - while(tok) + if (tok == NULL) { - event = mon_name_to_event(tok); - if(event == UNDEFINED_MONITOR_EVENT) - { - skygw_log_write(LE,"Error: Invalid event name %s",tok); - return -1; - } - events[event] = true; - tok = strtok_r(NULL,",| ",&saved); + return -1; + } + + while (tok) + { + event = mon_name_to_event(tok); + if (event == UNDEFINED_MONITOR_EVENT) + { + skygw_log_write(LE, "Error: Invalid event name %s", tok); + return -1; + } + events[event] = true; + tok = strtok_r(NULL, ",| ", &saved); } return 0; @@ -377,54 +380,97 @@ int mon_parse_event_string(bool* events, size_t count,char* string) monitor_event_t mon_name_to_event(char* tok) { - if(!strcasecmp("master_down",tok)) - return MASTER_DOWN_EVENT; - else if(!strcasecmp("master_up",tok)) - return MASTER_UP_EVENT; - else if(!strcasecmp("slave_down",tok)) - return SLAVE_DOWN_EVENT; - else if(!strcasecmp("slave_up",tok)) - return SLAVE_UP_EVENT; - else if(!strcasecmp("server_down",tok)) - return SERVER_DOWN_EVENT; - else if(!strcasecmp("server_up",tok)) - return SERVER_UP_EVENT; - else if(!strcasecmp("synced_down",tok)) - return SYNCED_DOWN_EVENT; - else if(!strcasecmp("synced_up",tok)) - return SYNCED_UP_EVENT; - else if(!strcasecmp("donor_down",tok)) - return DONOR_DOWN_EVENT; - else if(!strcasecmp("donor_up",tok)) - return DONOR_UP_EVENT; - else if(!strcasecmp("ndb_down",tok)) - return NDB_DOWN_EVENT; - else if(!strcasecmp("ndb_up",tok)) - return NDB_UP_EVENT; - else if(!strcasecmp("lost_master",tok)) - return LOST_MASTER_EVENT; - else if(!strcasecmp("lost_slave",tok)) - return LOST_SLAVE_EVENT; - else if(!strcasecmp("lost_synced",tok)) - return LOST_SYNCED_EVENT; - else if(!strcasecmp("lost_donor",tok)) - return LOST_DONOR_EVENT; - else if(!strcasecmp("lost_ndb",tok)) - return LOST_NDB_EVENT; - else if(!strcasecmp("new_master",tok)) - return NEW_MASTER_EVENT; - else if(!strcasecmp("new_slave",tok)) - return NEW_SLAVE_EVENT; - else if(!strcasecmp("new_synced",tok)) - return NEW_SYNCED_EVENT; - else if(!strcasecmp("new_donor",tok)) - return NEW_DONOR_EVENT; - else if(!strcasecmp("new_ndb",tok)) - return NEW_NDB_EVENT; - else - return UNDEFINED_MONITOR_EVENT; - + if (!strcasecmp("master_down", tok)) + { + return MASTER_DOWN_EVENT; } + else if (!strcasecmp("master_up", tok)) + { + return MASTER_UP_EVENT; + } + else if (!strcasecmp("slave_down", tok)) + { + return SLAVE_DOWN_EVENT; + } + else if (!strcasecmp("slave_up", tok)) + { + return SLAVE_UP_EVENT; + } + else if (!strcasecmp("server_down", tok)) + { + return SERVER_DOWN_EVENT; + } + else if (!strcasecmp("server_up", tok)) + { + return SERVER_UP_EVENT; + } + else if (!strcasecmp("synced_down", tok)) + { + return SYNCED_DOWN_EVENT; + } + else if (!strcasecmp("synced_up", tok)) + { + return SYNCED_UP_EVENT; + } + else if (!strcasecmp("donor_down", tok)) + { + return DONOR_DOWN_EVENT; + } + else if (!strcasecmp("donor_up", tok)) + { + return DONOR_UP_EVENT; + } + else if (!strcasecmp("ndb_down", tok)) + { + return NDB_DOWN_EVENT; + } + else if (!strcasecmp("ndb_up", tok)) + { + return NDB_UP_EVENT; + } + else if (!strcasecmp("lost_master", tok)) + { + return LOST_MASTER_EVENT; + } + else if (!strcasecmp("lost_slave", tok)) + { + return LOST_SLAVE_EVENT; + } + else if (!strcasecmp("lost_synced", tok)) + { + return LOST_SYNCED_EVENT; + } + else if (!strcasecmp("lost_donor", tok)) + { + return LOST_DONOR_EVENT; + } + else if (!strcasecmp("lost_ndb", tok)) + { + return LOST_NDB_EVENT; + } + else if (!strcasecmp("new_master", tok)) + { + return NEW_MASTER_EVENT; + } + else if (!strcasecmp("new_slave", tok)) + { + return NEW_SLAVE_EVENT; + } + else if (!strcasecmp("new_synced", tok)) + { + return NEW_SYNCED_EVENT; + } + else if (!strcasecmp("new_donor", tok)) + { + return NEW_DONOR_EVENT; + } + else if (!strcasecmp("new_ndb", tok)) + { + return NEW_NDB_EVENT; + } + + return UNDEFINED_MONITOR_EVENT; +} /** * Connect to a database. This will always leave a valid database handle in the diff --git a/server/modules/monitor/monitor_common.h b/server/modules/monitor/monitor_common.h index 3f944befc..13b191001 100644 --- a/server/modules/monitor/monitor_common.h +++ b/server/modules/monitor/monitor_common.h @@ -38,32 +38,33 @@ /** Monitor events that are caused by servers moving from * one state to another.*/ -typedef enum { - UNDEFINED_MONITOR_EVENT, - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - SYNCED_DOWN_EVENT, - SYNCED_UP_EVENT, - DONOR_DOWN_EVENT, - DONOR_UP_EVENT, - NDB_DOWN_EVENT, - NDB_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - LOST_SYNCED_EVENT, - LOST_DONOR_EVENT, - LOST_NDB_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - NEW_SYNCED_EVENT, - NEW_DONOR_EVENT, - NEW_NDB_EVENT, - MAX_MONITOR_EVENT -}monitor_event_t; +typedef enum +{ + UNDEFINED_MONITOR_EVENT, + MASTER_DOWN_EVENT, + MASTER_UP_EVENT, + SLAVE_DOWN_EVENT, + SLAVE_UP_EVENT, + SERVER_DOWN_EVENT, + SERVER_UP_EVENT, + SYNCED_DOWN_EVENT, + SYNCED_UP_EVENT, + DONOR_DOWN_EVENT, + DONOR_UP_EVENT, + NDB_DOWN_EVENT, + NDB_UP_EVENT, + LOST_MASTER_EVENT, + LOST_SLAVE_EVENT, + LOST_SYNCED_EVENT, + LOST_DONOR_EVENT, + LOST_NDB_EVENT, + NEW_MASTER_EVENT, + NEW_SLAVE_EVENT, + NEW_SYNCED_EVENT, + NEW_DONOR_EVENT, + NEW_NDB_EVENT, + MAX_MONITOR_EVENT +} monitor_event_t; typedef enum { @@ -72,15 +73,15 @@ typedef enum MONITOR_CONN_TIMEOUT } connect_result_t; -void mon_append_node_names(MONITOR_SERVERS* start,char* str, int len); +void mon_append_node_names(MONITOR_SERVERS* start, char* str, int len); monitor_event_t mon_get_event_type(MONITOR_SERVERS* node); char* mon_get_event_name(MONITOR_SERVERS* node); void monitor_clear_pending_status(MONITOR_SERVERS *ptr, int bit); void monitor_set_pending_status(MONITOR_SERVERS *ptr, int bit); bool mon_status_changed(MONITOR_SERVERS* mon_srv); bool mon_print_fail_status(MONITOR_SERVERS* mon_srv); -void monitor_launch_script(MONITOR* mon,MONITOR_SERVERS* ptr, char* script); -int mon_parse_event_string(bool* events, size_t count,char* string); +void monitor_launch_script(MONITOR* mon, MONITOR_SERVERS* ptr, char* script); +int mon_parse_event_string(bool* events, size_t count, char* string); connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database); void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval); #endif From b22d40b06ba6cd45fbd3788c4141de2bac80550c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 14 Nov 2015 06:49:19 +0200 Subject: [PATCH 168/179] Fixed PCRE2 beng built when CMake is configured The bundled PCRE2 library will be built as a separate target and configuring CMake no longer builds it. Instead, it will only be built when it is out of date. This requires all targets to declare that they depend on the pcre2 target in order for it to be built. --- CMakeLists.txt | 1 + cmake/BuildPCRE2.cmake | 14 ++++++++++---- server/core/CMakeLists.txt | 2 ++ server/modules/filter/CMakeLists.txt | 1 + server/modules/monitor/CMakeLists.txt | 5 +++++ server/modules/routing/schemarouter/CMakeLists.txt | 2 ++ utils/CMakeLists.txt | 1 + 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcf65c091..fa801353c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ find_package(Git) find_package(CURL) # Build PCRE2 +# Read BuildPCRE2 for details about how to add pcre2 as a dependency to a target include(cmake/BuildPCRE2.cmake) # You can find the variables set by this in the FindCURL.cmake file diff --git a/cmake/BuildPCRE2.cmake b/cmake/BuildPCRE2.cmake index 706808798..f1b636be9 100644 --- a/cmake/BuildPCRE2.cmake +++ b/cmake/BuildPCRE2.cmake @@ -1,16 +1,22 @@ # Build the PCRE2 library from source +# +# This will add a 'pcre2' target to CMake which will generate the libpcre2-8.so +# dynamic library and the pcre2.h header. If your target requires PCRE2 you +# need to add a dependeny on the 'pcre2' target by adding add_dependencies( pcre2) +# to the CMakeLists.txt + set(PCRE_ROOT_DIR ${CMAKE_SOURCE_DIR}/pcre2/) set(PCRE_BUILD_DIR ${CMAKE_BINARY_DIR}/pcre2/) - +set(PCRE2_LIBRARIES ${CMAKE_BINARY_DIR}/pcre2/libpcre2-8.so CACHE STRING "PCRE2 dynamic libraries" FORCE) execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PCRE_BUILD_DIR}) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${PCRE_ROOT_DIR} ${PCRE_BUILD_DIR}) -execute_process(COMMAND ${CMAKE_COMMAND} ${PCRE_BUILD_DIR} + +add_custom_target(pcre2 COMMAND ${CMAKE_COMMAND} ${PCRE_BUILD_DIR} -DBUILD_SHARED_LIBS=Y -DPCRE2_BUILD_PCRE2GREP=N -DPCRE2_BUILD_TESTS=N + COMMAND make WORKING_DIRECTORY ${PCRE_BUILD_DIR}) -execute_process(COMMAND make WORKING_DIRECTORY ${PCRE_BUILD_DIR}) -set(PCRE2_LIBRARIES ${CMAKE_BINARY_DIR}/pcre2/libpcre2-8.so CACHE STRING "PCRE2 dynamic libraries" FORCE) include_directories(${CMAKE_BINARY_DIR}/pcre2/) install(PROGRAMS ${PCRE2_LIBRARIES} DESTINATION ${MAXSCALE_LIBDIR}) diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 22e407268..9687ee699 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -6,6 +6,7 @@ if(BUILD_TESTS OR BUILD_TOOLS) target_link_libraries(fullcore ${TCMALLOC_LIBRARIES}) endif() target_link_libraries(fullcore ${CURL_LIBRARIES} utils log_manager pthread ${EMBEDDED_LIB} ${PCRE_LINK_FLAGS} ssl aio rt crypt dl crypto inih z m stdc++) + add_dependencies(fullcore pcre2) endif() add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c @@ -13,6 +14,7 @@ add_executable(maxscale atomic.c buffer.c spinlock.c gateway.c poll.c config.c users.c hashtable.c dbusers.c thread.c gwbitmask.c monitor.c adminusers.c secrets.c filter.c modutil.c hint.c housekeeper.c memlog.c resultset.c gwdirs.c externcmd.c random_jkiss.c maxscale_pcre2.c) +add_dependencies(maxscale pcre2) if(WITH_JEMALLOC) target_link_libraries(maxscale ${JEMALLOC_LIBRARIES}) diff --git a/server/modules/filter/CMakeLists.txt b/server/modules/filter/CMakeLists.txt index 34f77c7d8..2a79547ef 100644 --- a/server/modules/filter/CMakeLists.txt +++ b/server/modules/filter/CMakeLists.txt @@ -8,6 +8,7 @@ endif() add_library(regexfilter SHARED regexfilter.c) target_link_libraries(regexfilter log_manager ${PCRE2_LIBRARIES}) +add_dependencies(regexfilter pcre2) install(TARGETS regexfilter DESTINATION ${MAXSCALE_LIBDIR}) add_library(testfilter SHARED testfilter.c) diff --git a/server/modules/monitor/CMakeLists.txt b/server/modules/monitor/CMakeLists.txt index ab275cf46..58a59e1e1 100644 --- a/server/modules/monitor/CMakeLists.txt +++ b/server/modules/monitor/CMakeLists.txt @@ -1,16 +1,21 @@ add_library(mysqlmon SHARED mysql_mon.c monitor_common.c) target_link_libraries(mysqlmon log_manager) +add_dependencies(mysqlmon pcre2) install(TARGETS mysqlmon DESTINATION ${MAXSCALE_LIBDIR}) add_library(galeramon SHARED galeramon.c monitor_common.c) target_link_libraries(galeramon log_manager) +add_dependencies(galeramon pcre2) install(TARGETS galeramon DESTINATION ${MAXSCALE_LIBDIR}) add_library(ndbclustermon SHARED ndbclustermon.c monitor_common.c) target_link_libraries(ndbclustermon log_manager) +add_dependencies(ndbclustermon pcre2) install(TARGETS ndbclustermon DESTINATION ${MAXSCALE_LIBDIR}) + if(BUILD_MMMON) add_library(mmmon SHARED mmmon.c monitor_common.c) target_link_libraries(mmmon log_manager) + add_dependencies(mmmon pcre2) install(TARGETS mmmon DESTINATION ${MAXSCALE_LIBDIR}) endif() diff --git a/server/modules/routing/schemarouter/CMakeLists.txt b/server/modules/routing/schemarouter/CMakeLists.txt index ae8f295c2..916db0053 100644 --- a/server/modules/routing/schemarouter/CMakeLists.txt +++ b/server/modules/routing/schemarouter/CMakeLists.txt @@ -1,9 +1,11 @@ add_library(schemarouter SHARED schemarouter.c sharding_common.c) target_link_libraries(schemarouter log_manager query_classifier) +add_dependencies(schemarouter pcre2) install(TARGETS schemarouter DESTINATION ${MAXSCALE_LIBDIR}) add_library(shardrouter SHARED shardrouter.c svcconn.c sharding_common.c) target_link_libraries(shardrouter log_manager query_classifier) +add_dependencies(shardrouter pcre2) install(TARGETS shardrouter DESTINATION ${MAXSCALE_LIBDIR}) if(BUILD_TESTS) diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 10811abae..2b467f34e 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -1,2 +1,3 @@ add_library(utils skygw_utils.cc ../server/core/atomic.c) target_link_libraries(utils stdc++ ${PCRE2_LIBRARIES}) +add_dependencies(utils pcre2) From 65e2b50f96bce1516e5f82cd1a9954cf7e26b766 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 14 Nov 2015 07:05:53 +0200 Subject: [PATCH 169/179] Removed client hangup error message The error message did not provide any useful information and was most of the time a false positive due to EPOLL_RDHUP events calling the hangup function of the DCB. --- server/modules/protocol/mysql_client.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 60e66322c..d92b4fc91 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1866,13 +1866,7 @@ gw_client_hangup_event(DCB *dcb) { goto retblock; } -#if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Client hangup error handling, session state %s, dcb state %s.", - session_state(session->state), - STRDCBSTATE(dcb->state)))); -#endif + dcb_close(dcb); retblock: From a7e2bf09c809658d93ad55a5e6f0738727edfb98 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 13:46:22 +0200 Subject: [PATCH 170/179] Cleaned up monitor headers Formatted all monitor headers according to the coding style. --- server/modules/monitor/galeramon.h | 30 +++++++------- server/modules/monitor/mmmon.h | 22 ++++++---- server/modules/monitor/mysqlmon.h | 57 ++++++++++++++------------ server/modules/monitor/ndbclustermon.h | 20 +++++---- 4 files changed, 70 insertions(+), 59 deletions(-) diff --git a/server/modules/monitor/galeramon.h b/server/modules/monitor/galeramon.h index 5a209f01e..b92e97015 100644 --- a/server/modules/monitor/galeramon.h +++ b/server/modules/monitor/galeramon.h @@ -46,23 +46,23 @@ * @endverbatim */ - /** - * The handle for an instance of a MySQL Monitor module + * The handle for an instance of a Galera Monitor module */ -typedef struct { - SPINLOCK lock; /**< The monitor spinlock */ - pthread_t tid; /**< id of monitor thread */ - int shutdown; /**< Flag to shutdown the monitor thread */ - int status; /**< Monitor status */ - unsigned long id; /**< Monitor ID */ - int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ - int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ - int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ - MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ - char* script; - bool use_priority; /*< Use server priorities */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ +typedef struct +{ + SPINLOCK lock; /**< The monitor spinlock */ + pthread_t tid; /**< id of monitor thread */ + int shutdown; /**< Flag to shutdown the monitor thread */ + int status; /**< Monitor status */ + unsigned long id; /**< Monitor ID */ + int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ + int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ + int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ + MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ + char* script; + bool use_priority; /*< Use server priorities */ + bool events[MAX_MONITOR_EVENT]; /*< enabled events */ } GALERA_MONITOR; #endif diff --git a/server/modules/monitor/mmmon.h b/server/modules/monitor/mmmon.h index 8a9edfb56..9e1f4d962 100644 --- a/server/modules/monitor/mmmon.h +++ b/server/modules/monitor/mmmon.h @@ -17,6 +17,7 @@ * * Copyright MariaDB Corporation Ab 2015 */ + #include #include #include @@ -34,17 +35,22 @@ #include #include +/** + * @file mmmon.h - The Multi-Master monitor + */ + /** * The handle for an instance of a Multi-Master Monitor module */ -typedef struct { - SPINLOCK lock; /**< The monitor spinlock */ - pthread_t tid; /**< id of monitor thread */ - int shutdown; /**< Flag to shutdown the monitor thread */ - int status; /**< Monitor status */ - unsigned long id; /**< Monitor ID */ - int detectStaleMaster; /**< Monitor flag for Stale Master detection */ - MONITOR_SERVERS *master; /**< Master server for Master/Slave replication */ +typedef struct +{ + SPINLOCK lock; /**< The monitor spinlock */ + pthread_t tid; /**< id of monitor thread */ + int shutdown; /**< Flag to shutdown the monitor thread */ + int status; /**< Monitor status */ + unsigned long id; /**< Monitor ID */ + int detectStaleMaster; /**< Monitor flag for Stale Master detection */ + MONITOR_SERVERS *master; /**< Master server for Master/Slave replication */ char* script; /*< Script to call when state changes occur on servers */ bool events[MAX_MONITOR_EVENT]; /*< enabled events */ } MM_MONITOR; diff --git a/server/modules/monitor/mysqlmon.h b/server/modules/monitor/mysqlmon.h index 227b693c9..eaa640a94 100644 --- a/server/modules/monitor/mysqlmon.h +++ b/server/modules/monitor/mysqlmon.h @@ -17,6 +17,7 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ + #include #include #include @@ -33,44 +34,46 @@ #include #include #include + /** - * @file mysqlmon.h - The MySQL monitor functionality within the gateway + * @file mysqlmon.h - The MySQL monitor * * @verbatim * Revision History * - * Date Who Description - * 08/07/13 Mark Riddoch Initial implementation - * 26/05/14 Massimiliano Pinto Default values for MONITOR_INTERVAL - * 28/05/14 Massimiliano Pinto Addition of new fields in MYSQL_MONITOR struct - * 24/06/14 Massimiliano Pinto Addition of master field in MYSQL_MONITOR struct and MONITOR_MAX_NUM_SLAVES - * 28/08/14 Massimiliano Pinto Addition of detectStaleMaster - * 30/10/14 Massimiliano Pinto Addition of disableMasterFailback - * 07/11/14 Massimiliano Pinto Addition of NetworkTimeout: connect, read, write - * 20/04/15 Guillaume Lefranc Addition of availableWhenDonor - * 22/04/15 Martin Brampton Addition of disableMasterRoleSetting - * 07/05/15 Markus Makela Addition of command execution on Master server failure + * Date Who Description + * 08/07/13 Mark Riddoch Initial implementation + * 26/05/14 Massimiliano Pinto Default values for MONITOR_INTERVAL + * 28/05/14 Massimiliano Pinto Addition of new fields in MYSQL_MONITOR struct + * 24/06/14 Massimiliano Pinto Addition of master field in MYSQL_MONITOR struct and MONITOR_MAX_NUM_SLAVES + * 28/08/14 Massimiliano Pinto Addition of detectStaleMaster + * 30/10/14 Massimiliano Pinto Addition of disableMasterFailback + * 07/11/14 Massimiliano Pinto Addition of NetworkTimeout: connect, read, write + * 20/04/15 Guillaume Lefranc Addition of availableWhenDonor + * 22/04/15 Martin Brampton Addition of disableMasterRoleSetting + * 07/05/15 Markus Makela Addition of command execution on Master server failure * @endverbatim */ /** * The handle for an instance of a MySQL Monitor module */ -typedef struct { - SPINLOCK lock; /**< The monitor spinlock */ - pthread_t tid; /**< id of monitor thread */ - int shutdown; /**< Flag to shutdown the monitor thread */ - int status; /**< Monitor status */ - unsigned long id; /**< Monitor ID */ - int replicationHeartbeat; /**< Monitor flag for MySQL replication heartbeat */ - int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ - int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ - int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ - int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ - bool mysql51_replication; /**< Use MySQL 5.1 replication */ - MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ - char* script; /*< Script to call when state changes occur on servers */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ +typedef struct +{ + SPINLOCK lock; /**< The monitor spinlock */ + pthread_t tid; /**< id of monitor thread */ + int shutdown; /**< Flag to shutdown the monitor thread */ + int status; /**< Monitor status */ + unsigned long id; /**< Monitor ID */ + int replicationHeartbeat; /**< Monitor flag for MySQL replication heartbeat */ + int detectStaleMaster; /**< Monitor flag for MySQL replication Stale Master detection */ + int disableMasterFailback; /**< Monitor flag for Galera Cluster Master failback */ + int availableWhenDonor; /**< Monitor flag for Galera Cluster Donor availability */ + int disableMasterRoleSetting; /**< Monitor flag to disable setting master role */ + bool mysql51_replication; /**< Use MySQL 5.1 replication */ + MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ + char* script; /*< Script to call when state changes occur on servers */ + bool events[MAX_MONITOR_EVENT]; /*< enabled events */ } MYSQL_MONITOR; #endif diff --git a/server/modules/monitor/ndbclustermon.h b/server/modules/monitor/ndbclustermon.h index 56b961c45..90798fb87 100644 --- a/server/modules/monitor/ndbclustermon.h +++ b/server/modules/monitor/ndbclustermon.h @@ -17,6 +17,7 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ + #include #include #include @@ -42,15 +43,16 @@ /** * The handle for an instance of a NDB Cluster Monitor module */ -typedef struct { - SPINLOCK lock; /**< The monitor spinlock */ - pthread_t tid; /**< id of monitor thread */ - int shutdown; /**< Flag to shutdown the monitor thread */ - int status; /**< Monitor status */ - unsigned long id; /**< Monitor ID */ - MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ - char* script; /*< Script to call when state changes occur on servers */ - bool events[MAX_MONITOR_EVENT]; /*< enabled events */ +typedef struct +{ + SPINLOCK lock; /**< The monitor spinlock */ + pthread_t tid; /**< id of monitor thread */ + int shutdown; /**< Flag to shutdown the monitor thread */ + int status; /**< Monitor status */ + unsigned long id; /**< Monitor ID */ + MONITOR_SERVERS *master; /**< Master server for MySQL Master/Slave replication */ + char* script; /*< Script to call when state changes occur on servers */ + bool events[MAX_MONITOR_EVENT]; /*< enabled events */ } MYSQL_MONITOR; #endif From 1bfe85099f0343a83f390ea9840e224fb06acc55 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 16 Nov 2015 13:56:23 +0200 Subject: [PATCH 171/179] server/module/filters: All LOGIF and skygw_log_write calls removed. All LOGIF and skygw_log_write calls have been replaced with the equivalent MXS_[ERROR|WARNING|NOTICE|INFO|DEBUG] calls. --- server/modules/filter/dbfwfilter.c | 157 ++++++++-------- server/modules/filter/hint/hintparser.c | 79 ++------ server/modules/filter/mqfilter.c | 120 +++++------- server/modules/filter/namedserverfilter.c | 37 ++-- server/modules/filter/qlafilter.c | 74 ++++---- server/modules/filter/regexfilter.c | 30 ++- server/modules/filter/slavelag.c | 24 +-- server/modules/filter/tee.c | 193 +++++++++----------- server/modules/filter/test/harness_common.c | 33 ++-- server/modules/filter/test/harness_ui.c | 8 +- server/modules/filter/test/harness_util.c | 2 +- server/modules/filter/topfilter.c | 51 +++--- 12 files changed, 336 insertions(+), 472 deletions(-) diff --git a/server/modules/filter/dbfwfilter.c b/server/modules/filter/dbfwfilter.c index 1460759b2..7334011a4 100644 --- a/server/modules/filter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter.c @@ -514,7 +514,7 @@ static TIMERANGE* parse_time(const char* str) } else { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: malloc returned NULL."); + MXS_ERROR("dbfwfilter: malloc returned NULL."); } } } @@ -596,7 +596,7 @@ RULE* find_rule(char* tok, FW_INSTANCE* instance) } rlist = rlist->next; } - skygw_log_write(LOGFILE_ERROR, "Error : Rule not found: %s",tok); + MXS_ERROR("Rule not found: %s",tok); return NULL; } @@ -611,7 +611,7 @@ void add_users(char* rule, FW_INSTANCE* instance) STRLINK* link = calloc(1,sizeof(STRLINK)); if(link == NULL){ - skygw_log_write(LOGFILE_ERROR,"Error : Memory allocation failed"); + MXS_ERROR("Memory allocation failed"); return; } link->next = instance->userstrings; @@ -644,9 +644,9 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if((userptr == NULL || ruleptr == NULL || modeptr == NULL)|| (userptr > modeptr || userptr > ruleptr || modeptr > ruleptr)) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); - rval = false; - goto parse_err; + MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); + rval = false; + goto parse_err; } *modeptr++ = '\0'; @@ -656,7 +656,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, right keywords not found in the correct order: %s",orig); rval = false; goto parse_err; } @@ -665,7 +665,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) tok = strtok_r(NULL," ",&saveptr); if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, missing keyword after 'match': %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, missing keyword after 'match': %s",orig); rval = false; goto parse_err; } @@ -677,14 +677,14 @@ bool link_rules(char* orig, FW_INSTANCE* instance) match_any = false; strict = true; }else{ - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, 'match' was not followed by correct keyword: %s",orig); - rval = false; - goto parse_err; + MXS_ERROR("dbfwfilter: Rule syntax incorrect, 'match' was not followed by correct keyword: %s",orig); + rval = false; + goto parse_err; } } else { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, bad token: %s",tok); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, bad token: %s",tok); rval = false; goto parse_err; } @@ -693,7 +693,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if(tok != NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, extra token found after 'match' keyword: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, extra token found after 'match' keyword: %s",orig); rval = false; goto parse_err; } @@ -702,7 +702,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); rval = false; goto parse_err; } @@ -711,7 +711,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules given: %s",orig); rval = false; goto parse_err; } @@ -730,7 +730,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) } else { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, could not find rule '%s'.",tok); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, could not find rule '%s'.",tok); rval = false; goto parse_err; } @@ -747,14 +747,14 @@ bool link_rules(char* orig, FW_INSTANCE* instance) if(userptr == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, no users given: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no users given: %s",orig); rval = false; goto parse_err; } if(rulelist == NULL) { - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule syntax incorrect, no rules found: %s",orig); + MXS_ERROR("dbfwfilter: Rule syntax incorrect, no rules found: %s",orig); rval = false; goto parse_err; } @@ -770,7 +770,7 @@ bool link_rules(char* orig, FW_INSTANCE* instance) user = (USER*)calloc(1,sizeof(USER)); if(user == NULL){ - skygw_log_write(LOGFILE_ERROR,"Error: dbfwfilter: failed to allocate memory when parsing rules."); + MXS_ERROR("dbfwfilter: failed to allocate memory when parsing rules."); rval = false; goto parse_err; } @@ -858,7 +858,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, no rule: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, no rule: %s",rule); rval = false; goto retblock; } @@ -872,7 +872,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, incomplete rule: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, incomplete rule: %s",rule); rval = false; goto retblock; } @@ -883,7 +883,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(ruledef == NULL) { - skygw_log_write(LOGFILE_ERROR,"Error: Memory allocation failed."); + MXS_ERROR("Memory allocation failed."); rval = false; goto retblock; } @@ -893,7 +893,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(rlist == NULL) { free(ruledef); - skygw_log_write(LOGFILE_ERROR,"Error: Memory allocation failed."); + MXS_ERROR("Memory allocation failed."); rval = false; goto retblock; } @@ -914,7 +914,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) } else { - skygw_log_write(LOGFILE_ERROR,"Error : Unknown token in rule '%s': %s",rule,tok); + MXS_ERROR("Unknown token in rule '%s': %s",rule,tok); rval = false; goto retblock; } @@ -923,7 +923,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, no allow or deny: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, no allow or deny: %s",rule); rval = false; goto retblock; } @@ -948,7 +948,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { if(req_defined) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, Multiple non-optional rules: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, Multiple non-optional rules: %s",rule); rval = false; goto retblock; } @@ -985,7 +985,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { if(at_def) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, multiple 'at_times' tokens: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'at_times' tokens: %s",rule); rval = false; goto retblock; } @@ -997,7 +997,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) break; if(!check_time(tok)) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, malformed time definition: %s",tok); + MXS_ERROR("dbfwfilter: Rule parsing failed, malformed time definition: %s",tok); rval = false; goto retblock; } @@ -1006,7 +1006,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tmp == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, unexpected characters after time definition."); + MXS_ERROR("dbfwfilter: Rule parsing failed, unexpected characters after time definition."); rval = false; tr_free(tr); goto retblock; @@ -1038,14 +1038,14 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, No regex string."); + MXS_ERROR("dbfwfilter: Rule parsing failed, No regex string."); rval = false; goto retblock; } if(*tok != '\'' && *tok != '\"') { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, regex string not quoted."); + MXS_ERROR("dbfwfilter: Rule parsing failed, regex string not quoted."); rval = false; goto retblock; } @@ -1079,7 +1079,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(n_char >= 2048) { - skygw_log_write_flush(LOGFILE_ERROR, "dbfwfilter: Failed to parse rule, regular expression length is over 2048 characters."); + MXS_ERROR("dbfwfilter: Failed to parse rule, regular expression length is over 2048 characters."); rval = false; goto retblock; } @@ -1087,14 +1087,14 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) str = calloc(((tok - start) + 1),sizeof(char)); if(str == NULL) { - skygw_log_write_flush(LOGFILE_ERROR, "Fatal Error: malloc returned NULL."); + MXS_ERROR("Fatal Error: malloc returned NULL."); rval = false; goto retblock; } re = (regex_t*)malloc(sizeof(regex_t)); if(re == NULL){ - skygw_log_write_flush(LOGFILE_ERROR, "Fatal Error: malloc returned NULL."); + MXS_ERROR("Fatal Error: malloc returned NULL."); rval = false; free(str); goto retblock; @@ -1103,7 +1103,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) memcpy(str, start, (tok-start)); if(regcomp(re, str,REG_NOSUB|instance->regflags)){ - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Invalid regular expression '%s'.", str); + MXS_ERROR("dbfwfilter: Invalid regular expression '%s'.", str); rval = false; free(re); goto retblock; @@ -1130,7 +1130,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); goto retblock; } @@ -1140,14 +1140,14 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); goto retblock; } if(qs->limit < 1){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad query amount: %s", tok); + MXS_ERROR("dbfwfilter: Bad query amount: %s", tok); goto retblock; } @@ -1157,7 +1157,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); goto retblock; } @@ -1167,14 +1167,14 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); goto retblock; } if(qs->period < 1){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad time period: %s", tok); + MXS_ERROR("dbfwfilter: Bad time period: %s", tok); goto retblock; } @@ -1184,7 +1184,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); + MXS_ERROR("dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); goto retblock; } qs->cooldown = strtod(tok,&errptr); @@ -1193,14 +1193,14 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); + MXS_ERROR("dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); goto retblock; } if(qs->cooldown < 1){ free(qs); rval = false; - skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad blocking period: %s", tok); + MXS_ERROR("dbfwfilter: Bad blocking period: %s", tok); goto retblock; } @@ -1216,7 +1216,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) { if(oq_def) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, multiple 'on_queries' tokens: %s",rule); + MXS_ERROR("dbfwfilter: Rule parsing failed, multiple 'on_queries' tokens: %s",rule); rval = false; goto retblock; } @@ -1225,28 +1225,22 @@ bool parse_rule(char* rule, FW_INSTANCE* instance) if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR, - "dbfwfilter: Missing parameter for 'on_queries'."); + MXS_ERROR("dbfwfilter: Missing parameter for 'on_queries'."); rval = false; goto retblock; } if(!parse_querytypes(tok,ruledef)){ - skygw_log_write(LOGFILE_ERROR, - "dbfwfilter: Invalid query type" - "requirements: %s." - ,tok); + MXS_ERROR("dbfwfilter: Invalid query type requirements: %s.", tok); rval = false; goto retblock; } } else { - skygw_log_write(LOGFILE_ERROR, - "dbfwfilter: Unknown rule type: %s" - ,tok); - rval = false; - goto retblock; + MXS_ERROR("dbfwfilter: Unknown rule type: %s", tok); + rval = false; + goto retblock; } tok = strtok_r(NULL," ,",&saveptr); } @@ -1298,16 +1292,16 @@ createInstance(char **options, FILTER_PARAMETER **params) if ((my_instance = calloc(1, sizeof(FW_INSTANCE))) == NULL || (my_instance->lock = (SPINLOCK*)malloc(sizeof(SPINLOCK))) == NULL){ - skygw_log_write(LOGFILE_ERROR, "Memory allocation for firewall filter failed."); - return NULL; + MXS_ERROR("Memory allocation for firewall filter failed."); + return NULL; } spinlock_init(my_instance->lock); if((ht = hashtable_alloc(100, hashkeyfun, hashcmpfun)) == NULL){ - skygw_log_write(LOGFILE_ERROR, "Unable to allocate hashtable."); - free(my_instance); - return NULL; + MXS_ERROR("Unable to allocate hashtable."); + free(my_instance); + return NULL; } hashtable_memory_fns(ht,(HASHMEMORYFN)strdup,NULL,(HASHMEMORYFN)free,huserfree); @@ -1338,15 +1332,15 @@ createInstance(char **options, FILTER_PARAMETER **params) if(filename == NULL) { - skygw_log_write(LOGFILE_ERROR, "Unable to find rule file for firewall filter. Please provide the path with" - " rules="); + MXS_ERROR("Unable to find rule file for firewall filter. Please provide the path with" + " rules="); hashtable_free(my_instance->htable); free(my_instance); return NULL; } if((file = fopen(filename,"rb")) == NULL ){ - skygw_log_write(LOGFILE_ERROR, "Error while opening rule file for firewall filter."); + MXS_ERROR("Error while opening rule file for firewall filter."); hashtable_free(my_instance->htable); free(my_instance); free(filename); @@ -1361,7 +1355,7 @@ createInstance(char **options, FILTER_PARAMETER **params) if(fgets(buffer,2048,file) == NULL){ if(ferror(file)){ - skygw_log_write(LOGFILE_ERROR, "Error while reading rule file for firewall filter."); + MXS_ERROR("Error while reading rule file for firewall filter."); fclose(file); hashtable_free(my_instance->htable); free(my_instance); @@ -1394,7 +1388,7 @@ createInstance(char **options, FILTER_PARAMETER **params) if(file_empty) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: File is empty: %s", filename); + MXS_ERROR("dbfwfilter: File is empty: %s", filename); free(filename); err = true; goto retblock; @@ -1408,7 +1402,7 @@ createInstance(char **options, FILTER_PARAMETER **params) if(ptr == NULL) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: No 'users' line found."); + MXS_ERROR("dbfwfilter: No 'users' line found."); err = true; goto retblock; } @@ -1417,7 +1411,7 @@ createInstance(char **options, FILTER_PARAMETER **params) if(!link_rules(ptr->value,my_instance)) { - skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Failed to parse rule: %s",ptr->value); + MXS_ERROR("dbfwfilter: Failed to parse rule: %s",ptr->value); err = true; } tmp = ptr; @@ -1525,7 +1519,7 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) session->session->data == NULL || session->session->client == NULL) { - skygw_log_write_flush(LOGFILE_ERROR, "Error : Firewall filter session missing data."); + MXS_ERROR("Firewall filter session missing data."); return NULL; } @@ -1535,8 +1529,8 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) errmsg = (char*)malloc((512 + errlen)*sizeof(char)); if(errmsg == NULL){ - skygw_log_write_flush(LOGFILE_ERROR, "Fatal Error: Memory allocation failed."); - return NULL; + MXS_ERROR("Memory allocation failed."); + return NULL; } @@ -1673,7 +1667,7 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue switch(rulelist->rule->type){ case RT_UNDEFINED: - skygw_log_write_flush(LOGFILE_ERROR, "Error: Undefined rule type found."); + MXS_ERROR("Undefined rule type found."); break; case RT_REGEX: @@ -1684,7 +1678,7 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue if(!rulelist->rule->allow){ msg = strdup("Permission denied, query matched regular expression."); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': regex matched on query",rulelist->rule->name); + MXS_INFO("dbfwfilter: rule '%s': regex matched on query",rulelist->rule->name); goto queryresolved; }else{ break; @@ -1697,7 +1691,7 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue if(!rulelist->rule->allow){ matches = true; msg = strdup("Permission denied at this time."); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': query denied at: %s",rulelist->rule->name,asctime(tm_now)); + MXS_INFO("dbfwfilter: rule '%s': query denied at: %s",rulelist->rule->name,asctime(tm_now)); goto queryresolved; }else{ break; @@ -1724,7 +1718,8 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue if(!rulelist->rule->allow) { sprintf(emsg,"Permission denied to column '%s'.",strln->value); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': query targets forbidden column: %s",rulelist->rule->name,strln->value); + MXS_INFO("dbfwfilter: rule '%s': query targets forbidden column: %s", + rulelist->rule->name,strln->value); msg = strdup(emsg); goto queryresolved; } @@ -1755,7 +1750,7 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue matches = true; msg = strdup("Usage of wildcard denied."); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': query contains a wildcard.",rulelist->rule->name); + MXS_INFO("dbfwfilter: rule '%s': query contains a wildcard.",rulelist->rule->name); goto queryresolved; } free(where); @@ -1808,7 +1803,7 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue double blocked_for = queryspeed->cooldown - difftime(time_now,queryspeed->triggered); sprintf(emsg,"Queries denied for %f seconds",blocked_for); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': user denied for %f seconds",rulelist->rule->name,blocked_for); + MXS_INFO("dbfwfilter: rule '%s': user denied for %f seconds",rulelist->rule->name,blocked_for); msg = strdup(emsg); matches = true; @@ -1828,8 +1823,8 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue matches = true; queryspeed->active = true; - skygw_log_write(LOGFILE_TRACE, - "dbfwfilter: rule '%s': query limit triggered (%d queries in %f seconds), denying queries from user for %f seconds.", + MXS_INFO("dbfwfilter: rule '%s': query limit triggered (%d queries in %f seconds), " + "denying queries from user for %f seconds.", rulelist->rule->name, queryspeed->limit, queryspeed->period, @@ -1859,8 +1854,8 @@ bool rule_matches(FW_INSTANCE* my_instance, FW_SESSION* my_session, GWBUF *queue { matches = true; msg = strdup("Required WHERE/HAVING clause is missing."); - skygw_log_write(LOGFILE_TRACE, "dbfwfilter: rule '%s': query has no where/having clause, query is denied.", - rulelist->rule->name); + MXS_INFO("dbfwfilter: rule '%s': query has no where/having clause, query is denied.", + rulelist->rule->name); } break; diff --git a/server/modules/filter/hint/hintparser.c b/server/modules/filter/hint/hintparser.c index 6556b2a99..f43c4caee 100644 --- a/server/modules/filter/hint/hintparser.c +++ b/server/modules/filter/hint/hintparser.c @@ -266,18 +266,10 @@ HINT_MODE mode = HM_EXECUTE; break; default: /* Error: expected hint, name or STOP */ - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " - "'route', 'stop' or hint name instead of " - "'%s'. Hint ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "'route', 'stop' or hint name instead of " - "'%s'. Hint ignored.", - token_get_keyword(tok)))); + MXS_ERROR("Syntax error in hint. Expected " + "'route', 'stop' or hint name instead of " + "'%s'. Hint ignored.", + token_get_keyword(tok)); token_free(tok); goto retblock; } @@ -286,16 +278,9 @@ HINT_MODE mode = HM_EXECUTE; if (tok->token != TOK_TO) { /* Error, expect TO */; - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " + MXS_ERROR("Syntax error in hint. Expected " "'to' instead of '%s'. Hint ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "'to' instead of '%s'. Hint ignored.", - token_get_keyword(tok)))); + token_get_keyword(tok)); token_free(tok); goto retblock; } @@ -317,18 +302,10 @@ HINT_MODE mode = HM_EXECUTE; break; default: /* Error expected MASTER, SLAVE or SERVER */ - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " + MXS_ERROR("Syntax error in hint. Expected " "'master', 'slave', or 'server' instead " "of '%s'. Hint ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "'master', 'slave', or 'server' instead " - "of '%s'. Hint ignored.", - token_get_keyword(tok)))); + token_get_keyword(tok)); token_free(tok); goto retblock; @@ -343,18 +320,10 @@ HINT_MODE mode = HM_EXECUTE; else { /* Error: Expected server name */ - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " + MXS_ERROR("Syntax error in hint. Expected " "server name instead of '%s'. Hint " "ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "server name instead of '%s'. Hint " - "ignored.", - token_get_keyword(tok)))); + token_get_keyword(tok)); token_free(tok); goto retblock; } @@ -378,18 +347,10 @@ HINT_MODE mode = HM_EXECUTE; break; default: /* Error, token tok->value not expected */ - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " - "'=', 'prepare', or 'start' instead of " - "'%s'. Hint ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "'=', 'prepare', or 'start' instead of " - "'%s'. Hint ignored.", - token_get_keyword(tok)))); + MXS_ERROR("Syntax error in hint. Expected " + "'=', 'prepare', or 'start' instead of " + "'%s'. Hint ignored.", + token_get_keyword(tok)); token_free(tok); goto retblock; } @@ -413,18 +374,10 @@ HINT_MODE mode = HM_EXECUTE; break; default: /* Error, token tok->value not expected */ - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Error : Syntax error in hint. Expected " + MXS_ERROR("Syntax error in hint. Expected " "'route' or hint name instead of " "'%s'. Hint ignored.", - token_get_keyword(tok)))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Syntax error in hint. Expected " - "'route' or hint name instead of " - "'%s'. Hint ignored.", - token_get_keyword(tok)))); + token_get_keyword(tok)); token_free(tok); goto retblock; } diff --git a/server/modules/filter/mqfilter.c b/server/modules/filter/mqfilter.c index 7d78f20ea..1587240bd 100644 --- a/server/modules/filter/mqfilter.c +++ b/server/modules/filter/mqfilter.c @@ -307,53 +307,45 @@ init_conn(MQ_INSTANCE *my_instance) if((my_instance->sock = amqp_ssl_socket_new(my_instance->conn)) != NULL){ if((amqp_ok = amqp_ssl_socket_set_cacert(my_instance->sock,my_instance->ssl_CA_cert)) != AMQP_STATUS_OK){ - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to set CA certificate: %s", amqp_error_string2(amqp_ok)); - goto cleanup; + MXS_ERROR("Failed to set CA certificate: %s", amqp_error_string2(amqp_ok)); + goto cleanup; } if((amqp_ok = amqp_ssl_socket_set_key(my_instance->sock, my_instance->ssl_client_cert, my_instance->ssl_client_key)) != AMQP_STATUS_OK){ - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to set client certificate and key: %s", amqp_error_string2(amqp_ok)); - goto cleanup; + MXS_ERROR("Failed to set client certificate and key: %s", amqp_error_string2(amqp_ok)); + goto cleanup; } }else{ amqp_ok = AMQP_STATUS_SSL_CONNECTION_FAILED; - skygw_log_write(LOGFILE_ERROR, - "Error : SSL socket creation failed."); + MXS_ERROR("SSL socket creation failed."); goto cleanup; } /**SSL is not used, falling back to TCP*/ }else if((my_instance->sock = amqp_tcp_socket_new(my_instance->conn)) == NULL){ - skygw_log_write(LOGFILE_ERROR, - "Error : TCP socket creation failed."); - goto cleanup; + MXS_ERROR("TCP socket creation failed."); + goto cleanup; } /**Socket creation was successful, trying to open the socket*/ if((amqp_ok = amqp_socket_open(my_instance->sock,my_instance->hostname,my_instance->port)) != AMQP_STATUS_OK){ - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to open socket: %s", amqp_error_string2(amqp_ok)); - goto cleanup; + MXS_ERROR("Failed to open socket: %s", amqp_error_string2(amqp_ok)); + goto cleanup; } amqp_rpc_reply_t reply; reply = amqp_login(my_instance->conn,my_instance->vhost,0,AMQP_DEFAULT_FRAME_SIZE,0,AMQP_SASL_METHOD_PLAIN,my_instance->username,my_instance->password); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Login to RabbitMQ server failed."); - - goto cleanup; + MXS_ERROR("Login to RabbitMQ server failed."); + goto cleanup; } amqp_channel_open(my_instance->conn,my_instance->channel); reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Channel creation failed."); - goto cleanup; + MXS_ERROR("Channel creation failed."); + goto cleanup; } amqp_exchange_declare(my_instance->conn,my_instance->channel, @@ -365,8 +357,7 @@ init_conn(MQ_INSTANCE *my_instance) reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Exchange declaration failed,trying to redeclare the exchange."); + MXS_ERROR("Exchange declaration failed,trying to redeclare the exchange."); if(reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION){ if(reply.reply.id == AMQP_CHANNEL_CLOSE_METHOD){ amqp_send_method(my_instance->conn,my_instance->channel,AMQP_CHANNEL_CLOSE_OK_METHOD,NULL); @@ -386,9 +377,8 @@ init_conn(MQ_INSTANCE *my_instance) reply = amqp_get_rpc_reply(my_instance->conn); } if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Exchange redeclaration failed."); - goto cleanup; + MXS_ERROR("Exchange redeclaration failed."); + goto cleanup; } } @@ -402,9 +392,8 @@ init_conn(MQ_INSTANCE *my_instance) amqp_empty_table); reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Queue declaration failed."); - goto cleanup; + MXS_ERROR("Queue declaration failed."); + goto cleanup; } @@ -415,9 +404,8 @@ init_conn(MQ_INSTANCE *my_instance) amqp_empty_table); reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to bind queue to exchange."); - goto cleanup; + MXS_ERROR("Failed to bind queue to exchange."); + goto cleanup; } } rval = 1; @@ -451,10 +439,9 @@ char** parse_optstr(char* str, char* tok, int* szstore) arr = malloc(sizeof(char*)*size); if(arr == NULL){ - skygw_log_write(LOGFILE_ERROR, - "Error : Cannot allocate enough memory."); - *szstore = 0; - return NULL; + MXS_ERROR("Cannot allocate enough memory."); + *szstore = 0; + return NULL; } *szstore = size; @@ -552,7 +539,7 @@ createInstance(char **options, FILTER_PARAMETER **params) }else if(!strcmp(arr[x],"all")){ my_instance->trgtype = TRG_ALL; }else{ - skygw_log_write(LOGFILE_ERROR,"Error: Unknown option for 'logging_trigger':%s.",arr[x]); + MXS_ERROR("Unknown option for 'logging_trigger':%s.",arr[x]); } } @@ -719,8 +706,7 @@ int declareQueue(MQ_INSTANCE *my_instance, MQ_SESSION* my_session, char* qname) reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ success = 0; - skygw_log_write(LOGFILE_ERROR, - "Error : Queue declaration failed."); + MXS_ERROR("Queue declaration failed."); } @@ -733,8 +719,7 @@ int declareQueue(MQ_INSTANCE *my_instance, MQ_SESSION* my_session, char* qname) reply = amqp_get_rpc_reply(my_instance->conn); if(reply.reply_type != AMQP_RESPONSE_NORMAL){ success = 0; - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to bind queue to exchange."); + MXS_ERROR("Failed to bind queue to exchange."); } spinlock_release(&my_instance->rconn_lock); @@ -766,8 +751,7 @@ void sendMessage(void* data) }else{ instance->rconn_intv += 5.0; - skygw_log_write(LOGFILE_ERROR, - "Error : Failed to reconnect to the MQRabbit server "); + MXS_ERROR("Failed to reconnect to the MQRabbit server "); } } err_num = instance->conn_stat; @@ -853,11 +837,10 @@ void pushMessage(MQ_INSTANCE *instance, amqp_basic_properties_t* prop, char* msg newmsg->prop = prop; }else{ - skygw_log_write(LOGFILE_ERROR, - "Error : Cannot allocate enough memory."); - free(prop); - free(msg); - return; + MXS_ERROR("Cannot allocate enough memory."); + free(prop); + free(msg); + return; } spinlock_acquire(&instance->msg_lock); @@ -1033,8 +1016,8 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) } if(!success){ - skygw_log_write(LOGFILE_ERROR,"Error: Parsing query failed."); - goto send_downstream; + MXS_ERROR("Parsing query failed."); + goto send_downstream; } if(!my_instance->log_all){ @@ -1044,7 +1027,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) } if(my_instance->trgtype == TRG_ALL){ - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_ALL"); + MXS_INFO("Trigger is TRG_ALL"); schema_ok = true; src_ok = true; obj_ok = true; @@ -1064,8 +1047,8 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(strcmp(my_instance->src_trg->user[i],sessusr) == 0) { - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SOURCE: user: %s = %s",my_instance->src_trg->user[i],sessusr); - src_ok = true; + MXS_INFO("Trigger is TRG_SOURCE: user: %s = %s",my_instance->src_trg->user[i],sessusr); + src_ok = true; break; } @@ -1082,7 +1065,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(strcmp(my_instance->src_trg->host[i],sesshost) == 0) { - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SOURCE: host: %s = %s",my_instance->src_trg->host[i],sesshost); + MXS_INFO("Trigger is TRG_SOURCE: host: %s = %s",my_instance->src_trg->host[i],sesshost); src_ok = true; break; } @@ -1119,7 +1102,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(strcmp(tmp,my_instance->shm_trg->objects[i]) == 0){ - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SCHEMA: %s = %s",tmp,my_instance->shm_trg->objects[i]); + MXS_INFO("Trigger is TRG_SCHEMA: %s = %s",tmp,my_instance->shm_trg->objects[i]); schema_ok = true; break; @@ -1138,7 +1121,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(strcmp(my_session->db,my_instance->shm_trg->objects[i]) == 0){ - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SCHEMA: %s = %s",my_session->db,my_instance->shm_trg->objects[i]); + MXS_INFO("Trigger is TRG_SCHEMA: %s = %s",my_session->db,my_instance->shm_trg->objects[i]); schema_ok = true; break; @@ -1178,7 +1161,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(!strcmp(tbnm,my_instance->obj_trg->objects[i])){ obj_ok = true; - skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_OBJECT: %s = %s",my_instance->obj_trg->objects[i],sesstbls[j]); + MXS_INFO("Trigger is TRG_OBJECT: %s = %s",my_instance->obj_trg->objects[i],sesstbls[j]); break; } @@ -1212,19 +1195,19 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) * Something matched the trigger, log the query */ - skygw_log_write_flush(LOGFILE_TRACE,"Routing message to: %s:%d %s as %s/%s, exchange: %s<%s> key:%s queue:%s", - my_instance->hostname,my_instance->port, - my_instance->vhost,my_instance->username, - my_instance->password,my_instance->exchange, - my_instance->exchange_type,my_instance->key, - my_instance->queue); + MXS_INFO("Routing message to: %s:%d %s as %s/%s, exchange: %s<%s> key:%s queue:%s", + my_instance->hostname,my_instance->port, + my_instance->vhost,my_instance->username, + my_instance->password,my_instance->exchange, + my_instance->exchange_type,my_instance->key, + my_instance->queue); if(my_session->uid == NULL){ my_session->uid = calloc(33,sizeof(char)); if(!my_session->uid){ - skygw_log_write(LOGFILE_ERROR,"Error : Out of memory."); + MXS_ERROR("Out of memory."); }else{ genkey(my_session->uid,32); } @@ -1257,8 +1240,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) /**Try to convert to a canonical form and use the plain query if unsuccessful*/ if((canon_q = skygw_get_canonical(queue)) == NULL){ - skygw_log_write_flush(LOGFILE_ERROR, - "Error: Cannot form canonical query."); + MXS_ERROR("Cannot form canonical query."); } } @@ -1268,8 +1250,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) int qlen = strnlen(canon_q,length) + strnlen(t_buf,128); if((combined = malloc((qlen+1)*sizeof(char))) == NULL){ - skygw_log_write_flush(LOGFILE_ERROR, - "Error: Out of memory"); + MXS_ERROR("Out of memory"); } strcpy(combined,t_buf); strncat(combined,canon_q,length); @@ -1409,8 +1390,7 @@ static int clientReply(FILTER* instance, void *session, GWBUF *reply) prop->message_id = amqp_cstring_bytes("reply"); } if(!(combined = calloc(GWBUF_LENGTH(reply) + 256,sizeof(char)))){ - skygw_log_write_flush(LOGFILE_ERROR, - "Error : Out of memory"); + MXS_ERROR("Out of memory"); } memset(t_buf,0,128); diff --git a/server/modules/filter/namedserverfilter.c b/server/modules/filter/namedserverfilter.c index f478e05d2..c634d8198 100644 --- a/server/modules/filter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter.c @@ -161,10 +161,8 @@ int i, cflags = REG_ICASE; my_instance->user = strdup(params[i]->value); else if (!filter_standard_parameter(params[i]->name)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "namedserverfilter: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("namedserverfilter: Unexpected parameter '%s'.", + params[i]->name); } } @@ -182,10 +180,8 @@ int i, cflags = REG_ICASE; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "namedserverfilter: unsupported option '%s'.\n", - options[i]))); + MXS_ERROR("namedserverfilter: unsupported option '%s'.", + options[i]); } } } @@ -193,25 +189,22 @@ int i, cflags = REG_ICASE; if (my_instance->match == NULL || my_instance->server == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "namedserverfilter: Missing required configured" - " option. You must specify a match and server " - "option as a minimum."))); - free(my_instance); - return NULL; + MXS_ERROR("namedserverfilter: Missing required configured" + " option. You must specify a match and server " + "option as a minimum."); + free(my_instance); + return NULL; } if (regcomp(&my_instance->re, my_instance->match, my_instance->cflags)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "namedserverfilter: Invalid regular expression '%s'.\n", - my_instance->match))); - free(my_instance->match); - free(my_instance->server); - free(my_instance); - return NULL; + MXS_ERROR("namedserverfilter: Invalid regular expression '%s'.\n", + my_instance->match); + free(my_instance->match); + free(my_instance->server); + free(my_instance); + return NULL; } } return (FILTER *)my_instance; diff --git a/server/modules/filter/qlafilter.c b/server/modules/filter/qlafilter.c index 94ccdefca..1b72326ea 100644 --- a/server/modules/filter/qlafilter.c +++ b/server/modules/filter/qlafilter.c @@ -205,10 +205,8 @@ int i; } else if (!filter_standard_parameter(params[i]->name)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "qlafilter: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("qlafilter: Unexpected parameter '%s'.", + params[i]->name); } } } @@ -216,26 +214,24 @@ int i; if (my_instance->match && regcomp(&my_instance->re, my_instance->match, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "qlafilter: Invalid regular expression '%s'" - " for the match parameter.\n", - my_instance->match))); - free(my_instance->match); - free(my_instance->source); - if(my_instance->filebase){ - free(my_instance->filebase); - } - free(my_instance); - return NULL; + MXS_ERROR("qlafilter: Invalid regular expression '%s'" + " for the match parameter.\n", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + if(my_instance->filebase){ + free(my_instance->filebase); + } + free(my_instance); + return NULL; } if (my_instance->nomatch && regcomp(&my_instance->nore, my_instance->nomatch, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "qlafilter: Invalid regular expression '%s'" - " for the nomatch paramter.\n", - my_instance->match))); + MXS_ERROR("qlafilter: Invalid regular expression '%s'" + " for the nomatch paramter.", + my_instance->match); if (my_instance->match) regfree(&my_instance->re); free(my_instance->match); @@ -273,14 +269,12 @@ char *remote, *userName; == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Memory allocation for qla filter " - "file name failed due to %d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - free(my_session); - return NULL; + MXS_ERROR("Memory allocation for qla filter " + "file name failed due to %d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); + free(my_session); + return NULL; } my_session->active = 1; @@ -312,27 +306,23 @@ char *remote, *userName; if (my_session->fp == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Opening output file for qla " - "fileter failed due to %d, %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); - free(my_session->filename); - free(my_session); - my_session = NULL; + MXS_ERROR("Opening output file for qla " + "fileter failed due to %d, %s", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); + free(my_session->filename); + free(my_session); + my_session = NULL; } } } else { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Error : Memory allocation for qla filter failed due to " - "%d, %s.", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation for qla filter failed due to " + "%d, %s.", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } return my_session; } diff --git a/server/modules/filter/regexfilter.c b/server/modules/filter/regexfilter.c index 519b24820..ab35c0af2 100644 --- a/server/modules/filter/regexfilter.c +++ b/server/modules/filter/regexfilter.c @@ -208,10 +208,8 @@ createInstance(char **options, FILTER_PARAMETER **params) } else if (!filter_standard_parameter(params[i]->name)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "regexfilter: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("regexfilter: Unexpected parameter '%s'.", + params[i]->name); } } @@ -229,10 +227,8 @@ createInstance(char **options, FILTER_PARAMETER **params) } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "regexfilter: unsupported option '%s'.\n", - options[i]))); + MXS_ERROR("regexfilter: unsupported option '%s'.", + options[i]); } } } @@ -241,9 +237,7 @@ createInstance(char **options, FILTER_PARAMETER **params) { if ((my_instance->logfile = fopen(logfile, "a")) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "regexfilter: Failed to open file '%s'.\n", - logfile))); + MXS_ERROR("regexfilter: Failed to open file '%s'.", logfile); free_instance(my_instance); free(logfile); return NULL; @@ -269,9 +263,8 @@ createInstance(char **options, FILTER_PARAMETER **params) { char errbuffer[1024]; pcre2_get_error_message(errnumber, (PCRE2_UCHAR*) & errbuffer, sizeof(errbuffer)); - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: regexfilter: Compiling regular expression '%s' failed at %lu: %s\n", - my_instance->match, erroffset, errbuffer))); + MXS_ERROR("regexfilter: Compiling regular expression '%s' failed at %lu: %s", + my_instance->match, erroffset, errbuffer); free_instance(my_instance); return NULL; } @@ -279,9 +272,8 @@ createInstance(char **options, FILTER_PARAMETER **params) if((my_instance->match_data = pcre2_match_data_create_from_pattern( my_instance->re, NULL)) == NULL) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: regexfilter: Failure to create PCRE2 matching data. " - "This is most likely caused by a lack of available memory."))); + MXS_ERROR("regexfilter: Failure to create PCRE2 matching data. " + "This is most likely caused by a lack of available memory."); free_instance(my_instance); return NULL; } @@ -511,7 +503,7 @@ void log_match(REGEX_INSTANCE* inst, char* re, char* old, char* new) } if(inst->log_trace) { - LOGIF(LT,(skygw_log_write(LT,"Match %s: [%s] -> [%s]",re,old,new))); + MXS_INFO("Match %s: [%s] -> [%s]",re,old,new); } } @@ -530,6 +522,6 @@ void log_nomatch(REGEX_INSTANCE* inst, char* re, char* old) } if(inst->log_trace) { - LOGIF(LT,(skygw_log_write(LT,"No match %s: [%s]",re,old))); + MXS_INFO("No match %s: [%s]",re,old); } } diff --git a/server/modules/filter/slavelag.c b/server/modules/filter/slavelag.c index 1e9bbaaa2..df8b6331b 100644 --- a/server/modules/filter/slavelag.c +++ b/server/modules/filter/slavelag.c @@ -179,10 +179,8 @@ int i,cflags = 0; my_instance->nomatch = strdup(params[i]->value); else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "lagfilter: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("lagfilter: Unexpected parameter '%s'.\n", + params[i]->name); } } @@ -200,10 +198,8 @@ int i,cflags = 0; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "lagfilter: unsupported option '%s'.", - options[i]))); + MXS_ERROR("lagfilter: unsupported option '%s'.", + options[i]))); } } } @@ -212,20 +208,16 @@ int i,cflags = 0; { if(regcomp(&my_instance->re,my_instance->match,cflags)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "lagfilter: Failed to compile regex '%s'.", - my_instance->match))); + MXS_ERROR("lagfilter: Failed to compile regex '%s'.", + my_instance->match); } } if(my_instance->nomatch) { if(regcomp(&my_instance->nore,my_instance->nomatch,cflags)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "lagfilter: Failed to compile regex '%s'.", - my_instance->nomatch))); + MXS_ERROR("lagfilter: Failed to compile regex '%s'.", + my_instance->nomatch))); } } } diff --git a/server/modules/filter/tee.c b/server/modules/filter/tee.c index 2f68b22bd..880bc5c24 100644 --- a/server/modules/filter/tee.c +++ b/server/modules/filter/tee.c @@ -274,9 +274,9 @@ orphan_free(void* data) #ifdef SS_DEBUG if(o_stopping + o_ready > 0) - skygw_log_write(LOGFILE_DEBUG, "tee.c: %d orphans in " - "SESSION_STATE_STOPPING, %d orphans in " - "SESSION_STATE_ROUTER_READY. ", o_stopping, o_ready); + MXS_DEBUG("tee.c: %d orphans in " + "SESSION_STATE_STOPPING, %d orphans in " + "SESSION_STATE_ROUTER_READY. ", o_stopping, o_ready); #endif while(finished) @@ -297,7 +297,7 @@ orphan_free(void* data) } #ifdef SS_DEBUG - skygw_log_write(LOGFILE_DEBUG, "tee.c: %d orphans freed.", o_freed); + MXS_DEBUG("tee.c: %d orphans freed.", o_freed); #endif } @@ -358,9 +358,8 @@ int i; { if (options) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "tee: The tee filter has been passed an option, " - "this filter does not support any options.\n"))); + MXS_ERROR("tee: The tee filter has been passed an option, " + "this filter does not support any options."); } my_instance->service = NULL; my_instance->source = NULL; @@ -375,11 +374,8 @@ int i; { if ((my_instance->service = service_find(params[i]->value)) == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "tee: service '%s' " - "not found.\n", - params[i]->value))); + MXS_ERROR("tee: service '%s' not found.\n", + params[i]->value); } } else if (!strcmp(params[i]->name, "match")) @@ -396,10 +392,8 @@ int i; my_instance->userName = strdup(params[i]->value); else if (!filter_standard_parameter(params[i]->name)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "tee: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("tee: Unexpected parameter '%s'.", + params[i]->name); } } } @@ -414,29 +408,27 @@ int i; if (my_instance->match && regcomp(&my_instance->re, my_instance->match, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "tee: Invalid regular expression '%s'" - " for the match parameter.\n", - my_instance->match))); - free(my_instance->match); - free(my_instance->source); - free(my_instance); - return NULL; + MXS_ERROR("tee: Invalid regular expression '%s'" + " for the match parameter.", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + free(my_instance); + return NULL; } if (my_instance->nomatch && regcomp(&my_instance->nore, my_instance->nomatch, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "tee: Invalid regular expression '%s'" - " for the nomatch paramter.\n", - my_instance->match))); - if (my_instance->match) - regfree(&my_instance->re); - free(my_instance->match); - free(my_instance->source); - free(my_instance); - return NULL; + MXS_ERROR("tee: Invalid regular expression '%s'" + " for the nomatch paramter.\n", + my_instance->match); + if (my_instance->match) + regfree(&my_instance->re); + free(my_instance->match); + free(my_instance->source); + free(my_instance); + return NULL; } } return (FILTER *)my_instance; @@ -460,11 +452,10 @@ char *remote, *userName; if (strcmp(my_instance->service->name, session->service->name) == 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : %s: Recursive use of tee filter in service.", - session->service->name))); - my_session = NULL; - goto retblock; + MXS_ERROR("%s: Recursive use of tee filter in service.", + session->service->name); + my_session = NULL; + goto retblock; } HASHTABLE* ht = hashtable_alloc(100,simple_str_hash,strcmp); @@ -473,11 +464,10 @@ char *remote, *userName; if(is_loop) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : %s: Recursive use of tee filter in service.", - session->service->name))); - my_session = NULL; - goto retblock; + MXS_ERROR("%s: Recursive use of tee filter in service.", + session->service->name); + my_session = NULL; + goto retblock; } if ((my_session = calloc(1, sizeof(TEE_SESSION))) != NULL) @@ -497,9 +487,7 @@ char *remote, *userName; { my_session->active = 0; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : Tee filter is not active."))); + MXS_WARNING("Tee filter is not active."); } } userName = session_getUser(session); @@ -510,9 +498,7 @@ char *remote, *userName; { my_session->active = 0; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Warning : Tee filter is not active."))); + MXS_WARNING("Tee filter is not active."); } if (my_session->active) @@ -527,10 +513,8 @@ char *remote, *userName; freeSession(instance, (void *)my_session); my_session = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Creating client DCB for Tee " - "filter failed. Terminating session."))); + MXS_ERROR("Creating client DCB for Tee " + "filter failed. Terminating session."); goto retblock; } @@ -540,11 +524,9 @@ char *remote, *userName; dcb_close(dcb); freeSession(instance, (void *)my_session); my_session = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : tee: Allocating memory for " - "dummy filter definition failed." - " Terminating session."))); + MXS_ERROR("tee: Allocating memory for " + "dummy filter definition failed." + " Terminating session."); goto retblock; } @@ -557,10 +539,8 @@ char *remote, *userName; dcb_close(dcb); freeSession(instance, (void *)my_session); my_session = NULL; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Creating client session for Tee " - "filter failed. Terminating session."))); + MXS_ERROR("Creating client session for Tee " + "filter failed. Terminating session."); goto retblock; } @@ -580,11 +560,9 @@ char *remote, *userName; closeSession(instance,(void*)my_session); dcb_close(dcb); free(my_session); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : tee: Allocating memory for" - "dummy upstream failed." - " Terminating session."))); + MXS_ERROR("tee: Allocating memory for" + "dummy upstream failed." + " Terminating session."); return NULL; } @@ -616,7 +594,7 @@ ROUTER_OBJECT *router; void *router_instance, *rsession; SESSION *bsession; #ifdef SS_DEBUG -skygw_log_write(LOGFILE_TRACE,"Tee close: %d", atomic_add(&debug_seq,1)); +MXS_INFO("Tee close: %d", atomic_add(&debug_seq,1)); #endif if (my_session->active) { @@ -649,7 +627,7 @@ skygw_log_write(LOGFILE_TRACE,"Tee close: %d", atomic_add(&debug_seq,1)); my_session->client_dcb && my_session->client_dcb->state == DCB_STATE_POLLING) { - skygw_log_write(LOGFILE_TRACE,"Tee session closed mid-query."); + MXS_INFO("Tee session closed mid-query."); GWBUF* errbuf = modutil_create_mysql_err_msg(1,0,1,"00000","Session closed."); my_session->client_dcb->func.write(my_session->client_dcb,errbuf); } @@ -673,7 +651,7 @@ TEE_SESSION *my_session = (TEE_SESSION *)session; SESSION* ses = my_session->branch_session; session_state_t state; #ifdef SS_DEBUG -skygw_log_write(LOGFILE_TRACE,"Tee free: %d", atomic_add(&debug_seq,1)); +MXS_INFO("Tee free: %d", atomic_add(&debug_seq,1)); #endif if (ses != NULL) { @@ -772,9 +750,10 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) *((unsigned char*)queue->start + 4) : 1; #ifdef SS_DEBUG - skygw_log_write(LOGFILE_TRACE,"Tee routeQuery: %d : %s", - atomic_add(&debug_seq,1), - ((char*)queue->start + 5)); + int prev_debug_seq = atomic_add(&debug_seq,1); + MXS_INFO("Tee routeQuery: %d : %s", + prev_debug_seq, + ((char*)queue->start + 5)); #endif @@ -782,7 +761,7 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue) if(!my_session->active) { - skygw_log_write(LOGFILE_TRACE, "Tee: Received a reply when the session was closed."); + MXS_INFO("Tee: Received a reply when the session was closed."); gwbuf_free(queue); spinlock_release(&my_session->tee_lock); return 0; @@ -909,19 +888,20 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) int min_eof = my_session->command != 0x04 ? 2 : 1; int more_results = 0; #ifdef SS_DEBUG + int prev_debug_seq = atomic_add(&debug_seq,1); ptr = (unsigned char*) reply->start; - skygw_log_write(LOGFILE_TRACE,"Tee clientReply [%s] [%s] [%s]: %d", - instance ? "parent":"child", - my_session->active ? "open" : "closed", - PTR_IS_ERR(ptr) ? "ERR" : PTR_IS_OK(ptr) ? "OK" : "RSET", - atomic_add(&debug_seq,1)); + MXS_INFO("Tee clientReply [%s] [%s] [%s]: %d", + instance ? "parent":"child", + my_session->active ? "open" : "closed", + PTR_IS_ERR(ptr) ? "ERR" : PTR_IS_OK(ptr) ? "OK" : "RSET", + prev_debug_seq); #endif spinlock_acquire(&my_session->tee_lock); if(!my_session->active) { - skygw_log_write(LOGFILE_TRACE,"Tee: Failed to return reply, session is closed"); + MXS_INFO("Tee: Failed to return reply, session is closed"); gwbuf_free(reply); rc = 0; if(my_session->waiting[PARENT]) @@ -944,8 +924,8 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(complete == NULL) { /** Incomplete packet */ - skygw_log_write(LOGFILE_DEBUG,"tee.c: Incomplete packet, " - "waiting for a complete packet before forwarding."); + MXS_DEBUG("tee.c: Incomplete packet, " + "waiting for a complete packet before forwarding."); rc = 1; goto retblock; } @@ -963,7 +943,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(my_session->replies[branch] == 0) { - skygw_log_write(LOGFILE_TRACE,"Tee: First reply to a query for [%s].",branch == PARENT ? "PARENT":"CHILD"); + MXS_INFO("Tee: First reply to a query for [%s].",branch == PARENT ? "PARENT":"CHILD"); /* Reply is in a single packet if it is an OK, ERR or LOCAL_INFILE packet. * Otherwise the reply is a result set and the amount of packets is unknown. */ @@ -978,17 +958,16 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) more_results = (flags & 0x08) && my_session->client_multistatement; if(more_results) { - skygw_log_write(LOGFILE_TRACE, - "Tee: [%s] waiting for more results.",branch == PARENT ? "PARENT":"CHILD"); + MXS_INFO("Tee: [%s] waiting for more results.",branch == PARENT ? "PARENT":"CHILD"); } } } #ifdef SS_DEBUG else { - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c: [%ld] Waiting for a result set from %s session.", - my_session->d_id, - branch == PARENT?"parent":"child"); + MXS_DEBUG("tee.c: [%ld] Waiting for a result set from %s session.", + my_session->d_id, + branch == PARENT?"parent":"child"); } #endif } @@ -1002,9 +981,9 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(my_session->eof[branch] >= min_eof) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c [%ld] %s received last EOF packet", - my_session->d_id, - branch == PARENT?"parent":"child"); + MXS_DEBUG("tee.c [%ld] %s received last EOF packet", + my_session->d_id, + branch == PARENT?"parent":"child"); #endif my_session->waiting[branch] = more_results; if(more_results) @@ -1035,7 +1014,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) rc = 0; gwbuf_free(my_session->tee_replybuf); my_session->tee_replybuf = NULL; - skygw_log_write_flush(LOGFILE_ERROR,"Error : Tee child session was closed."); + MXS_ERROR("Tee child session was closed."); } if(mpkt) @@ -1051,7 +1030,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) { route = true; #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%ld] Routing final packet of response set.",my_session->d_id); + MXS_DEBUG("tee.c:[%ld] Routing final packet of response set.",my_session->d_id); #endif } } @@ -1059,7 +1038,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) !my_session->waiting[CHILD]) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG,"tee.c:[%ld] Routing single packet response.",my_session->d_id); + MXS_DEBUG("tee.c:[%ld] Routing single packet response.",my_session->d_id); #endif route = true; } @@ -1068,8 +1047,8 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) if(route) { #ifdef SS_DEBUG - skygw_log_write_flush(LOGFILE_DEBUG, "tee.c:[%ld] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" - " child(waiting [%s] replies[%d] eof [%d])", + MXS_DEBUG("tee.c:[%ld] Routing buffer '%p' parent(waiting [%s] replies [%d] eof[%d])" + " child(waiting [%s] replies[%d] eof [%d])", my_session->d_id, my_session->tee_replybuf, my_session->waiting[PARENT] ? "true":"false", @@ -1094,7 +1073,7 @@ clientReply (FILTER* instance, void *session, GWBUF *reply) GWBUF* clone = clone_query(my_session->instance,my_session,buffer); reset_session_state(my_session,buffer); route_single_query(my_session->instance,my_session,buffer,clone); - LOGIF(LT,(skygw_log_write(LT,"tee: routing queued query"))); + MXS_INFO("tee: routing queued query"); } @@ -1314,9 +1293,7 @@ int route_single_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF /** Close tee session */ my_session->active = 0; rval = 0; - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Closed tee filter session: Child session in invalid state."))); + MXS_INFO("Closed tee filter session: Child session in invalid state."); gwbuf_free(clone); } } @@ -1324,9 +1301,7 @@ int route_single_query(TEE_INSTANCE* my_instance, TEE_SESSION* my_session, GWBUF { if (my_session->active) { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Closed tee filter session: Child session is NULL."))); + MXS_INFO("Closed tee filter session: Child session is NULL."); my_session->active = 0; rval = 0; } @@ -1352,8 +1327,8 @@ int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer) { case 0x1b: my_session->client_multistatement = *((unsigned char*) buffer->start + 5); - LOGIF(LT,(skygw_log_write(LT,"Tee: client %s multistatements", - my_session->client_multistatement ? "enabled":"disabled"))); + MXS_INFO("tee: client %s multistatements", + my_session->client_multistatement ? "enabled":"disabled"); case 0x03: case 0x16: case 0x17: @@ -1380,9 +1355,9 @@ void create_orphan(SESSION* ses) orphan_session_t* orphan; if((orphan = malloc(sizeof(orphan_session_t))) == NULL) { - skygw_log_write(LOGFILE_ERROR,"Error : Failed to " - "allocate memory for orphan session struct, " - "child session might leak memory."); + MXS_ERROR("Failed to " + "allocate memory for orphan session struct, " + "child session might leak memory."); }else{ orphan->session = ses; spinlock_acquire(&orphanLock); diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index 0b8510263..12d0e40a8 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -23,7 +23,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ if(!(instance.head = calloc(1,sizeof(FILTERCHAIN)))) { printf("Error: Out of memory\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Out of memory\n"); + MXS_ERROR("Out of memory\n"); return 1; } @@ -57,7 +57,7 @@ int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ if(!(instance.thrpool = malloc(instance.thrcount * sizeof(pthread_t)))){ printf("Error: Out of memory\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Out of memory\n"); + MXS_ERROR("Out of memory\n"); return 1; } @@ -259,7 +259,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue) }else{ printf("Error: cannot allocate enough memory.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); + MXS_ERROR("cannot allocate enough memory.\n"); return 0; } @@ -342,14 +342,14 @@ int load_query() buffer = (char*)calloc(4092,sizeof(char)); if(buffer == NULL){ printf("Error: cannot allocate enough memory.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); + MXS_ERROR("cannot allocate enough memory.\n"); return 1; } query_list = calloc(qbuff_sz,sizeof(char*)); if(query_list == NULL){ printf("Error: cannot allocate enough memory.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); + MXS_ERROR("cannot allocate enough memory.\n"); free(buffer); return 1; } @@ -361,7 +361,7 @@ int load_query() char** tmpbuff = realloc(query_list,sizeof(char*)*qbuff_sz*2); if(tmpbuff == NULL){ printf("Error: cannot allocate enough memory.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); + MXS_ERROR("cannot allocate enough memory.\n"); rval = 1; goto retblock; } @@ -388,7 +388,7 @@ int load_query() if(tmpbff[i] == NULL) { printf("Error: cannot allocate a new buffer.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate a new buffer.\n"); + MXS_ERROR("cannot allocate a new buffer.\n"); int x; for(x = 0;xvalue); - skygw_log_write(LOGFILE_ERROR,"Error creating filter instance!\nModule: %s\n",item->value); + MXS_ERROR("Error creating filter instance!\nModule: %s\n",item->value); config_ok = 0; goto cleanup; @@ -737,8 +737,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) if(fc->instance->setUpstream && fc->instance->clientReply){ fc->instance->setUpstream(fc->filter, fc->session[i], fc->up[i]); }else{ - skygw_log_write(LOGFILE_MESSAGE, - "Warning: The filter %s does not support client replies.\n",fc->name); + MXS_WARNING("The filter %s does not support client replies.\n",fc->name); } if(fc->next && fc->next->next){ @@ -821,7 +820,7 @@ FILTERCHAIN* load_filter_module(char* str) if( (flt_ptr->instance = (FILTER_OBJECT*)load_module(str, MODULE_FILTER)) == NULL) { printf("Error: Module loading failed: %s\n",str); - skygw_log_write(LOGFILE_ERROR,"Error: Module loading failed: %s\n",str); + MXS_ERROR("Module loading failed: %s\n",str); free(flt_ptr->down); free(flt_ptr); return NULL; diff --git a/server/modules/filter/test/harness_ui.c b/server/modules/filter/test/harness_ui.c index b92182a37..4f84a8600 100644 --- a/server/modules/filter/test/harness_ui.c +++ b/server/modules/filter/test/harness_ui.c @@ -10,7 +10,7 @@ int main(int argc, char** argv){ if(harness_init(argc,argv,&hinstance)){ printf("Error: Initialization failed.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); + MXS_ERROR("Initialization failed.\n"); mxs_log_finish(); return 1; } @@ -48,7 +48,7 @@ int main(int argc, char** argv){ tmp_chn = load_filter_module(tk); if(!tmp_chn || !load_filter(tmp_chn,instance.conf)){ printf("Error creating filter instance.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Error creating filter instance.\n"); + MXS_ERROR("Error creating filter instance.\n"); }else{ instance.head = tmp_chn; } @@ -180,7 +180,7 @@ int main(int argc, char** argv){ if(!(t_thr_pool = realloc(instance.thrpool,instance.thrcount * sizeof(pthread_t)))){ printf("Error: Out of memory\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Out of memory\n"); + MXS_ERROR("Out of memory\n"); instance.running = 0; break; } @@ -348,7 +348,7 @@ void manual_query() qlen = strnlen(query, 1024); if((tmpbuf = malloc(sizeof(GWBUF*)))== NULL){ printf("Error: cannot allocate enough memory.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: cannot allocate enough memory.\n"); + MXS_ERROR("Cannot allocate enough memory.\n"); return; } instance.buffer = tmpbuf; diff --git a/server/modules/filter/test/harness_util.c b/server/modules/filter/test/harness_util.c index 16d10c8c4..c23e8c192 100644 --- a/server/modules/filter/test/harness_util.c +++ b/server/modules/filter/test/harness_util.c @@ -34,7 +34,7 @@ int main(int argc,char** argv) if(harness_init(argc,argv,&inst) || inst->error){ printf("Error: Initialization failed.\n"); - skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); + MXS_ERROR("Initialization failed.\n"); mxs_log_finish(); return 1; } diff --git a/server/modules/filter/topfilter.c b/server/modules/filter/topfilter.c index a8089b830..457375a83 100644 --- a/server/modules/filter/topfilter.c +++ b/server/modules/filter/topfilter.c @@ -217,48 +217,43 @@ TOPN_INSTANCE *my_instance; my_instance->user = strdup(params[i]->value); else if (!filter_standard_parameter(params[i]->name)) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "topfilter: Unexpected parameter '%s'.\n", - params[i]->name))); + MXS_ERROR("topfilter: Unexpected parameter '%s'.", + params[i]->name); } } if (options) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "topfilter: Options are not supported by this " - " filter. They will be ignored\n"))); + MXS_ERROR("topfilter: Options are not supported by this " + " filter. They will be ignored."); } my_instance->sessions = 0; if (my_instance->match && regcomp(&my_instance->re, my_instance->match, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "topfilter: Invalid regular expression '%s'" - " for the match parameter.\n", - my_instance->match))); - free(my_instance->match); - free(my_instance->source); - free(my_instance->user); - free(my_instance->filebase); - free(my_instance); - return NULL; + MXS_ERROR("topfilter: Invalid regular expression '%s'" + " for the match parameter.", + my_instance->match); + free(my_instance->match); + free(my_instance->source); + free(my_instance->user); + free(my_instance->filebase); + free(my_instance); + return NULL; } if (my_instance->exclude && regcomp(&my_instance->exre, my_instance->exclude, REG_ICASE)) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "qlafilter: Invalid regular expression '%s'" - " for the nomatch paramter.\n", - my_instance->match))); - regfree(&my_instance->re); - free(my_instance->match); - free(my_instance->source); - free(my_instance->user); - free(my_instance->filebase); - free(my_instance); - return NULL; + MXS_ERROR("qlafilter: Invalid regular expression '%s'" + " for the nomatch paramter.\n", + my_instance->match); + regfree(&my_instance->re); + free(my_instance->match); + free(my_instance->source); + free(my_instance->user); + free(my_instance->filebase); + free(my_instance); + return NULL; } } return (FILTER *)my_instance; From 797d9dc03d47f4cddc4dfbb188c7712eef7e54dd Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 14:05:57 +0200 Subject: [PATCH 172/179] Ndbclustermon formatting changes Fixed indentation, bracket alignment and other minor things. --- server/modules/monitor/ndbclustermon.c | 518 +++++++++++++------------ 1 file changed, 265 insertions(+), 253 deletions(-) diff --git a/server/modules/monitor/ndbclustermon.c b/server/modules/monitor/ndbclustermon.c index ea9de889f..71005b8ec 100644 --- a/server/modules/monitor/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon.c @@ -33,26 +33,26 @@ #include -static void monitorMain(void *); +static void monitorMain(void *); static char *version_str = "V2.1.0"; -MODULE_INFO info = { - MODULE_API_MONITOR, - MODULE_BETA_RELEASE, - MONITOR_VERSION, - "A MySQL cluster SQL node monitor" +MODULE_INFO info = { + MODULE_API_MONITOR, + MODULE_BETA_RELEASE, + MONITOR_VERSION, + "A MySQL cluster SQL node monitor" }; -static void *startMonitor(void *,void*); -static void stopMonitor(void *); -static void diagnostics(DCB *, void *); +static void *startMonitor(void *, void*); +static void stopMonitor(void *); +static void diagnostics(DCB *, void *); bool isNdbEvent(monitor_event_t event); -static MONITOR_OBJECT MyObject = { - startMonitor, - stopMonitor, - diagnostics +static MONITOR_OBJECT MyObject = { + startMonitor, + stopMonitor, + diagnostics }; /** @@ -63,7 +63,7 @@ static MONITOR_OBJECT MyObject = { char * version() { - return version_str; + return version_str; } /** @@ -73,10 +73,10 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise the MySQL Cluster Monitor module %s.\n", - version_str))); + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "Initialise the MySQL Cluster Monitor module %s.\n", + version_str))); } /** @@ -90,7 +90,7 @@ ModuleInit() MONITOR_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -100,65 +100,72 @@ GetModuleObject() * * @return A handle to use when interacting with the monitor */ -static void * -startMonitor(void *arg,void* opt) +static void * +startMonitor(void *arg, void* opt) { - MONITOR* mon = (MONITOR*)arg; + MONITOR* mon = (MONITOR*) arg; MYSQL_MONITOR *handle = mon->handle; - CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - bool have_events = false,script_error = false; + CONFIG_PARAMETER* params = (CONFIG_PARAMETER*) opt; + bool have_events = false, script_error = false; if (handle != NULL) { - handle->shutdown = 0; + handle->shutdown = 0; } else { - if ((handle = (MYSQL_MONITOR *)malloc(sizeof(MYSQL_MONITOR))) == NULL) - return NULL; - handle->shutdown = 0; - handle->id = MONITOR_DEFAULT_ID; - handle->script = NULL; - handle->master = NULL; - memset(handle->events,false,sizeof(handle->events)); - spinlock_init(&handle->lock); - } - while(params) - { - if(!strcmp(params->name,"script")) - { - if (externcmd_can_execute(params->value)) + if ((handle = (MYSQL_MONITOR *) malloc(sizeof(MYSQL_MONITOR))) == NULL) { - free(handle->script); - handle->script = strdup(params->value); + return NULL; } - else - { - script_error = true; - } - } - else if(!strcmp(params->name,"events")) - { - if(mon_parse_event_string((bool*)&handle->events,sizeof(handle->events),params->value) != 0) - script_error = true; - else - have_events = true; - } - params = params->next; + handle->shutdown = 0; + handle->id = MONITOR_DEFAULT_ID; + handle->script = NULL; + handle->master = NULL; + memset(handle->events, false, sizeof(handle->events)); + spinlock_init(&handle->lock); } - if(script_error) + while (params) { - skygw_log_write(LE,"Error: Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.",mon->name); - free(handle->script); - handle->script = NULL; + if (!strcmp(params->name, "script")) + { + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } + } + else if (!strcmp(params->name, "events")) + { + if (mon_parse_event_string((bool*) &handle->events, + sizeof(handle->events), params->value) != 0) + { + script_error = true; + } + else + { + have_events = true; + } + } + params = params->next; + } + if (script_error) + { + skygw_log_write(LE, "Error: Errors were found in the script configuration parameters " + "for the monitor '%s'. The script will not be used.", mon->name); + free(handle->script); + handle->script = NULL; } /** If no specific events are given, enable them all */ - if(!have_events) + if (!have_events) { - memset(handle->events,true,sizeof(handle->events)); + memset(handle->events, true, sizeof(handle->events)); } - handle->tid = (THREAD)thread_start(monitorMain, mon); + handle->tid = (THREAD) thread_start(monitorMain, mon); return handle; } @@ -167,14 +174,14 @@ startMonitor(void *arg,void* opt) * * @param arg Handle on thr running monior */ -static void +static void stopMonitor(void *arg) { - MONITOR* mon = (MONITOR*)arg; -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; + MONITOR* mon = (MONITOR*) arg; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) mon->handle; - handle->shutdown = 1; - thread_wait((void *)handle->tid); + handle->shutdown = 1; + thread_wait((void *) handle->tid); } /** @@ -187,38 +194,38 @@ static void diagnostics(DCB *dcb, void *arg) { MONITOR* mon = arg; -MYSQL_MONITOR *handle = (MYSQL_MONITOR *)mon->handle; -MONITOR_SERVERS *db; -char *sep; + MYSQL_MONITOR *handle = (MYSQL_MONITOR *) mon->handle; + MONITOR_SERVERS *db; + char *sep; - switch (handle->status) - { - case MONITOR_RUNNING: - dcb_printf(dcb, "\tMonitor running\n"); - break; - case MONITOR_STOPPING: - dcb_printf(dcb, "\tMonitor stopping\n"); - break; - case MONITOR_STOPPED: - dcb_printf(dcb, "\tMonitor stopped\n"); - break; - } + switch (handle->status) + { + case MONITOR_RUNNING: + dcb_printf(dcb, "\tMonitor running\n"); + break; + case MONITOR_STOPPING: + dcb_printf(dcb, "\tMonitor stopping\n"); + break; + case MONITOR_STOPPED: + dcb_printf(dcb, "\tMonitor stopped\n"); + break; + } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); - dcb_printf(dcb,"\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); - dcb_printf(dcb,"\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); - dcb_printf(dcb,"\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); - dcb_printf(dcb, "\tMonitored servers: "); + dcb_printf(dcb, "\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb, "\tConnect Timeout:\t%i seconds\n", mon->connect_timeout); + dcb_printf(dcb, "\tRead Timeout:\t\t%i seconds\n", mon->read_timeout); + dcb_printf(dcb, "\tWrite Timeout:\t\t%i seconds\n", mon->write_timeout); + dcb_printf(dcb, "\tMonitored servers: "); - db = mon->databases; - sep = ""; - while (db) - { - dcb_printf(dcb, "%s%s:%d", sep, db->server->name, db->server->port); - sep = ", "; - db = db->next; - } - dcb_printf(dcb, "\n"); + db = mon->databases; + sep = ""; + while (db) + { + dcb_printf(dcb, "%s%s:%d", sep, db->server->name, db->server->port); + sep = ", "; + db = db->next; + } + dcb_printf(dcb, "\n"); } /** @@ -227,16 +234,18 @@ char *sep; * @param database The database to probe */ static void -monitorDatabase(MONITOR_SERVERS *database, char *defaultUser, char *defaultPasswd, MONITOR *mon) +monitorDatabase(MONITOR_SERVERS *database, char *defaultUser, char *defaultPasswd, MONITOR *mon) { -MYSQL_ROW row; -MYSQL_RES *result; -int isjoined = 0; -char *server_string; + MYSQL_ROW row; + MYSQL_RES *result; + int isjoined = 0; + char *server_string; /* Don't even probe server flagged as in maintenance */ if (SERVER_IN_MAINT(database->server)) + { return; + } connect_result_t rval = mon_connect_to_db(mon, database); if (rval != MONITOR_CONN_OK) @@ -258,69 +267,72 @@ char *server_string; } server_clear_status(database->server, SERVER_AUTH_ERROR); - /* If we get this far then we have a working connection */ - server_set_status(database->server, SERVER_RUNNING); + /* If we get this far then we have a working connection */ + server_set_status(database->server, SERVER_RUNNING); - /* get server version string */ - server_string = (char *)mysql_get_server_info(database->con); + /* get server version string */ + server_string = (char *) mysql_get_server_info(database->con); if (server_string) { server_set_version_string(database->server, server_string); } - /* Check if the the SQL node is able to contact one or more data nodes */ - if (mysql_query(database->con, "SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } + /* Check if the the SQL node is able to contact one or more data nodes */ + if (mysql_query(database->con, "SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW STATUS LIKE 'Ndb_number_of_ready_data_nodes'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } - while ((row = mysql_fetch_row(result))) - { - if (atoi(row[1]) > 0) - isjoined = 1; - } - mysql_free_result(result); - } + while ((row = mysql_fetch_row(result))) + { + if (atoi(row[1]) > 0) + isjoined = 1; + } + mysql_free_result(result); + } - /* Check the the SQL node id in the MySQL cluster */ - if (mysql_query(database->con, "SHOW STATUS LIKE 'Ndb_cluster_node_id'") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW STATUS LIKE 'Ndb_cluster_node_id'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } + /* Check the the SQL node id in the MySQL cluster */ + if (mysql_query(database->con, "SHOW STATUS LIKE 'Ndb_cluster_node_id'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW STATUS LIKE 'Ndb_cluster_node_id'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } - long cluster_node_id = -1; - while ((row = mysql_fetch_row(result))) - { - cluster_node_id = strtol(row[1], NULL, 10); - if ((errno == ERANGE && (cluster_node_id == LONG_MAX - || cluster_node_id == LONG_MIN)) || (errno != 0 && cluster_node_id == 0)) - { - cluster_node_id = -1; - } - database->server->node_id = cluster_node_id; - } - mysql_free_result(result); - } + long cluster_node_id = -1; + while ((row = mysql_fetch_row(result))) + { + cluster_node_id = strtol(row[1], NULL, 10); + if ((errno == ERANGE && (cluster_node_id == LONG_MAX + || cluster_node_id == LONG_MIN)) || (errno != 0 && cluster_node_id == 0)) + { + cluster_node_id = -1; + } + database->server->node_id = cluster_node_id; + } + mysql_free_result(result); + } - if (isjoined) { - server_set_status(database->server, SERVER_NDB); - database->server->depth = 0; - } else { - server_clear_status(database->server, SERVER_NDB); - database->server->depth = -1; - } + if (isjoined) + { + server_set_status(database->server, SERVER_NDB); + database->server->depth = 0; + } + else + { + server_clear_status(database->server, SERVER_NDB); + database->server->depth = -1; + } } /** @@ -332,114 +344,114 @@ static void monitorMain(void *arg) { MONITOR* mon = arg; -MYSQL_MONITOR *handle; -MONITOR_SERVERS *ptr; -size_t nrounds = 0; + MYSQL_MONITOR *handle; + MONITOR_SERVERS *ptr; + size_t nrounds = 0; -spinlock_acquire(&mon->lock); -handle = (MYSQL_MONITOR *)mon->handle; -spinlock_release(&mon->lock); + spinlock_acquire(&mon->lock); + handle = (MYSQL_MONITOR *) mon->handle; + spinlock_release(&mon->lock); - if (mysql_thread_init()) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Fatal : mysql_thread_init failed in monitor " - "module. Exiting.\n"))); - return; - } - handle->status = MONITOR_RUNNING; - - while (1) - { - if (handle->shutdown) - { - handle->status = MONITOR_STOPPING; - mysql_thread_end(); - handle->status = MONITOR_STOPPED; - return; - } + if (mysql_thread_init()) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Fatal : mysql_thread_init failed in monitor " + "module. Exiting.\n"))); + return; + } + handle->status = MONITOR_RUNNING; - /** Wait base interval */ - thread_millisleep(MON_BASE_INTERVAL_MS); - /** - * Calculate how far away the monitor interval is from its full - * cycle and if monitor interval time further than the base - * interval, then skip monitoring checks. Excluding the first - * round. - */ - if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= - MON_BASE_INTERVAL_MS) - { - nrounds += 1; - continue; - } - nrounds += 1; - ptr = mon->databases; + while (1) + { + if (handle->shutdown) + { + handle->status = MONITOR_STOPPING; + mysql_thread_end(); + handle->status = MONITOR_STOPPED; + return; + } - while (ptr) - { - ptr->mon_prev_status = ptr->server->status; - monitorDatabase(ptr, mon->user, mon->password,mon); + /** Wait base interval */ + thread_millisleep(MON_BASE_INTERVAL_MS); + /** + * Calculate how far away the monitor interval is from its full + * cycle and if monitor interval time further than the base + * interval, then skip monitoring checks. Excluding the first + * round. + */ + if (nrounds != 0 && + ((nrounds * MON_BASE_INTERVAL_MS) % mon->interval) >= + MON_BASE_INTERVAL_MS) + { + nrounds += 1; + continue; + } + nrounds += 1; + ptr = mon->databases; - if (ptr->server->status != ptr->mon_prev_status || - SERVER_IS_DOWN(ptr->server)) - { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Backend server %s:%d state : %s", - ptr->server->name, - ptr->server->port, - STRSRVSTATUS(ptr->server)))); - } + while (ptr) + { + ptr->mon_prev_status = ptr->server->status; + monitorDatabase(ptr, mon->user, mon->password, mon); - ptr = ptr->next; - } + if (ptr->server->status != ptr->mon_prev_status || + SERVER_IS_DOWN(ptr->server)) + { + LOGIF(LD, (skygw_log_write_flush( + LOGFILE_DEBUG, + "Backend server %s:%d state : %s", + ptr->server->name, + ptr->server->port, + STRSRVSTATUS(ptr->server)))); + } - ptr = mon->databases; - monitor_event_t evtype; + ptr = ptr->next; + } - while(ptr) - { - /** Execute monitor script if a server state has changed */ - if(mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if(isNdbEvent(evtype)) - { - skygw_log_write(LOGFILE_TRACE,"Server changed state: %s[%s:%u]: %s", - ptr->server->unique_name, - ptr->server->name,ptr->server->port, - mon_get_event_name(ptr)); - if(handle->script && handle->events[evtype]) - { - monitor_launch_script(mon,ptr,handle->script); - } - } - } - ptr = ptr->next; - } - } + ptr = mon->databases; + monitor_event_t evtype; + + while (ptr) + { + /** Execute monitor script if a server state has changed */ + if (mon_status_changed(ptr)) + { + evtype = mon_get_event_type(ptr); + if (isNdbEvent(evtype)) + { + skygw_log_write(LOGFILE_TRACE, "Server changed state: %s[%s:%u]: %s", + ptr->server->unique_name, + ptr->server->name, ptr->server->port, + mon_get_event_name(ptr)); + if (handle->script && handle->events[evtype]) + { + monitor_launch_script(mon, ptr, handle->script); + } + } + } + ptr = ptr->next; + } + } } static monitor_event_t ndb_events[] = { - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - NDB_UP_EVENT, - NDB_DOWN_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - LOST_NDB_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - NEW_NDB_EVENT, - MAX_MONITOR_EVENT + MASTER_DOWN_EVENT, + MASTER_UP_EVENT, + SLAVE_DOWN_EVENT, + SLAVE_UP_EVENT, + SERVER_DOWN_EVENT, + SERVER_UP_EVENT, + NDB_UP_EVENT, + NDB_DOWN_EVENT, + LOST_MASTER_EVENT, + LOST_SLAVE_EVENT, + LOST_NDB_EVENT, + NEW_MASTER_EVENT, + NEW_SLAVE_EVENT, + NEW_NDB_EVENT, + MAX_MONITOR_EVENT }; /** @@ -450,10 +462,10 @@ static monitor_event_t ndb_events[] = { bool isNdbEvent(monitor_event_t event) { int i; - for(i = 0;ndb_events[i] != MAX_MONITOR_EVENT;i++) + for (i = 0; ndb_events[i] != MAX_MONITOR_EVENT; i++) { - if(event == ndb_events[i]) - return true; + if (event == ndb_events[i]) + return true; } return false; } From 6846b0b6b63969a29e1862ed12c046f26ccf900d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 14:03:42 +0200 Subject: [PATCH 173/179] Mmmon formatting changes Fixed indentation, bracket alignment and other minor things. --- server/modules/monitor/mmmon.c | 983 +++++++++++++++++---------------- 1 file changed, 515 insertions(+), 468 deletions(-) diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 7029c4691..4d18fa5ce 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -33,28 +33,30 @@ #include #include -static void monitorMain(void *); +static void monitorMain(void *); static char *version_str = "V1.1.1"; -MODULE_INFO info = { - MODULE_API_MONITOR, - MODULE_BETA_RELEASE, - MONITOR_VERSION, - "A Multi-Master Multi Master monitor" +MODULE_INFO info = +{ + MODULE_API_MONITOR, + MODULE_BETA_RELEASE, + MONITOR_VERSION, + "A Multi-Master Multi Master monitor" }; -static void *startMonitor(void *,void*); -static void stopMonitor(void *); -static void diagnostics(DCB *, void *); -static void detectStaleMaster(void *, int); +static void *startMonitor(void *, void*); +static void stopMonitor(void *); +static void diagnostics(DCB *, void *); +static void detectStaleMaster(void *, int); static MONITOR_SERVERS *get_current_master(MONITOR *); bool isMySQLEvent(monitor_event_t event); -static MONITOR_OBJECT MyObject = { - startMonitor, - stopMonitor, - diagnostics +static MONITOR_OBJECT MyObject = +{ + startMonitor, + stopMonitor, + diagnostics }; /** @@ -65,7 +67,7 @@ static MONITOR_OBJECT MyObject = { char * version() { - return version_str; + return version_str; } /** @@ -75,10 +77,10 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise the Multi-Master Monitor module %s.", - version_str))); + LOGIF(LM, (skygw_log_write( + LOGFILE_MESSAGE, + "Initialise the Multi-Master Monitor module %s.", + version_str))); } /** @@ -92,7 +94,7 @@ ModuleInit() MONITOR_OBJECT * GetModuleObject() { - return &MyObject; + return &MyObject; } /** @@ -103,71 +105,78 @@ GetModuleObject() * @param arg The current handle - NULL if first start * @return A handle to use when interacting with the monitor */ -static void * -startMonitor(void *arg,void* opt) +static void * +startMonitor(void *arg, void* opt) { - MONITOR* mon = (MONITOR*)arg; + MONITOR* mon = (MONITOR*) arg; MM_MONITOR *handle = mon->handle; - CONFIG_PARAMETER* params = (CONFIG_PARAMETER*)opt; - bool have_events = false,script_error = false; + CONFIG_PARAMETER* params = (CONFIG_PARAMETER*) opt; + bool have_events = false, script_error = false; if (handle) { - handle->shutdown = 0; + handle->shutdown = 0; } else { - if ((handle = (MM_MONITOR *)malloc(sizeof(MM_MONITOR))) == NULL) - return NULL; - handle->shutdown = 0; - handle->id = MONITOR_DEFAULT_ID; - handle->master = NULL; - handle->script = NULL; - handle->detectStaleMaster = false; - memset(handle->events,false,sizeof(handle->events)); - spinlock_init(&handle->lock); + if ((handle = (MM_MONITOR *) malloc(sizeof(MM_MONITOR))) == NULL) + { + return NULL; + } + handle->shutdown = 0; + handle->id = MONITOR_DEFAULT_ID; + handle->master = NULL; + handle->script = NULL; + handle->detectStaleMaster = false; + memset(handle->events, false, sizeof(handle->events)); + spinlock_init(&handle->lock); } - while(params) + while (params) { - if(!strcmp(params->name,"detect_stale_master")) - { - handle->detectStaleMaster = config_truth_value(params->value); - } - else if(!strcmp(params->name,"script")) - { - if (externcmd_can_execute(params->value)) + if (!strcmp(params->name, "detect_stale_master")) { - free(handle->script); - handle->script = strdup(params->value); + handle->detectStaleMaster = config_truth_value(params->value); } - else + else if (!strcmp(params->name, "script")) { - script_error = true; + if (externcmd_can_execute(params->value)) + { + free(handle->script); + handle->script = strdup(params->value); + } + else + { + script_error = true; + } } - } - else if(!strcmp(params->name,"events")) - { - if(mon_parse_event_string((bool*)&handle->events,sizeof(handle->events),params->value) != 0) - script_error = true; - else - have_events = true; - } - params = params->next; + else if (!strcmp(params->name, "events")) + { + if (mon_parse_event_string((bool*) & handle->events, + sizeof(handle->events), params->value) != 0) + { + script_error = true; + } + else + { + have_events = true; + } + } + params = params->next; } - if(script_error) + if (script_error) { - skygw_log_write(LE,"Error: Errors were found in the script configuration parameters " - "for the monitor '%s'. The script will not be used.",mon->name); - free(handle->script); - handle->script = NULL; + skygw_log_write(LE, "Error: Errors were found in the script configuration parameters " + "for the monitor '%s'. The script will not be used.", mon->name); + free(handle->script); + handle->script = NULL; } /** If no specific events are given, enable them all */ - if(!have_events) + if (!have_events) { - memset(handle->events,true,sizeof(handle->events)); + memset(handle->events, true, sizeof(handle->events)); } - handle->tid = (THREAD)thread_start(monitorMain, mon); + handle->tid = (THREAD) thread_start(monitorMain, mon); return handle; } @@ -176,14 +185,14 @@ startMonitor(void *arg,void* opt) * * @param arg Handle on thr running monior */ -static void +static void stopMonitor(void *arg) { MONITOR* mon = arg; - MM_MONITOR *handle = (MM_MONITOR *)mon->handle; + MM_MONITOR *handle = (MM_MONITOR *) mon->handle; - handle->shutdown = 1; - thread_wait((void *)handle->tid); + handle->shutdown = 1; + thread_wait((void *) handle->tid); } /** @@ -194,41 +203,41 @@ stopMonitor(void *arg) */ static void diagnostics(DCB *dcb, void *arg) { - MONITOR* mon = (MONITOR*)arg; -MM_MONITOR *handle = (MM_MONITOR *)mon->handle; -MONITOR_SERVERS *db; -char *sep; + MONITOR* mon = (MONITOR*) arg; + MM_MONITOR *handle = (MM_MONITOR *) mon->handle; + MONITOR_SERVERS *db; + char *sep; - switch (handle->status) - { - case MONITOR_RUNNING: - dcb_printf(dcb, "\tMonitor running\n"); - break; - case MONITOR_STOPPING: - dcb_printf(dcb, "\tMonitor stopping\n"); - break; - case MONITOR_STOPPED: - dcb_printf(dcb, "\tMonitor stopped\n"); - break; - } + switch (handle->status) + { + case MONITOR_RUNNING: + dcb_printf(dcb, "\tMonitor running\n"); + break; + case MONITOR_STOPPING: + dcb_printf(dcb, "\tMonitor stopping\n"); + break; + case MONITOR_STOPPED: + dcb_printf(dcb, "\tMonitor stopped\n"); + break; + } - dcb_printf(dcb,"\tSampling interval:\t%lu milliseconds\n", mon->interval); - dcb_printf(dcb,"\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); - dcb_printf(dcb, "\tMonitored servers: "); + dcb_printf(dcb, "\tSampling interval:\t%lu milliseconds\n", mon->interval); + dcb_printf(dcb, "\tDetect Stale Master:\t%s\n", (handle->detectStaleMaster == 1) ? "enabled" : "disabled"); + dcb_printf(dcb, "\tMonitored servers: "); - db = mon->databases; - sep = ""; - while (db) - { - dcb_printf(dcb, - "%s%s:%d", - sep, - db->server->name, - db->server->port); - sep = ", "; - db = db->next; - } - dcb_printf(dcb, "\n"); + db = mon->databases; + sep = ""; + while (db) + { + dcb_printf(dcb, + "%s%s:%d", + sep, + db->server->name, + db->server->port); + sep = ", "; + db = db->next; + } + dcb_printf(dcb, "\n"); } /** @@ -240,16 +249,18 @@ char *sep; static void monitorDatabase(MONITOR* mon, MONITOR_SERVERS *database) { -MYSQL_ROW row; -MYSQL_RES *result; -int isslave = 0; -int ismaster = 0; -unsigned long int server_version = 0; -char *server_string; + MYSQL_ROW row; + MYSQL_RES *result; + int isslave = 0; + int ismaster = 0; + unsigned long int server_version = 0; + char *server_string; /* Don't probe servers in maintenance mode */ if (SERVER_IN_MAINT(database->server)) + { return; + } /** Store previous status */ database->mon_prev_status = database->server->status; @@ -288,208 +299,228 @@ char *server_string; } /* Store current status in both server and monitor server pending struct */ - server_set_status(database->server, SERVER_RUNNING); - monitor_set_pending_status(database, SERVER_RUNNING); + server_set_status(database->server, SERVER_RUNNING); + monitor_set_pending_status(database, SERVER_RUNNING); - /* get server version from current server */ - server_version = mysql_get_server_version(database->con); + /* get server version from current server */ + server_version = mysql_get_server_version(database->con); - /* get server version string */ - server_string = (char *)mysql_get_server_info(database->con); + /* get server version string */ + server_string = (char *) mysql_get_server_info(database->con); if (server_string) { server_set_version_string(database->server, server_string); } - /* get server_id form current node */ - if (mysql_query(database->con, "SELECT @@server_id") == 0 - && (result = mysql_store_result(database->con)) != NULL) + /* get server_id form current node */ + if (mysql_query(database->con, "SELECT @@server_id") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + long server_id = -1; + + if (mysql_field_count(database->con) != 1) { - long server_id = -1; + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for 'SELECT @@server_id'. Expected 1 column." + " MySQL Version: %s", version_str); + return; + } - if(mysql_field_count(database->con) != 1) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for 'SELECT @@server_id'. Expected 1 column." - " MySQL Version: %s",version_str); - return; - } + while ((row = mysql_fetch_row(result))) + { + server_id = strtol(row[0], NULL, 10); + if ((errno == ERANGE && (server_id == LONG_MAX + || server_id == LONG_MIN)) || (errno != 0 && server_id == 0)) + { + server_id = -1; + } + database->server->node_id = server_id; + } + mysql_free_result(result); + } - while ((row = mysql_fetch_row(result))) - { - server_id = strtol(row[0], NULL, 10); - if ((errno == ERANGE && (server_id == LONG_MAX - || server_id == LONG_MIN)) || (errno != 0 && server_id == 0)) - { - server_id = -1; - } - database->server->node_id = server_id; - } + /* Check if the Slave_SQL_Running and Slave_IO_Running status is + * set to Yes + */ + + /* Check first for MariaDB 10.x.x and get status for multimaster replication */ + if (server_version >= 100000) + { + + if (mysql_query(database->con, "SHOW ALL SLAVES STATUS") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + int i = 0; + long master_id = -1; + + if (mysql_field_count(database->con) < 42) + { mysql_free_result(result); + skygw_log_write(LE, "Error: \"SHOW ALL SLAVES STATUS\" " + "returned less than the expected amount of columns. Expected 42 columns" + " MySQL Version: %s", version_str); + return; + } + + while ((row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + if (strncmp(row[12], "Yes", 3) == 0 + && strncmp(row[13], "Yes", 3) == 0) + { + isslave += 1; + } + + /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building + * the replication tree, slaves ids will be added to master(s) and we will have at least the + * root master server. + * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' + */ + if (strncmp(row[12], "Yes", 3) == 0) + { + /* get Master_Server_Id values */ + master_id = atol(row[41]); + if (master_id == 0) + { + master_id = -1; + } + } + + i++; + } + /* store master_id of current node */ + memcpy(&database->server->master_id, &master_id, sizeof(long)); + + mysql_free_result(result); + + /* If all configured slaves are running set this node as slave */ + if (isslave > 0 && isslave == i) + { + isslave = 1; + } + else + { + isslave = 0; + } } - - /* Check if the Slave_SQL_Running and Slave_IO_Running status is - * set to Yes - */ - - /* Check first for MariaDB 10.x.x and get status for multimaster replication */ - if (server_version >= 100000) { - - if (mysql_query(database->con, "SHOW ALL SLAVES STATUS") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - int i = 0; - long master_id = -1; - - if(mysql_field_count(database->con) < 42) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: \"SHOW ALL SLAVES STATUS\" " - "returned less than the expected amount of columns. Expected 42 columns" - " MySQL Version: %s",version_str); - return; - } - - while ((row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - if (strncmp(row[12], "Yes", 3) == 0 - && strncmp(row[13], "Yes", 3) == 0) { - isslave += 1; - } - - /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building - * the replication tree, slaves ids will be added to master(s) and we will have at least the - * root master server. - * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' - */ - if (strncmp(row[12], "Yes", 3) == 0) { - /* get Master_Server_Id values */ - master_id = atol(row[41]); - if (master_id == 0) - master_id = -1; - } - - i++; - } - /* store master_id of current node */ - memcpy(&database->server->master_id, &master_id, sizeof(long)); - - mysql_free_result(result); - - /* If all configured slaves are running set this node as slave */ - if (isslave > 0 && isslave == i) - isslave = 1; - else - isslave = 0; - } - } else { - if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - long master_id = -1; - - if(mysql_field_count(database->con) < 40) - { - mysql_free_result(result); - - if(server_version < 5*10000 + 5*100) - { - if(database->log_version_err) - { - skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" " - " for versions less than 5.5 does not have master_server_id, " - "replication tree cannot be resolved for server %s." - " MySQL Version: %s",database->server->unique_name,version_str); - database->log_version_err = false; - } - } - else - { - skygw_log_write(LE,"Error: \"SHOW SLAVE STATUS\" " - "returned less than the expected amount of columns. Expected 40 columns." - " MySQL Version: %s",version_str); - } - return; - } - - while ((row = mysql_fetch_row(result))) - { - /* get Slave_IO_Running and Slave_SQL_Running values*/ - if (strncmp(row[10], "Yes", 3) == 0 - && strncmp(row[11], "Yes", 3) == 0) { - isslave = 1; - } - - /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building - * the replication tree, slaves ids will be added to master(s) and we will have at least the - * root master server. - * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' - */ - if (strncmp(row[10], "Yes", 3) == 0) { - /* get Master_Server_Id values */ - master_id = atol(row[39]); - if (master_id == 0) - master_id = -1; - } - } - /* store master_id of current node */ - memcpy(&database->server->master_id, &master_id, sizeof(long)); - - mysql_free_result(result); - } - } - - /* get variable 'read_only' set by an external component */ - if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0 - && (result = mysql_store_result(database->con)) != NULL) - { - if(mysql_field_count(database->con) < 2) - { - mysql_free_result(result); - skygw_log_write(LE,"Error: Unexpected result for \"SHOW GLOBAL VARIABLES LIKE 'read_only'\". Expected 2 columns." - " MySQL Version: %s",version_str); - return; - } - - while ((row = mysql_fetch_row(result))) - { - if (strncasecmp(row[1], "OFF", 3) == 0) { - ismaster = 1; - } else { - isslave = 1; - } - } - mysql_free_result(result); - } - - /* Remove addition info */ - monitor_clear_pending_status(database, SERVER_STALE_STATUS); - - /* Set the Slave Role */ - if (isslave) - { - monitor_set_pending_status(database, SERVER_SLAVE); - /* Avoid any possible stale Master state */ - monitor_clear_pending_status(database, SERVER_MASTER); - - /* Set replication depth to 1 */ - database->server->depth = 1; - } else { - /* Avoid any possible Master/Slave stale state */ - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_clear_pending_status(database, SERVER_MASTER); - } - - /* Set the Master role */ - if (ismaster) + } + else + { + if (mysql_query(database->con, "SHOW SLAVE STATUS") == 0 + && (result = mysql_store_result(database->con)) != NULL) { - monitor_clear_pending_status(database, SERVER_SLAVE); - monitor_set_pending_status(database, SERVER_MASTER); + long master_id = -1; - /* Set replication depth to 0 */ - database->server->depth = 0; + if (mysql_field_count(database->con) < 40) + { + mysql_free_result(result); + + if (server_version < 5 * 10000 + 5 * 100) + { + if (database->log_version_err) + { + skygw_log_write(LE, "Error: \"SHOW SLAVE STATUS\" " + " for versions less than 5.5 does not have master_server_id, " + "replication tree cannot be resolved for server %s." + " MySQL Version: %s", database->server->unique_name, version_str); + database->log_version_err = false; + } + } + else + { + skygw_log_write(LE, "Error: \"SHOW SLAVE STATUS\" " + "returned less than the expected amount of columns. Expected 40 columns." + " MySQL Version: %s", version_str); + } + return; + } + + while ((row = mysql_fetch_row(result))) + { + /* get Slave_IO_Running and Slave_SQL_Running values*/ + if (strncmp(row[10], "Yes", 3) == 0 + && strncmp(row[11], "Yes", 3) == 0) + { + isslave = 1; + } + + /* If Slave_IO_Running = Yes, assign the master_id to current server: this allows building + * the replication tree, slaves ids will be added to master(s) and we will have at least the + * root master server. + * Please note, there could be no slaves at all if Slave_SQL_Running == 'No' + */ + if (strncmp(row[10], "Yes", 3) == 0) + { + /* get Master_Server_Id values */ + master_id = atol(row[39]); + if (master_id == 0) + { + master_id = -1; + } + } + } + /* store master_id of current node */ + memcpy(&database->server->master_id, &master_id, sizeof(long)); + + mysql_free_result(result); } + } + + /* get variable 'read_only' set by an external component */ + if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0 + && (result = mysql_store_result(database->con)) != NULL) + { + if (mysql_field_count(database->con) < 2) + { + mysql_free_result(result); + skygw_log_write(LE, "Error: Unexpected result for \"SHOW GLOBAL VARIABLES LIKE 'read_only'\". Expected 2 columns." + " MySQL Version: %s", version_str); + return; + } + + while ((row = mysql_fetch_row(result))) + { + if (strncasecmp(row[1], "OFF", 3) == 0) + { + ismaster = 1; + } + else + { + isslave = 1; + } + } + mysql_free_result(result); + } + + /* Remove addition info */ + monitor_clear_pending_status(database, SERVER_STALE_STATUS); + + /* Set the Slave Role */ + if (isslave) + { + monitor_set_pending_status(database, SERVER_SLAVE); + /* Avoid any possible stale Master state */ + monitor_clear_pending_status(database, SERVER_MASTER); + + /* Set replication depth to 1 */ + database->server->depth = 1; + } + else + { + /* Avoid any possible Master/Slave stale state */ + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_clear_pending_status(database, SERVER_MASTER); + } + + /* Set the Master role */ + if (ismaster) + { + monitor_clear_pending_status(database, SERVER_SLAVE); + monitor_set_pending_status(database, SERVER_MASTER); + + /* Set replication depth to 0 */ + database->server->depth = 0; + } } @@ -501,140 +532,144 @@ char *server_string; static void monitorMain(void *arg) { - MONITOR* mon = (MONITOR*)arg; -MM_MONITOR *handle; -MONITOR_SERVERS *ptr; -int detect_stale_master = false; -MONITOR_SERVERS *root_master = NULL; -size_t nrounds = 0; + MONITOR* mon = (MONITOR*) arg; + MM_MONITOR *handle; + MONITOR_SERVERS *ptr; + int detect_stale_master = false; + MONITOR_SERVERS *root_master = NULL; + size_t nrounds = 0; -spinlock_acquire(&mon->lock); -handle = (MM_MONITOR *)mon->handle; -spinlock_release(&mon->lock); -detect_stale_master = handle->detectStaleMaster; + spinlock_acquire(&mon->lock); + handle = (MM_MONITOR *) mon->handle; + spinlock_release(&mon->lock); + detect_stale_master = handle->detectStaleMaster; - if (mysql_thread_init()) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Fatal : mysql_thread_init failed in monitor " - "module. Exiting.\n"))); - return; - } + if (mysql_thread_init()) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Fatal : mysql_thread_init failed in monitor " + "module. Exiting.\n"))); + return; + } - handle->status = MONITOR_RUNNING; - while (1) - { - if (handle->shutdown) - { - handle->status = MONITOR_STOPPING; - mysql_thread_end(); - handle->status = MONITOR_STOPPED; - return; - } + handle->status = MONITOR_RUNNING; + while (1) + { + if (handle->shutdown) + { + handle->status = MONITOR_STOPPING; + mysql_thread_end(); + handle->status = MONITOR_STOPPED; + return; + } - /** Wait base interval */ - thread_millisleep(MON_BASE_INTERVAL_MS); - /** - * Calculate how far away the monitor interval is from its full - * cycle and if monitor interval time further than the base - * interval, then skip monitoring checks. Excluding the first - * round. - */ - if (nrounds != 0 && - ((nrounds*MON_BASE_INTERVAL_MS)%mon->interval) >= - MON_BASE_INTERVAL_MS) + /** Wait base interval */ + thread_millisleep(MON_BASE_INTERVAL_MS); + /** + * Calculate how far away the monitor interval is from its full + * cycle and if monitor interval time further than the base + * interval, then skip monitoring checks. Excluding the first + * round. + */ + if (nrounds != 0 && + ((nrounds * MON_BASE_INTERVAL_MS) % mon->interval) >= + MON_BASE_INTERVAL_MS) + { + nrounds += 1; + continue; + } + nrounds += 1; + + /* start from the first server in the list */ + ptr = mon->databases; + + while (ptr) + { + /* copy server status into monitor pending_status */ + ptr->pending_status = ptr->server->status; + + /* monitor current node */ + monitorDatabase(mon, ptr); + + if (mon_status_changed(ptr)) + { + dcb_hangup_foreach(ptr->server); + } + + if (mon_status_changed(ptr) || + mon_print_fail_status(ptr)) + { + LOGIF(LD, (skygw_log_write_flush( + LOGFILE_DEBUG, + "Backend server %s:%d state : %s", + ptr->server->name, + ptr->server->port, + STRSRVSTATUS(ptr->server)))); + } + if (SERVER_IS_DOWN(ptr->server)) + { + /** Increase this server'e error count */ + ptr->mon_err_count += 1; + } + else + { + /** Reset this server's error count */ + ptr->mon_err_count = 0; + } + + ptr = ptr->next; + } + + /* Get Master server pointer */ + root_master = get_current_master(mon); + + /* Update server status from monitor pending status on that server*/ + + ptr = mon->databases; + while (ptr) + { + if (!SERVER_IN_MAINT(ptr->server)) + { + /* If "detect_stale_master" option is On, let's use the previus master */ + if (detect_stale_master && root_master && (!strcmp(ptr->server->name, root_master->server->name) && ptr->server->port == root_master->server->port) && (ptr->server->status & SERVER_MASTER) && !(ptr->pending_status & SERVER_MASTER)) { - nrounds += 1; - continue; + /* in this case server->status will not be updated from pending_status */ + LOGIF(LM, (skygw_log_write_flush( + LOGFILE_MESSAGE, "[mysql_mon]: root server [%s:%i] is no longer Master, let's use it again even if it could be a stale master, you have been warned!", ptr->server->name, ptr->server->port))); + /* Set the STALE bit for this server in server struct */ + server_set_status(ptr->server, SERVER_STALE_STATUS); } - nrounds += 1; + else + { + ptr->server->status = ptr->pending_status; + } + } + ptr = ptr->next; + } - /* start from the first server in the list */ - ptr = mon->databases; - - while (ptr) - { - /* copy server status into monitor pending_status */ - ptr->pending_status = ptr->server->status; - - /* monitor current node */ - monitorDatabase(mon, ptr); - - if (mon_status_changed(ptr)) - { - dcb_hangup_foreach(ptr->server); - } - - if (mon_status_changed(ptr) || - mon_print_fail_status(ptr)) - { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Backend server %s:%d state : %s", - ptr->server->name, - ptr->server->port, - STRSRVSTATUS(ptr->server)))); - } - if (SERVER_IS_DOWN(ptr->server)) - { - /** Increase this server'e error count */ - ptr->mon_err_count += 1; - } - else - { - /** Reset this server's error count */ - ptr->mon_err_count = 0; - } - - ptr = ptr->next; - } - - /* Get Master server pointer */ - root_master = get_current_master(mon); - - /* Update server status from monitor pending status on that server*/ - - ptr = mon->databases; - while (ptr) - { - if (! SERVER_IN_MAINT(ptr->server)) { - /* If "detect_stale_master" option is On, let's use the previus master */ - if (detect_stale_master && root_master && (!strcmp(ptr->server->name, root_master->server->name) && ptr->server->port == root_master->server->port) && (ptr->server->status & SERVER_MASTER) && !(ptr->pending_status & SERVER_MASTER)) { - /* in this case server->status will not be updated from pending_status */ - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, "[mysql_mon]: root server [%s:%i] is no longer Master, let's use it again even if it could be a stale master, you have been warned!", ptr->server->name, ptr->server->port))); - /* Set the STALE bit for this server in server struct */ - server_set_status(ptr->server, SERVER_STALE_STATUS); - } else { - ptr->server->status = ptr->pending_status; - } - } - ptr = ptr->next; - } - - ptr = mon->databases; - monitor_event_t evtype; - while(ptr) - { - if(mon_status_changed(ptr)) - { - evtype = mon_get_event_type(ptr); - if(isMySQLEvent(evtype)) - { - skygw_log_write(LOGFILE_TRACE,"Server changed state: %s[%s:%u]: %s", - ptr->server->unique_name, - ptr->server->name,ptr->server->port, - mon_get_event_name(ptr)); - if(handle->script && handle->events[evtype]) - { - monitor_launch_script(mon,ptr,handle->script); - } - } - } - ptr = ptr->next; - } - } + ptr = mon->databases; + monitor_event_t evtype; + while (ptr) + { + if (mon_status_changed(ptr)) + { + evtype = mon_get_event_type(ptr); + if (isMySQLEvent(evtype)) + { + skygw_log_write(LOGFILE_TRACE, "Server changed state: %s[%s:%u]: %s", + ptr->server->unique_name, + ptr->server->name, ptr->server->port, + mon_get_event_name(ptr)); + if (handle->script && handle->events[evtype]) + { + monitor_launch_script(mon, ptr, handle->script); + } + } + } + ptr = ptr->next; + } + } } /** @@ -648,9 +683,9 @@ detect_stale_master = handle->detectStaleMaster; static void detectStaleMaster(void *arg, int enable) { - MONITOR* mon = (MONITOR*)arg; -MM_MONITOR *handle = (MM_MONITOR *)mon->handle; - memcpy(&handle->detectStaleMaster, &enable, sizeof(int)); + MONITOR* mon = (MONITOR*) arg; + MM_MONITOR *handle = (MM_MONITOR *) mon->handle; + memcpy(&handle->detectStaleMaster, &enable, sizeof(int)); } /******* @@ -663,61 +698,71 @@ MM_MONITOR *handle = (MM_MONITOR *)mon->handle; * @return The server at root level with SERVER_MASTER bit */ -static MONITOR_SERVERS *get_current_master(MONITOR *mon) { +static MONITOR_SERVERS *get_current_master(MONITOR *mon) +{ MM_MONITOR* handle = mon->handle; -MONITOR_SERVERS *ptr; + MONITOR_SERVERS *ptr; - ptr = mon->databases; + ptr = mon->databases; - while (ptr) - { - /* The server could be in SERVER_IN_MAINT - * that means SERVER_IS_RUNNING returns 0 - * Let's check only for SERVER_IS_DOWN: server is not running - */ - if (SERVER_IS_DOWN(ptr->server)) { - ptr = ptr->next; - continue; - } + while (ptr) + { + /* The server could be in SERVER_IN_MAINT + * that means SERVER_IS_RUNNING returns 0 + * Let's check only for SERVER_IS_DOWN: server is not running + */ + if (SERVER_IS_DOWN(ptr->server)) + { + ptr = ptr->next; + continue; + } - if (ptr->server->depth == 0) { - handle->master = ptr; - } + if (ptr->server->depth == 0) + { + handle->master = ptr; + } - ptr = ptr->next; - } + ptr = ptr->next; + } - /* - * Return the root master - */ + /* + * Return the root master + */ - if (handle->master != NULL) { - /* If the root master is in MAINT, return NULL */ - if (SERVER_IN_MAINT(handle->master->server)) { - return NULL; - } else { - return handle->master; - } - } else { - return NULL; - } + if (handle->master != NULL) + { + /* If the root master is in MAINT, return NULL */ + if (SERVER_IN_MAINT(handle->master->server)) + { + return NULL; + } + else + { + return handle->master; + } + } + else + { + return NULL; + } } static monitor_event_t mysql_events[] = { - MASTER_DOWN_EVENT, - MASTER_UP_EVENT, - SLAVE_DOWN_EVENT, - SLAVE_UP_EVENT, - SERVER_DOWN_EVENT, - SERVER_UP_EVENT, - LOST_MASTER_EVENT, - LOST_SLAVE_EVENT, - NEW_MASTER_EVENT, - NEW_SLAVE_EVENT, - MAX_MONITOR_EVENT + MASTER_DOWN_EVENT, + MASTER_UP_EVENT, + SLAVE_DOWN_EVENT, + SLAVE_UP_EVENT, + SERVER_DOWN_EVENT, + SERVER_UP_EVENT, + LOST_MASTER_EVENT, + LOST_SLAVE_EVENT, + NEW_MASTER_EVENT, + NEW_SLAVE_EVENT, + MAX_MONITOR_EVENT }; + /** * Check if the MM monitor is monitoring this event type. * @param event Event to check @@ -726,10 +771,12 @@ static monitor_event_t mysql_events[] = { bool isMySQLEvent(monitor_event_t event) { int i; - for(i = 0;mysql_events[i] != MAX_MONITOR_EVENT;i++) + for (i = 0; mysql_events[i] != MAX_MONITOR_EVENT; i++) { - if(event == mysql_events[i]) - return true; + if (event == mysql_events[i]) + { + return true; + } } return false; } From 5d4fe65b19532affb43749c5dc59fa2c60b6a37f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Nov 2015 21:00:22 +0200 Subject: [PATCH 174/179] Fixed some misaligned brackets. --- server/modules/monitor/galeramon.c | 9 ++++++--- server/modules/monitor/mmmon.c | 3 ++- server/modules/monitor/mysql_mon.c | 9 ++++++--- server/modules/monitor/ndbclustermon.c | 11 ++++++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/server/modules/monitor/galeramon.c b/server/modules/monitor/galeramon.c index 6755294e6..34840e9a2 100644 --- a/server/modules/monitor/galeramon.c +++ b/server/modules/monitor/galeramon.c @@ -48,7 +48,8 @@ static void monitorMain(void *); static char *version_str = "V2.0.0"; -MODULE_INFO info = { +MODULE_INFO info = +{ MODULE_API_MONITOR, MODULE_GA, MONITOR_VERSION, @@ -63,7 +64,8 @@ static MONITOR_SERVERS *set_cluster_master(MONITOR_SERVERS *, MONITOR_SERVERS *, static void disableMasterFailback(void *, int); bool isGaleraEvent(monitor_event_t event); -static MONITOR_OBJECT MyObject = { +static MONITOR_OBJECT MyObject = +{ startMonitor, stopMonitor, diagnostics @@ -758,7 +760,8 @@ availableWhenDonor(void *arg, int disable) memcpy(&handle->availableWhenDonor, &disable, sizeof(int)); } -static monitor_event_t galera_events[] = { +static monitor_event_t galera_events[] = +{ MASTER_DOWN_EVENT, MASTER_UP_EVENT, SLAVE_DOWN_EVENT, diff --git a/server/modules/monitor/mmmon.c b/server/modules/monitor/mmmon.c index 4d18fa5ce..dd60c4a64 100644 --- a/server/modules/monitor/mmmon.c +++ b/server/modules/monitor/mmmon.c @@ -749,7 +749,8 @@ static MONITOR_SERVERS *get_current_master(MONITOR *mon) } -static monitor_event_t mysql_events[] = { +static monitor_event_t mysql_events[] = +{ MASTER_DOWN_EVENT, MASTER_UP_EVENT, SLAVE_DOWN_EVENT, diff --git a/server/modules/monitor/mysql_mon.c b/server/modules/monitor/mysql_mon.c index f1c922581..a638b1c1f 100644 --- a/server/modules/monitor/mysql_mon.c +++ b/server/modules/monitor/mysql_mon.c @@ -60,7 +60,8 @@ static void monitorMain(void *); static char *version_str = "V1.4.0"; -MODULE_INFO info = { +MODULE_INFO info = +{ MODULE_API_MONITOR, MODULE_GA, MONITOR_VERSION, @@ -82,7 +83,8 @@ void check_maxscale_schema_replication(MONITOR *monitor); static bool report_version_err = true; static const char* hb_table_name = "maxscale_schema.replication_heartbeat"; -static MONITOR_OBJECT MyObject = { +static MONITOR_OBJECT MyObject = +{ startMonitor, stopMonitor, diagnostics @@ -1501,7 +1503,8 @@ static int add_slave_to_master(long *slaves_list, int list_size, long node_id) return 0; } -static monitor_event_t mysql_events[] = { +static monitor_event_t mysql_events[] = +{ MASTER_DOWN_EVENT, MASTER_UP_EVENT, SLAVE_DOWN_EVENT, diff --git a/server/modules/monitor/ndbclustermon.c b/server/modules/monitor/ndbclustermon.c index 71005b8ec..5dc810c0b 100644 --- a/server/modules/monitor/ndbclustermon.c +++ b/server/modules/monitor/ndbclustermon.c @@ -37,7 +37,8 @@ static void monitorMain(void *); static char *version_str = "V2.1.0"; -MODULE_INFO info = { +MODULE_INFO info = +{ MODULE_API_MONITOR, MODULE_BETA_RELEASE, MONITOR_VERSION, @@ -49,7 +50,8 @@ static void stopMonitor(void *); static void diagnostics(DCB *, void *); bool isNdbEvent(monitor_event_t event); -static MONITOR_OBJECT MyObject = { +static MONITOR_OBJECT MyObject = +{ startMonitor, stopMonitor, diagnostics @@ -436,7 +438,8 @@ monitorMain(void *arg) } -static monitor_event_t ndb_events[] = { +static monitor_event_t ndb_events[] = +{ MASTER_DOWN_EVENT, MASTER_UP_EVENT, SLAVE_DOWN_EVENT, @@ -465,7 +468,9 @@ bool isNdbEvent(monitor_event_t event) for (i = 0; ndb_events[i] != MAX_MONITOR_EVENT; i++) { if (event == ndb_events[i]) + { return true; + } } return false; } From 074f37e99775b1bbada400946b4afe21225649b6 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 17 Nov 2015 03:04:23 +0200 Subject: [PATCH 175/179] Fixed crash when filters fail to load The number of filters wasn't decreased if a filter failed to load resulting in a crash when the filters were applied. --- server/core/service.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/core/service.c b/server/core/service.c index 4f2453a90..f97393cd0 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -1103,6 +1103,7 @@ int n = 0; { MXS_ERROR("Failed to load filter '%s' for service '%s'.", filter_name, service->name); + n--; } flist[n] = NULL; From b828b04c059b1a3f826a1efa0c0e90e9fa2bd21c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 17 Nov 2015 09:17:29 +0200 Subject: [PATCH 176/179] Fixed debug assertion. --- server/modules/routing/schemarouter/schemarouter.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/modules/routing/schemarouter/schemarouter.c b/server/modules/routing/schemarouter/schemarouter.c index 6473f49c2..a13e7c554 100644 --- a/server/modules/routing/schemarouter/schemarouter.c +++ b/server/modules/routing/schemarouter/schemarouter.c @@ -1841,9 +1841,8 @@ RESULT_ROW *result_set_cb(struct resultset * rset, void *data) { RESULT_ROW *row = NULL; struct string_array *strarray = (struct string_array*) data; - ss_dassert(strarray->position < strarray->size); - if ((row = resultset_make_row(rset))) + if (strarray->position < strarray->size && (row = resultset_make_row(rset))) { if (resultset_row_set(row, 0, strarray->array[strarray->position++]) == 0) { From 6641c42ef949a6611788a050da93d95cbcacb54a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 17 Nov 2015 07:16:14 +0200 Subject: [PATCH 177/179] Added sync logs command to maxadmin Added maxadmin command to flush all logs to disk. This will allow tests to gather all logs without having to wait for the logs to be flushed by the log flusher thread. --- server/modules/routing/debugcmd.c | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index b21e31b47..45e275215 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -306,6 +306,38 @@ struct subcommand shutdownoptions[] = { } }; +static void sync_logs(DCB *dcb) +{ + if (mxs_log_flush_sync() == 0) + { + dcb_printf(dcb, "Logs flushed to disk\n"); + } + else + { + dcb_printf(dcb, "Failed to flush logs to disk. Read the error log for " + "more details.\n"); + } +} + +struct subcommand syncoptions[] = +{ + { + "logs", + 0, + sync_logs, + "Flush log files to disk", + "Flush log files to disk", + {0, 0, 0} + }, + { + NULL, + 0, + NULL, + NULL, + NULL, + {0, 0, 0} + } +}; static void restart_service(DCB *dcb, SERVICE *service); static void restart_monitor(DCB *dcb, MONITOR *monitor); @@ -722,6 +754,7 @@ static struct { { "set", setoptions }, { "show", showoptions }, { "shutdown", shutdownoptions }, + { "sync", syncoptions }, { NULL, NULL } }; From 453055a6c0dcb3e120a21a640bedab11c983eefd Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 16 Nov 2015 21:39:34 +0200 Subject: [PATCH 178/179] server/modules/protocol: All LOGIFs and skygw_log_writes replaced. LOGIFs and skygw_log_writes replaced with the equivalent MXS_[ERROR|WARNING|NOTICE|INFO|DEBUG] macros. --- server/modules/protocol/httpd.c | 7 +- server/modules/protocol/maxscaled.c | 23 +- server/modules/protocol/mysql_backend.c | 376 ++++++++++------------ server/modules/protocol/mysql_client.c | 319 ++++++++----------- server/modules/protocol/mysql_common.c | 398 ++++++++++-------------- server/modules/protocol/telnetd.c | 9 +- 6 files changed, 472 insertions(+), 660 deletions(-) diff --git a/server/modules/protocol/httpd.c b/server/modules/protocol/httpd.c index daa73d538..5d4aaeb7f 100644 --- a/server/modules/protocol/httpd.c +++ b/server/modules/protocol/httpd.c @@ -411,9 +411,8 @@ int syseno = 0; if(syseno != 0){ char errbuf[STRERROR_BUFLEN]; - skygw_log_write_flush(LOGFILE_ERROR, - "Error: Failed to set socket options. Error %d: %s", - errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, strerror_r(errno, errbuf, sizeof(errbuf))); return 0; } /* set NONBLOCKING mode */ @@ -428,7 +427,7 @@ int syseno = 0; rc = listen(listener->fd, SOMAXCONN); if (rc == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE,"Listening httpd connections at %s", config))); + MXS_NOTICE("Listening httpd connections at %s", config); } else { int eno = errno; errno = 0; diff --git a/server/modules/protocol/maxscaled.c b/server/modules/protocol/maxscaled.c index d18d99fb8..0c5fa6614 100644 --- a/server/modules/protocol/maxscaled.c +++ b/server/modules/protocol/maxscaled.c @@ -104,9 +104,7 @@ version() void ModuleInit() { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Initialise MaxScaled Protocol module.\n"))); + MXS_INFO("Initialise MaxScaled Protocol module.");; } /** @@ -352,10 +350,7 @@ int rc; // socket options if (setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one))) { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Unable to set SO_REUSEADDR on maxscale listener." - ))); + MXS_ERROR("Unable to set SO_REUSEADDR on maxscale listener."); } // set NONBLOCKING mode setnonblocking(listener->fd); @@ -368,20 +363,14 @@ int rc; rc = listen(listener->fd, SOMAXCONN); if (rc == 0) { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Listening maxscale connections at %s\n", - config))); + MXS_NOTICE("Listening maxscale connections at %s", config); } else { int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Failed to start listening for maxscale admin connections " - "due error %d, %s\n\n", - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to start listening for maxscale admin connections " + "due error %d, %s", + eno, strerror_r(eno, errbuf, sizeof(errbuf))); return 0; } diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index e48c00f98..279a87981 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -140,12 +140,10 @@ static MYSQL_session* gw_get_shared_session_auth_info( if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY) { auth_info = dcb->session->data; } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [gw_get_shared_session_auth_info] Couldn't get " - "session authentication info. Session in a wrong state %d.", - pthread_self(), - dcb->session->state))); + MXS_ERROR("%lu [gw_get_shared_session_auth_info] Couldn't get " + "session authentication info. Session in a wrong state %d.", + pthread_self(), + dcb->session->state); } spinlock_release(&dcb->session->ses_lock); @@ -184,15 +182,13 @@ static int gw_read_backend_event(DCB *dcb) { backend_protocol = (MySQLProtocol *) dcb->protocol; CHK_PROTOCOL(backend_protocol); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] Read dcb %p fd %d protocol " - "state %d, %s.", - pthread_self(), - dcb, - dcb->fd, - backend_protocol->protocol_auth_state, - STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)))); + MXS_DEBUG("%lu [gw_read_backend_event] Read dcb %p fd %d protocol " + "state %d, %s.", + pthread_self(), + dcb, + dcb->fd, + backend_protocol->protocol_auth_state, + STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)); /* backend is connected: @@ -220,13 +216,11 @@ static int gw_read_backend_event(DCB *dcb) { { backend_protocol->protocol_auth_state = MYSQL_HANDSHAKE_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] after " - "gw_read_backend_handshake, fd %d, " - "state = MYSQL_HANDSHAKE_FAILED.", - pthread_self(), - backend_protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_event] after " + "gw_read_backend_handshake, fd %d, " + "state = MYSQL_HANDSHAKE_FAILED.", + pthread_self(), + backend_protocol->owner_dcb->fd); } else { @@ -241,13 +235,11 @@ static int gw_read_backend_event(DCB *dcb) { backend_protocol) != 0) { backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] after " - "gw_send_authentication_to_backend " - "fd %d, state = MYSQL_AUTH_FAILED.", - pthread_self(), - backend_protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_event] after " + "gw_send_authentication_to_backend " + "fd %d, state = MYSQL_AUTH_FAILED.", + pthread_self(), + backend_protocol->owner_dcb->fd); } else { @@ -303,46 +295,38 @@ static int gw_read_backend_event(DCB *dcb) { switch (receive_rc) { case -1: backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] after " - "gw_receive_backend_authentication " - "fd %d, state = MYSQL_AUTH_FAILED.", - pthread_self(), - backend_protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_event] after " + "gw_receive_backend_authentication " + "fd %d, state = MYSQL_AUTH_FAILED.", + pthread_self(), + backend_protocol->owner_dcb->fd); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Backend server didn't " - "accept authentication for user " - "%s.", - current_session->user))); + MXS_ERROR("Backend server didn't " + "accept authentication for user " + "%s.", + current_session->user); break; case 1: backend_protocol->protocol_auth_state = MYSQL_IDLE; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] " - "gw_receive_backend_auth succeed. " - "dcb %p fd %d, user %s.", - pthread_self(), - dcb, - dcb->fd, - current_session->user))); + MXS_DEBUG("%lu [gw_read_backend_event] " + "gw_receive_backend_auth succeed. " + "dcb %p fd %d, user %s.", + pthread_self(), + dcb, + dcb->fd, + current_session->user); break; default: ss_dassert(receive_rc == 0); - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] " - "gw_receive_backend_auth read " - "successfully " - "nothing. dcb %p fd %d, user %s.", - pthread_self(), - dcb, - dcb->fd, - current_session->user))); + MXS_DEBUG("%lu [gw_read_backend_event] " + "gw_receive_backend_auth read " + "successfully " + "nothing. dcb %p fd %d, user %s.", + pthread_self(), + dcb, + dcb->fd, + current_session->user); rc = 0; goto return_with_lock; break; @@ -376,14 +360,12 @@ static int gw_read_backend_event(DCB *dcb) { service_refresh_users(dcb->session->service); } #if defined(SS_DEBUG) - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] " - "calling handleError. Backend " - "DCB %p, session %p", - pthread_self(), - dcb, - dcb->session))); + MXS_DEBUG("%lu [gw_read_backend_event] " + "calling handleError. Backend " + "DCB %p, session %p", + pthread_self(), + dcb, + dcb->session); #endif errbuf = mysql_create_custom_error( @@ -426,14 +408,12 @@ static int gw_read_backend_event(DCB *dcb) { else { ss_dassert(backend_protocol->protocol_auth_state == MYSQL_IDLE); - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_read_backend_event] " - "gw_receive_backend_auth succeed. Fd %d, " - "user %s.", - pthread_self(), - dcb->fd, - current_session->user))); + MXS_DEBUG("%lu [gw_read_backend_event] " + "gw_receive_backend_auth succeed. Fd %d, " + "user %s.", + pthread_self(), + dcb->fd, + current_session->user); /* check the delay queue and flush the data */ if (dcb->delayq) @@ -468,9 +448,7 @@ static int gw_read_backend_event(DCB *dcb) { GWBUF* errbuf; bool succp; #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend read error handling #2."))); + MXS_ERROR("Backend read error handling #2."); #endif errbuf = mysql_create_custom_error( 1, @@ -555,13 +533,11 @@ static int gw_read_backend_event(DCB *dcb) { } if (!read_buffer) { - LOGIF(LM, (skygw_log_write_flush( - LOGFILE_MESSAGE, - "%lu [gw_read_backend_event] " - "Read buffer unexpectedly null, even though response " - "not marked as complete. User: %s", - pthread_self(), - current_session->user))); + MXS_NOTICE("%lu [gw_read_backend_event] " + "Read buffer unexpectedly null, even though response " + "not marked as complete. User: %s", + pthread_self(), + current_session->user); rc = 0; goto return_rc; } @@ -650,34 +626,28 @@ static int gw_write_backend_event(DCB *dcb) { 0, "Writing to backend failed due invalid Maxscale " "state."); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_write_backend_event] Write to backend " - "dcb %p fd %d " - "failed due invalid state %s.", - pthread_self(), - dcb, - dcb->fd, - STRDCBSTATE(dcb->state)))); + MXS_DEBUG("%lu [gw_write_backend_event] Write to backend " + "dcb %p fd %d " + "failed due invalid state %s.", + pthread_self(), + dcb, + dcb->fd, + STRDCBSTATE(dcb->state)); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Attempt to write buffered data to backend " - "failed " - "due internal inconsistent state."))); + MXS_ERROR("Attempt to write buffered data to backend " + "failed " + "due internal inconsistent state."); rc = 0; } } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_write_backend_event] Dcb %p in state %s " - "but there's nothing to write either.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); + MXS_DEBUG("%lu [gw_write_backend_event] Dcb %p in state %s " + "but there's nothing to write either.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); rc = 1; } goto return_rc; @@ -691,14 +661,12 @@ static int gw_write_backend_event(DCB *dcb) { dcb_drain_writeq(dcb); rc = 1; return_rc: - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_write_backend_event] " - "wrote to dcb %p fd %d, return %d", - pthread_self(), - dcb, - dcb->fd, - rc))); + MXS_DEBUG("%lu [gw_write_backend_event] " + "wrote to dcb %p fd %d, return %d", + pthread_self(), + dcb, + dcb->fd, + rc); return rc; } @@ -726,12 +694,12 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue) switch (backend_protocol->protocol_auth_state) { case MYSQL_HANDSHAKE_FAILED: case MYSQL_AUTH_FAILED: - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error : Unable to write to backend '%s' due to " - "%s failure. Server in state %s.", - dcb->server->unique_name, - backend_protocol->protocol_auth_state == MYSQL_HANDSHAKE_FAILED ? "handshake" : "authentication", - STRSRVSTATUS(dcb->server)))); + MXS_ERROR("Unable to write to backend '%s' due to " + "%s failure. Server in state %s.", + dcb->server->unique_name, + backend_protocol->protocol_auth_state == MYSQL_HANDSHAKE_FAILED ? + "handshake" : "authentication", + STRSRVSTATUS(dcb->server)); /** Consume query buffer */ while ((queue = gwbuf_consume( queue, @@ -746,14 +714,12 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue) uint8_t* ptr = GWBUF_DATA(queue); int cmd = MYSQL_GET_COMMAND(ptr); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_MySQLWrite_backend] write to dcb %p " - "fd %d protocol state %s.", - pthread_self(), - dcb, - dcb->fd, - STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)))); + MXS_DEBUG("%lu [gw_MySQLWrite_backend] write to dcb %p " + "fd %d protocol state %s.", + pthread_self(), + dcb, + dcb->fd, + STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)); spinlock_release(&dcb->authlock); /** @@ -777,14 +743,12 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue) default: { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_MySQLWrite_backend] delayed write to " - "dcb %p fd %d protocol state %s.", - pthread_self(), - dcb, - dcb->fd, - STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)))); + MXS_DEBUG("%lu [gw_MySQLWrite_backend] delayed write to " + "dcb %p fd %d protocol state %s.", + pthread_self(), + dcb, + dcb->fd, + STRPROTOCOLSTATE(backend_protocol->protocol_auth_state)); /** * In case of session commands, store command to DCB's * protocol struct. @@ -859,11 +823,9 @@ static int gw_error_backend_event(DCB *dcb) if (error != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "DCB in state %s got error '%s'.", - STRDCBSTATE(dcb->state), - strerror_r(error, errbuf, sizeof(errbuf))))); + MXS_ERROR("DCB in state %s got error '%s'.", + STRDCBSTATE(dcb->state), + strerror_r(error, errbuf, sizeof(errbuf))); } } return 1; @@ -900,10 +862,8 @@ static int gw_error_backend_event(DCB *dcb) if (error != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error '%s' in session that is not ready for routing.", - strerror_r(error, errbuf, sizeof(errbuf))))); + MXS_ERROR("Error '%s' in session that is not ready for routing.", + strerror_r(error, errbuf, sizeof(errbuf))); } } gwbuf_free(errbuf); @@ -911,9 +871,7 @@ static int gw_error_backend_event(DCB *dcb) } #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend error event handling."))); + MXS_INFO("Backend error event handling."); #endif router->handleError(router_instance, rsession, @@ -965,16 +923,11 @@ static int gw_create_backend_connection( ss_dassert(protocol != NULL); if (protocol == NULL) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_create_backend_connection] Failed to create " - "protocol object for backend connection.", - pthread_self()))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to create " - "protocol object for backend connection."))); - goto return_fd; + MXS_DEBUG("%lu [gw_create_backend_connection] Failed to create " + "protocol object for backend connection.", + pthread_self()); + MXS_ERROR("Failed to create protocol object for backend connection."); + goto return_fd; } /** Copy client flags to backend protocol */ @@ -1004,45 +957,39 @@ static int gw_create_backend_connection( ss_dassert(fd > 0); protocol->fd = fd; protocol->protocol_auth_state = MYSQL_CONNECTED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_create_backend_connection] Established " - "connection to %s:%i, protocol fd %d client " - "fd %d.", - pthread_self(), - server->name, - server->port, - protocol->fd, - session->client->fd))); + MXS_DEBUG("%lu [gw_create_backend_connection] Established " + "connection to %s:%i, protocol fd %d client " + "fd %d.", + pthread_self(), + server->name, + server->port, + protocol->fd, + session->client->fd); break; case 1: ss_dassert(fd > 0); protocol->protocol_auth_state = MYSQL_PENDING_CONNECT; protocol->fd = fd; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_create_backend_connection] Connection " - "pending to %s:%i, protocol fd %d client fd %d.", - pthread_self(), - server->name, - server->port, - protocol->fd, - session->client->fd))); + MXS_DEBUG("%lu [gw_create_backend_connection] Connection " + "pending to %s:%i, protocol fd %d client fd %d.", + pthread_self(), + server->name, + server->port, + protocol->fd, + session->client->fd); break; default: ss_dassert(fd == -1); ss_dassert(protocol->protocol_auth_state == MYSQL_ALLOC); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_create_backend_connection] Connection " - "failed to %s:%i, protocol fd %d client fd %d.", - pthread_self(), - server->name, - server->port, - protocol->fd, - session->client->fd))); + MXS_DEBUG("%lu [gw_create_backend_connection] Connection " + "failed to %s:%i, protocol fd %d client fd %d.", + pthread_self(), + server->name, + server->port, + protocol->fd, + session->client->fd); break; } /*< switch */ @@ -1123,11 +1070,9 @@ gw_backend_hangup(DCB *dcb) if (error != 0 && ses_state != SESSION_STATE_STOPPING) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Hangup in session that is not ready for routing, " - "Error reported is '%s'.", - strerror_r(error, errbuf, sizeof(errbuf))))); + MXS_ERROR("Hangup in session that is not ready for routing, " + "Error reported is '%s'.", + strerror_r(error, errbuf, sizeof(errbuf))); } } gwbuf_free(errbuf); @@ -1142,9 +1087,7 @@ gw_backend_hangup(DCB *dcb) #if defined(SS_DEBUG) if(ses_state != SESSION_STATE_STOPPING) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend hangup error handling."))); + MXS_ERROR("Backend hangup error handling."); } #endif @@ -1160,9 +1103,7 @@ gw_backend_hangup(DCB *dcb) if (!succp) { #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend hangup -> closing session."))); + MXS_ERROR("Backend hangup -> closing session."); #endif spinlock_acquire(&session->ses_lock); session->state = SESSION_STATE_STOPPING; @@ -1188,9 +1129,8 @@ gw_backend_close(DCB *dcb) CHK_DCB(dcb); session = dcb->session; - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [gw_backend_close]", - pthread_self()))); + MXS_DEBUG("%lu [gw_backend_close]", + pthread_self()); quitbuf = mysql_create_com_quit(NULL, 0); gwbuf_set_type(quitbuf, GWBUF_TYPE_MYSQL); @@ -1326,9 +1266,7 @@ static int backend_write_delayqueue(DCB *dcb) router_instance = session->service->router_instance; rsession = session->router_session; #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend write delayqueue error handling."))); + MXS_INFO("Backend write delayqueue error handling."); #endif errbuf = mysql_create_custom_error( 1, @@ -1488,11 +1426,9 @@ static int gw_change_user( auth_ret); if (message == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Creating error message failed."))); - rv = 0; - goto retblock; + MXS_ERROR("Creating error message failed."); + rv = 0; + goto retblock; } /** * Add command to backend's protocol, create artificial reply @@ -1561,13 +1497,11 @@ static GWBUF* process_response_data ( srvcmd = protocol_get_srv_command(p, false); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [process_response_data] Read command %s for DCB %p fd %d.", - pthread_self(), - STRPACKETTYPE(srvcmd), - dcb, - dcb->fd))); + MXS_DEBUG("%lu [process_response_data] Read command %s for DCB %p fd %d.", + pthread_self(), + STRPACKETTYPE(srvcmd), + dcb, + dcb->fd); /** * Read values from protocol structure, fails if values are * uninitialized. @@ -1667,9 +1601,11 @@ static GWBUF* process_response_data ( wait for more data from the backend server.*/ if(readbuf == NULL || GWBUF_LENGTH(readbuf) < 3) { - skygw_log_write(LD," %lu [%s] Read %d packets. Waiting for %d more packets for a total of %d packets.", - pthread_self(),__FUNCTION__,initial_packets - npackets_left, - npackets_left,initial_packets); + MXS_DEBUG("%lu [%s] Read %d packets. Waiting for %d more " + "packets for a total of %d packets.", + pthread_self(),__FUNCTION__, + initial_packets - npackets_left, + npackets_left,initial_packets); /** Store the already read data into the readqueue of the DCB * and restore the response status to the initial number of packets */ diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index d92b4fc91..8993fc802 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -480,16 +480,16 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { /** Client didn't requested SSL when SSL mode was required*/ if(!ssl && protocol->owner_dcb->service->ssl_mode == SSL_REQUIRED) { - LOGIF(LT,(skygw_log_write(LT,"User %s@%s connected to service '%s' without SSL when SSL was required.", - protocol->owner_dcb->user, - protocol->owner_dcb->remote, - protocol->owner_dcb->service->name))); + MXS_INFO("User %s@%s connected to service '%s' without SSL when SSL was required.", + protocol->owner_dcb->user, + protocol->owner_dcb->remote, + protocol->owner_dcb->service->name); return MYSQL_FAILED_AUTH_SSL; } if(LOG_IS_ENABLED(LT) && ssl) { - skygw_log_write(LT,"User %s@%s connected to service '%s' with SSL.", + MXS_INFO("User %s@%s connected to service '%s' with SSL.", protocol->owner_dcb->user, protocol->owner_dcb->remote, protocol->owner_dcb->service->name); @@ -521,7 +521,7 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { client_auth_packet = GWBUF_DATA(queue); client_auth_packet_size = gwbuf_length(queue); *buf = queue; - LOGIF(LD,(skygw_log_write(LD,"%lu Read %d bytes from fd %d",pthread_self(),bytes,dcb->fd))); + MXS_DEBUG("%lu Read %d bytes from fd %d",pthread_self(),bytes,dcb->fd); } } @@ -562,7 +562,7 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { * Decode the token and check the password * Note: if auth_token_len == 0 && auth_token == NULL, user is without password */ - skygw_log_write(LOGFILE_DEBUG,"Receiving connection from '%s' to database '%s'.",username,database); + MXS_DEBUG("Receiving connection from '%s' to database '%s'.",username,database); auth_ret = gw_check_mysql_scramble_data(dcb, auth_token, auth_token_len, @@ -599,15 +599,15 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { } else if (dcb->service->log_auth_warnings) { - skygw_log_write(LM, "%s: login attempt for user '%s', authentication failed.", - dcb->service->name, username); + MXS_NOTICE("%s: login attempt for user '%s', authentication failed.", + dcb->service->name, username); if (dcb->ipv4.sin_addr.s_addr == 0x0100007F && !dcb->service->localhost_match_wildcard_host) { - skygw_log_write_flush(LM, "If you have a wildcard grant that covers" - " this address, try adding " - "'localhost_match_wildcard_host=true' for " - "service '%s'. ", dcb->service->name); + MXS_NOTICE("If you have a wildcard grant that covers" + " this address, try adding " + "'localhost_match_wildcard_host=true' for " + "service '%s'. ", dcb->service->name); } } @@ -676,8 +676,8 @@ int gw_read_client_event( CHK_PROTOCOL(protocol); #ifdef SS_DEBUG - skygw_log_write(LD,"[gw_read_client_event] Protocol state: %s", - gw_mysql_protocol_state2string(protocol->protocol_auth_state)); + MXS_DEBUG("[gw_read_client_event] Protocol state: %s", + gw_mysql_protocol_state2string(protocol->protocol_auth_state)); #endif @@ -698,8 +698,7 @@ int gw_read_client_event( ioctl(dcb->fd,FIONREAD,&b); if(b == 0) { - skygw_log_write(LD, - "[gw_read_client_event] No data in socket after SSL auth"); + MXS_DEBUG("[gw_read_client_event] No data in socket after SSL auth"); return 0; } break; @@ -883,13 +882,11 @@ int gw_read_client_event( else { protocol->protocol_auth_state = MYSQL_AUTH_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_client_event] session " - "creation failed. fd %d, " - "state = MYSQL_AUTH_FAILED.", - pthread_self(), - protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_client_event] session " + "creation failed. fd %d, " + "state = MYSQL_AUTH_FAILED.", + pthread_self(), + protocol->owner_dcb->fd); /** Send ERR 1045 to client */ mysql_send_auth_error( @@ -927,13 +924,11 @@ int gw_read_client_event( if (fail_str) free(fail_str); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_client_event] after " - "gw_mysql_do_authentication, fd %d, " - "state = MYSQL_AUTH_FAILED.", - pthread_self(), - protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_client_event] after " + "gw_mysql_do_authentication, fd %d, " + "state = MYSQL_AUTH_FAILED.", + pthread_self(), + protocol->owner_dcb->fd); /** * Release MYSQL_session since it is not used anymore. */ @@ -983,13 +978,11 @@ int gw_read_client_event( else { protocol->protocol_auth_state = MYSQL_AUTH_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_client_event] session " - "creation failed. fd %d, " - "state = MYSQL_AUTH_FAILED.", - pthread_self(), - protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_client_event] session " + "creation failed. fd %d, " + "state = MYSQL_AUTH_FAILED.", + pthread_self(), + protocol->owner_dcb->fd); /** Send ERR 1045 to client */ mysql_send_auth_error( @@ -1027,13 +1020,11 @@ int gw_read_client_event( if (fail_str) free(fail_str); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_client_event] after " - "gw_mysql_do_authentication, fd %d, " - "state = MYSQL_AUTH_FAILED.", - pthread_self(), - protocol->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_client_event] after " + "gw_mysql_do_authentication, fd %d, " + "state = MYSQL_AUTH_FAILED.", + pthread_self(), + protocol->owner_dcb->fd); /** * Release MYSQL_session since it is not used anymore. */ @@ -1153,10 +1144,8 @@ int gw_read_client_event( */ if (!succp) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing the query failed. " - "Session will be closed."))); + MXS_ERROR("Routing the query failed. " + "Session will be closed."); } while (read_buffer) @@ -1168,8 +1157,8 @@ int gw_read_client_event( } else { - skygw_log_write_flush(LT,"Session received a query in state %s", - STRSESSIONSTATE(ses_state)); + MXS_INFO("Session received a query in state %s", + STRSESSIONSTATE(ses_state)); while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL); goto return_rc; } @@ -1328,10 +1317,9 @@ int gw_MySQLListener(DCB *listen_dcb, if ((l_so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Error: Can't create UNIX socket: %i, %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Can't create UNIX socket: %i, %s", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return 0; } memset(&local_addr, 0, sizeof(local_addr)); @@ -1348,7 +1336,7 @@ int gw_MySQLListener(DCB *listen_dcb, */ if (!parse_bindconfig(config_bind, 4406, &serv_addr)) { - skygw_log_write(LE, "Error in parse_bindconfig for [%s]", config_bind); + MXS_ERROR("Error in parse_bindconfig for [%s]", config_bind); return 0; } @@ -1356,10 +1344,9 @@ int gw_MySQLListener(DCB *listen_dcb, if ((l_so = socket(AF_INET, SOCK_STREAM, 0)) < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Error: Can't create socket: %i, %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Can't create socket: %i, %s", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); return 0; } @@ -1373,10 +1360,9 @@ int gw_MySQLListener(DCB *listen_dcb, if (setsockopt(l_so, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Failed to set socket options. Error %d: %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } if (is_tcp) @@ -1384,16 +1370,15 @@ int gw_MySQLListener(DCB *listen_dcb, char errbuf[STRERROR_BUFLEN]; if (setsockopt(l_so, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) != 0) { - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR, - "Error: Failed to set socket options. Error %d: %s", - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } } // set NONBLOCKING mode if (setnonblocking(l_so) != 0) { - skygw_log_write(LE, "Error: Failed to set socket to non-blocking mode."); + MXS_ERROR("Failed to set socket to non-blocking mode."); close(l_so); return 0; } @@ -1406,18 +1391,17 @@ int gw_MySQLListener(DCB *listen_dcb, if ((rc == -1) && (errno != ENOENT)) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, "Error: Failed to unlink Unix Socket %s: %d %s", - config_bind, errno, strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to unlink Unix Socket %s: %d %s", + config_bind, errno, strerror_r(errno, errbuf, sizeof(errbuf))); } if (bind(l_so, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Error: Failed to bind to UNIX Domain socket '%s': %i, %s", - config_bind, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to bind to UNIX Domain socket '%s': %i, %s", + config_bind, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); close(l_so); return 0; } @@ -1426,31 +1410,28 @@ int gw_MySQLListener(DCB *listen_dcb, if (chmod(config_bind, 0777) < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Error: Failed to change permissions on UNIX Domain socket '%s': %i, %s", - config_bind, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to change permissions on UNIX Domain socket '%s': %i, %s", + config_bind, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } - break; case AF_INET: if (bind(l_so, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Error: Failed to bind on '%s': %i, %s", - config_bind, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to bind on '%s': %i, %s", + config_bind, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); close(l_so); return 0; } break; default: - skygw_log_write(LE, "Error: Socket Family %i not supported\n", current_addr->sa_family); + MXS_ERROR("Socket Family %i not supported\n", current_addr->sa_family); close(l_so); return 0; } @@ -1458,16 +1439,15 @@ int gw_MySQLListener(DCB *listen_dcb, if (listen(l_so, 10 * SOMAXCONN) != 0) { char errbuf[STRERROR_BUFLEN]; - skygw_log_write(LE, - "Failed to start listening on '%s': %d, %s", - config_bind, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to start listening on '%s': %d, %s", + config_bind, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); close(l_so); return 0; } - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE, "Listening MySQL connections at %s", config_bind))); + MXS_NOTICE("Listening MySQL connections at %s", config_bind); // assign l_so to dcb listen_dcb->fd = l_so; @@ -1475,9 +1455,8 @@ int gw_MySQLListener(DCB *listen_dcb, // add listening socket to poll structure if (poll_add_dcb(listen_dcb) != 0) { - skygw_log_write(LE, - "MaxScale encountered system limit while " - "attempting to register on an epoll instance."); + MXS_ERROR("MaxScale encountered system limit while " + "attempting to register on an epoll instance."); return 0; } #if defined(FAKE_CODE) @@ -1560,23 +1539,19 @@ int gw_MySQLAccept(DCB *listener) * (EMFILE) max. number of files limit. */ char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_MySQLAccept] Error %d, %s. ", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [gw_MySQLAccept] Error %d, %s. ", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); if (i == 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error %d, %s. " - "Failed to accept new client " - "connection.", - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Error %d, %s. " + "Failed to accept new client " + "connection.", + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); } i++; ts1.tv_nsec = 100*i*i*1000000; @@ -1594,18 +1569,14 @@ int gw_MySQLAccept(DCB *listener) * Other error. */ char errbuf[STRERROR_BUFLEN]; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_MySQLAccept] Error %d, %s.", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to accept new client " - "connection due to %d, %s.", - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_DEBUG("%lu [gw_MySQLAccept] Error %d, %s.", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); + MXS_ERROR("Failed to accept new client " + "connection due to %d, %s.", + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); rc = 1; goto return_rc; } /* if (eno == ..) */ @@ -1615,11 +1586,9 @@ int gw_MySQLAccept(DCB *listener) listener->stats.n_accepts++; #if defined(SS_DEBUG) - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_MySQLAccept] Accepted fd %d.", - pthread_self(), - c_sock))); + MXS_DEBUG("%lu [gw_MySQLAccept] Accepted fd %d.", + pthread_self(), + c_sock); #endif /* SS_DEBUG */ #if defined(FAKE_CODE) conn_open[c_sock] = true; @@ -1629,26 +1598,25 @@ int gw_MySQLAccept(DCB *listener) char errbuf[STRERROR_BUFLEN]; if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen)) != 0){ - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, strerror_r(errno, errbuf, sizeof(errbuf))); } sendbuf = GW_CLIENT_SO_RCVBUF; if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen)) != 0){ - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, strerror_r(errno, errbuf, sizeof(errbuf))); } setnonblocking(c_sock); client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); if (client_dcb == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Failed to create " - "DCB object for client connection."))); - close(c_sock); - rc = 1; - goto return_rc; + MXS_ERROR("Failed to create DCB object for client connection."); + close(c_sock); + rc = 1; + goto return_rc; } client_dcb->service = listener->session->service; @@ -1686,11 +1654,9 @@ int gw_MySQLAccept(DCB *listener) if (protocol == NULL) { /** delete client_dcb */ dcb_close(client_dcb); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [gw_MySQLAccept] Failed to create " - "protocol object for client connection.", - pthread_self()))); + MXS_ERROR("%lu [gw_MySQLAccept] Failed to create " + "protocol object for client connection.", + pthread_self()); rc = 1; goto return_rc; } @@ -1722,25 +1688,21 @@ int gw_MySQLAccept(DCB *listener) dcb_close(client_dcb); /** Previous state is recovered in poll_add_dcb. */ - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [gw_MySQLAccept] Failed to add dcb %p for " - "fd %d to epoll set.", - pthread_self(), - client_dcb, - client_dcb->fd))); + MXS_ERROR("%lu [gw_MySQLAccept] Failed to add dcb %p for " + "fd %d to epoll set.", + pthread_self(), + client_dcb, + client_dcb->fd); rc = 1; goto return_rc; } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_MySQLAccept] Added dcb %p for fd " - "%d to epoll set.", - pthread_self(), - client_dcb, - client_dcb->fd))); + MXS_DEBUG("%lu [gw_MySQLAccept] Added dcb %p for fd " + "%d to epoll set.", + pthread_self(), + client_dcb, + client_dcb->fd); } } /**< while 1 */ #if defined(SS_DEBUG) @@ -1763,14 +1725,12 @@ static int gw_error_client_event( session = dcb->session; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_error_client_event] Error event handling for DCB %p " - "in state %s, session %p.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state), - (session != NULL ? session : NULL)))); + MXS_DEBUG("%lu [gw_error_client_event] Error event handling for DCB %p " + "in state %s, session %p.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state), + (session != NULL ? session : NULL)); if (session != NULL && session->state == SESSION_STATE_STOPPING) { @@ -1778,9 +1738,7 @@ static int gw_error_client_event( } #if defined(SS_DEBUG) - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "Client error event handling."))); + MXS_DEBUG("Client error event handling."); #endif dcb_close(dcb); @@ -1803,9 +1761,7 @@ gw_client_close(DCB *dcb) if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(protocol); } #endif - LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, - "%lu [gw_client_close]", - pthread_self()))); + MXS_DEBUG("%lu [gw_client_close]", pthread_self()); mysql_protocol_done(dcb); session = dcb->session; /** @@ -1975,9 +1931,9 @@ int do_ssl_accept(MySQLProtocol* protocol) queue and wait for more.*/ rval = 0; - skygw_log_write_flush(LT,"SSL_accept ongoing for %s@%s", - protocol->owner_dcb->user, - protocol->owner_dcb->remote); + MXS_INFO("SSL_accept ongoing for %s@%s", + protocol->owner_dcb->user, + protocol->owner_dcb->remote); return 0; break; case 1: @@ -1993,9 +1949,9 @@ int do_ssl_accept(MySQLProtocol* protocol) rval = 1; - skygw_log_write_flush(LT,"SSL_accept done for %s@%s", - protocol->owner_dcb->user, - protocol->owner_dcb->remote); + MXS_INFO("SSL_accept done for %s@%s", + protocol->owner_dcb->user, + protocol->owner_dcb->remote); break; case -1: @@ -2004,20 +1960,17 @@ int do_ssl_accept(MySQLProtocol* protocol) protocol->protocol_auth_state = MYSQL_AUTH_SSL_HANDSHAKE_FAILED; spinlock_release(&protocol->protocol_lock); rval = -1; - skygw_log_write_flush(LE, - "Error: Fatal error in SSL_accept for %s", - protocol->owner_dcb->remote); + MXS_ERROR("Fatal error in SSL_accept for %s", + protocol->owner_dcb->remote); break; default: - skygw_log_write_flush(LE, - "Error: Fatal error in SSL_accept, returned value was %d.", - rval); + MXS_ERROR("Fatal error in SSL_accept, returned value was %d.", rval); break; } #ifdef SS_DEBUG - skygw_log_write(LD,"[do_ssl_accept] Protocol state: %s", - gw_mysql_protocol_state2string(protocol->protocol_auth_state)); + MXS_DEBUG("[do_ssl_accept] Protocol state: %s", + gw_mysql_protocol_state2string(protocol->protocol_auth_state)); #endif return rval; diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 519191a4b..5ed0d5b24 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -86,13 +86,11 @@ MySQLProtocol* mysql_protocol_init( int eno = errno; errno = 0; char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [mysql_init_protocol] MySQL protocol init failed : " - "memory allocation due error %d, %s.", - pthread_self(), - eno, - strerror_r(eno, errbuf, sizeof(errbuf))))); + MXS_ERROR("%lu [mysql_init_protocol] MySQL protocol init failed : " + "memory allocation due error %d, %s.", + pthread_self(), + eno, + strerror_r(eno, errbuf, sizeof(errbuf))); goto return_p; } p->protocol_state = MYSQL_PROTOCOL_ALLOC; @@ -187,13 +185,11 @@ int gw_read_backend_handshake( if (h_len <= 4) { /* log error this exit point */ conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_handshake] after " - "dcb_read, fd %d, " - "state = MYSQL_HANDSHAKE_FAILED.", - pthread_self(), - dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_handshake] after " + "dcb_read, fd %d, " + "state = MYSQL_HANDSHAKE_FAILED.", + pthread_self(), + dcb->fd); return 1; } @@ -206,24 +202,20 @@ int gw_read_backend_handshake( conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_receive_backend_auth] Invalid " - "authentication message from backend dcb %p " - "fd %d, ptr[4] = %d, error code %d, msg %s.", - pthread_self(), - dcb, - dcb->fd, - payload[4], - errcode, - bufstr))); + MXS_DEBUG("%lu [gw_receive_backend_auth] Invalid " + "authentication message from backend dcb %p " + "fd %d, ptr[4] = %d, error code %d, msg %s.", + pthread_self(), + dcb, + dcb->fd, + payload[4], + errcode, + bufstr); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Invalid authentication message " - "from backend. Error code: %d, Msg : %s", - errcode, - bufstr))); + MXS_ERROR("Invalid authentication message " + "from backend. Error code: %d, Msg : %s", + errcode, + bufstr); /** * If ER_HOST_IS_BLOCKED is found @@ -232,12 +224,14 @@ int gw_read_backend_handshake( */ if (errcode == 1129) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Server %s has been put into maintenance mode due to the server blocking connections from MaxScale. Run 'mysqladmin -h %s -P %d flush-hosts' on this server before taking this server out of maintenance mode.", - dcb->server->unique_name, - dcb->server->name, - dcb->server->port))); + MXS_ERROR("Server %s has been put into maintenance mode due " + "to the server blocking connections from MaxScale. " + "Run 'mysqladmin -h %s -P %d flush-hosts' on this " + "server before taking this server out of maintenance " + "mode.", + dcb->server->unique_name, + dcb->server->name, + dcb->server->port); server_set_status(dcb->server, SERVER_MAINT); } @@ -255,13 +249,11 @@ int gw_read_backend_handshake( conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_handshake] after " - "gw_mysql_get_byte3, fd %d, " - "state = MYSQL_HANDSHAKE_FAILED.", - pthread_self(), - dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_handshake] after " + "gw_mysql_get_byte3, fd %d, " + "state = MYSQL_HANDSHAKE_FAILED.", + pthread_self(), + dcb->fd); return 1; } @@ -279,13 +271,11 @@ int gw_read_backend_handshake( */ conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_read_backend_handshake] after " - "gw_decode_mysql_server_handshake, fd %d, " - "state = MYSQL_HANDSHAKE_FAILED.", - pthread_self(), - conn->owner_dcb->fd))); + MXS_DEBUG("%lu [gw_read_backend_handshake] after " + "gw_decode_mysql_server_handshake, fd %d, " + "state = MYSQL_HANDSHAKE_FAILED.", + pthread_self(), + conn->owner_dcb->fd); while((head = gwbuf_consume(head, GWBUF_LENGTH(head)))); return 1; } @@ -445,24 +435,20 @@ int gw_receive_backend_auth( char* err = strndup(&((char *)ptr)[8], 5); char* bufstr = strndup(&((char *)ptr)[13], len-4-5); - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_receive_backend_auth] Invalid " - "authentication message from backend dcb %p " - "fd %d, ptr[4] = %d, error %s, msg %s.", - pthread_self(), - dcb, - dcb->fd, - ptr[4], - err, - bufstr))); + MXS_DEBUG("%lu [gw_receive_backend_auth] Invalid " + "authentication message from backend dcb %p " + "fd %d, ptr[4] = %d, error %s, msg %s.", + pthread_self(), + dcb, + dcb->fd, + ptr[4], + err, + bufstr); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Invalid authentication message " - "from backend. Error : %s, Msg : %s", - err, - bufstr))); + MXS_ERROR("Invalid authentication message " + "from backend. Error : %s, Msg : %s", + err, + bufstr); free(bufstr); free(err); @@ -470,21 +456,17 @@ int gw_receive_backend_auth( } else { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_receive_backend_auth] Invalid " - "authentication message from backend dcb %p " - "fd %d, ptr[4] = %d", - pthread_self(), - dcb, - dcb->fd, - ptr[4]))); + MXS_DEBUG("%lu [gw_receive_backend_auth] Invalid " + "authentication message from backend dcb %p " + "fd %d, ptr[4] = %d", + pthread_self(), + dcb, + dcb->fd, + ptr[4]); - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Invalid authentication message " - "from backend. Packet type : %d", - ptr[4]))); + MXS_ERROR("Invalid authentication message " + "from backend. Packet type : %d", + ptr[4]); } /*< * Remove data from buffer. @@ -498,33 +480,29 @@ int gw_receive_backend_auth( * although no bytes was read. */ rc = 0; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [gw_receive_backend_auth] Read zero bytes from " - "backend dcb %p fd %d in state %s. n %d, head %p, len %ld", - pthread_self(), - dcb, - dcb->fd, - STRDCBSTATE(dcb->state), - n, - head, - (head == NULL) ? 0 : GWBUF_LENGTH(head)))); + MXS_DEBUG("%lu [gw_receive_backend_auth] Read zero bytes from " + "backend dcb %p fd %d in state %s. n %d, head %p, len %ld", + pthread_self(), + dcb, + dcb->fd, + STRDCBSTATE(dcb->state), + n, + head, + (head == NULL) ? 0 : GWBUF_LENGTH(head)); } else { ss_dassert(n < 0 && head == NULL); rc = -1; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_receive_backend_auth] Reading from backend dcb %p " - "fd %d in state %s failed. n %d, head %p, len %ld", - pthread_self(), - dcb, - dcb->fd, - STRDCBSTATE(dcb->state), - n, - head, - (head == NULL) ? 0 : GWBUF_LENGTH(head)))); + MXS_DEBUG("%lu [gw_receive_backend_auth] Reading from backend dcb %p " + "fd %d in state %s failed. n %d, head %p, len %ld", + pthread_self(), + dcb, + dcb->fd, + STRDCBSTATE(dcb->state), + n, + head, + (head == NULL) ? 0 : GWBUF_LENGTH(head)); } return rc; @@ -762,15 +740,13 @@ int gw_do_connect_to_backend( if (so < 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Establishing connection to backend server " - "%s:%d failed.\n\t\t Socket creation failed " - "due %d, %s.", - host, - port, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Establishing connection to backend server " + "%s:%d failed.\n\t\t Socket creation failed " + "due %d, %s.", + host, + port, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); rv = -1; goto return_rv; } @@ -782,15 +758,13 @@ int gw_do_connect_to_backend( if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to set socket options " - "%s:%d failed.\n\t\t Socket configuration failed " - "due %d, %s.", - host, - port, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options " + "%s:%d failed.\n\t\t Socket configuration failed " + "due %d, %s.", + host, + port, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); rv = -1; /** Close socket */ goto close_so; @@ -800,15 +774,13 @@ int gw_do_connect_to_backend( if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to set socket options " - "%s:%d failed.\n\t\t Socket configuration failed " - "due %d, %s.", - host, - port, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options " + "%s:%d failed.\n\t\t Socket configuration failed " + "due %d, %s.", + host, + port, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); rv = -1; /** Close socket */ goto close_so; @@ -818,15 +790,13 @@ int gw_do_connect_to_backend( if(setsockopt(so, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to set socket options " - "%s:%d failed.\n\t\t Socket configuration failed " - "due %d, %s.", - host, - port, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options " + "%s:%d failed.\n\t\t Socket configuration failed " + "due %d, %s.", + host, + port, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); rv = -1; /** Close socket */ goto close_so; @@ -845,27 +815,20 @@ int gw_do_connect_to_backend( else { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to connect backend server %s:%d, " - "due %d, %s.", - host, - port, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to connect backend server %s:%d, " + "due %d, %s.", + host, + port, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); /** Close socket */ goto close_so; } } *fd = so; - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [gw_do_connect_to_backend] Connected to backend server " - "%s:%d, fd %d.", - pthread_self(), - host, - port, - so))); + MXS_DEBUG("%lu [gw_do_connect_to_backend] Connected to backend server " + "%s:%d, fd %d.", + pthread_self(), host, port, so); #if defined(FAKE_CODE) conn_open[so] = true; #endif /* FAKE_CODE */ @@ -878,13 +841,10 @@ close_so: if (close(so) != 0) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error: Failed to " - "close socket %d due %d, %s.", - so, - errno, - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to close socket %d due %d, %s.", + so, + errno, + strerror_r(errno, errbuf, sizeof(errbuf))); } goto return_rv; } @@ -1461,15 +1421,12 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, strcpy(key.hostname, dcb->remote); } - LOGIF(LD, - (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [MySQL Client Auth], checking user [%s@%s]%s%s", - pthread_self(), - key.user, - dcb->remote, - key.resource != NULL ?" db: " :"", - key.resource != NULL ?key.resource :""))); + MXS_DEBUG("%lu [MySQL Client Auth], checking user [%s@%s]%s%s", + pthread_self(), + key.user, + dcb->remote, + key.resource != NULL ?" db: " :"", + key.resource != NULL ?key.resource :""); /* look for user@current_ipv4 now */ user_password = mysql_users_fetch(service->users, &key); @@ -1530,13 +1487,11 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); key.netmask = 0; - LOGIF(LD, - (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", - pthread_self(), - key.user, - dcb->remote))); + MXS_DEBUG("%lu [MySQL Client Auth], checking user [%s@%s] with " + "wildcard host [%%]", + pthread_self(), + key.user, + dcb->remote); user_password = mysql_users_fetch(service->users, &key); @@ -1550,19 +1505,14 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, * user@% not found. */ - LOGIF(LD, - (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [MySQL Client Auth], user [%s@%s] not existent", - pthread_self(), - key.user, - dcb->remote))); + MXS_DEBUG("%lu [MySQL Client Auth], user [%s@%s] not existent", + pthread_self(), + key.user, + dcb->remote); - LOGIF(LT,skygw_log_write_flush( - LOGFILE_ERROR, - "Authentication Failed: user [%s@%s] not found.", - key.user, - dcb->remote)); + MXS_INFO("Authentication Failed: user [%s@%s] not found.", + key.user, + dcb->remote); break; } @@ -1622,14 +1572,12 @@ mysql_send_auth_error ( if (dcb->state != DCB_STATE_POLLING) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [mysql_send_auth_error] dcb %p is in a state %s, " - "and it is not in epoll set anymore. Skip error sending.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)))); - return 0; + MXS_DEBUG("%lu [mysql_send_auth_error] dcb %p is in a state %s, " + "and it is not in epoll set anymore. Skip error sending.", + pthread_self(), + dcb, + STRDCBSTATE(dcb->state)); + return 0; } mysql_errno = 1045; mysql_error_msg = "Access denied!"; @@ -1830,11 +1778,9 @@ void protocol_archive_srv_command( s1 = &p->protocol_command; #if defined(EXTRA_SS_DEBUG) - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Move command %s from fd %d to command history.", - STRPACKETTYPE(s1->scom_cmd), - p->owner_dcb->fd))); + MXS_INFO("Move command %s from fd %d to command history.", + STRPACKETTYPE(s1->scom_cmd), + p->owner_dcb->fd); #endif /** Copy to history list */ if ((h1 = p->protocol_cmd_history) == NULL) @@ -1907,23 +1853,19 @@ void protocol_add_srv_command( p->protocol_command.scom_next = server_command_init(NULL, cmd); } #if defined(EXTRA_SS_DEBUG) - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Added command %s to fd %d.", - STRPACKETTYPE(cmd), - p->owner_dcb->fd))); + MXS_INFO("Added command %s to fd %d.", + STRPACKETTYPE(cmd), + p->owner_dcb->fd); c = &p->protocol_command; while (c != NULL && c->scom_cmd != MYSQL_COM_UNDEFINED) { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "fd %d : %d %s", - p->owner_dcb->fd, - c->scom_cmd, - STRPACKETTYPE(c->scom_cmd)))); - c = c->scom_next; + MXS_INFO("fd %d : %d %s", + p->owner_dcb->fd, + c->scom_cmd, + STRPACKETTYPE(c->scom_cmd)); + c = c->scom_next; } #endif retblock: @@ -1944,11 +1886,9 @@ void protocol_remove_srv_command( spinlock_acquire(&p->protocol_lock); s = &p->protocol_command; #if defined(EXTRA_SS_DEBUG) - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Removed command %s from fd %d.", - STRPACKETTYPE(s->scom_cmd), - p->owner_dcb->fd))); + MXS_INFO("Removed command %s from fd %d.", + STRPACKETTYPE(s->scom_cmd), + p->owner_dcb->fd); #endif if (s->scom_next == NULL) { @@ -1975,12 +1915,10 @@ mysql_server_cmd_t protocol_get_srv_command( { protocol_remove_srv_command(p); } - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [protocol_get_srv_command] Read command %s for fd %d.", - pthread_self(), - STRPACKETTYPE(cmd), - p->owner_dcb->fd))); + MXS_DEBUG("%lu [protocol_get_srv_command] Read command %s for fd %d.", + pthread_self(), + STRPACKETTYPE(cmd), + p->owner_dcb->fd); return cmd; } @@ -2235,10 +2173,8 @@ char *create_auth_fail_str( if (errstr == NULL) { char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Memory allocation failed due to %s.", - strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Memory allocation failed due to %s.", + strerror_r(errno, errbuf, sizeof(errbuf))); goto retblock; } diff --git a/server/modules/protocol/telnetd.c b/server/modules/protocol/telnetd.c index 943154c18..324c66524 100644 --- a/server/modules/protocol/telnetd.c +++ b/server/modules/protocol/telnetd.c @@ -116,9 +116,7 @@ version() void ModuleInit() { - LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, - "Initialise Telnetd Protocol module.\n"))); + MXS_INFO("Initialise Telnetd Protocol module."); } /** @@ -382,7 +380,8 @@ int syseno = 0; if(syseno != 0){ char errbuf[STRERROR_BUFLEN]; - LOGIF(LE, (skygw_log_write_flush(LOGFILE_ERROR,"Error: Failed to set socket options. Error %d: %s", errno, strerror_r(errno, errbuf, sizeof(errbuf))))); + MXS_ERROR("Failed to set socket options. Error %d: %s", + errno, strerror_r(errno, errbuf, sizeof(errbuf))); return 0; } // set NONBLOCKING mode @@ -396,7 +395,7 @@ int syseno = 0; rc = listen(listener->fd, SOMAXCONN); if (rc == 0) { - LOGIF(LM, (skygw_log_write_flush(LOGFILE_MESSAGE,"Listening telnet connections at %s", config))); + MXS_NOTICE("Listening telnet connections at %s", config); } else { int eno = errno; errno = 0; From ac358af7a6ddfeb5458704911fe95f693237c269 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 16 Nov 2015 23:35:25 +0200 Subject: [PATCH 179/179] LOGIF and skygw_log_write removed from cli.c and debugcli.c --- server/modules/routing/cli.c | 12 ++---------- server/modules/routing/debugcli.c | 14 ++++---------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/server/modules/routing/cli.c b/server/modules/routing/cli.c index 19bb15cc7..18a54ab3a 100644 --- a/server/modules/routing/cli.c +++ b/server/modules/routing/cli.c @@ -100,10 +100,7 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise CLI router module %s.\n", - version_str))); + MXS_NOTICE("Initialise CLI router module %s.", version_str); spinlock_init(&instlock); instances = NULL; } @@ -149,12 +146,7 @@ int i; { for (i = 0; options[i]; i++) { - { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Unknown option for CLI '%s'\n", - options[i]))); - } + MXS_ERROR("Unknown option for CLI '%s'", options[i]); } } diff --git a/server/modules/routing/debugcli.c b/server/modules/routing/debugcli.c index 9f6213809..3dcbe0a31 100644 --- a/server/modules/routing/debugcli.c +++ b/server/modules/routing/debugcli.c @@ -99,12 +99,9 @@ version() void ModuleInit() { - LOGIF(LM, (skygw_log_write( - LOGFILE_MESSAGE, - "Initialise debug CLI router module %s.\n", - version_str))); - spinlock_init(&instlock); - instances = NULL; + MXS_NOTICE("Initialise debug CLI router module %s.", version_str); + spinlock_init(&instlock); + instances = NULL; } /** @@ -158,10 +155,7 @@ int i; } else { - LOGIF(LE, (skygw_log_write( - LOGFILE_ERROR, - "Unknown option for CLI '%s'\n", - options[i]))); + MXS_ERROR("Unknown option for CLI '%s'", options[i]); } } }