Remove listmanager code
The code prevented scaling by imposing global spinlocks for the DCBs and SESSIONs. Removing this list means that a thread-local list must be taken into use to replace it.
This commit is contained in:
parent
e53b9585dd
commit
2efa862944
@ -48,7 +48,6 @@
|
||||
#include <maxscale/cdefs.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/gw_protocol.h>
|
||||
#include <maxscale/gw_authenticator.h>
|
||||
#include <maxscale/gw_ssl.h>
|
||||
@ -216,7 +215,6 @@ typedef enum
|
||||
*/
|
||||
typedef struct dcb
|
||||
{
|
||||
LIST_ENTRY_FIELDS
|
||||
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 */
|
||||
@ -326,7 +324,6 @@ void dcb_global_init();
|
||||
|
||||
int dcb_write(DCB *, GWBUF *);
|
||||
DCB *dcb_accept(DCB *listener, GWPROTOCOL *protocol_funcs);
|
||||
bool dcb_pre_alloc(int number);
|
||||
DCB *dcb_alloc(dcb_role_t, struct servlistener *);
|
||||
void dcb_free(DCB *);
|
||||
void dcb_free_all_memory(DCB *dcb);
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <time.h>
|
||||
#include <maxscale/atomic.h>
|
||||
#include <maxscale/buffer.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/resultset.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
@ -160,7 +159,6 @@ typedef enum
|
||||
*/
|
||||
typedef struct session
|
||||
{
|
||||
LIST_ENTRY_FIELDS
|
||||
skygw_chk_t ses_chk_top;
|
||||
SPINLOCK ses_lock;
|
||||
session_state_t state; /*< Current descriptor state */
|
||||
@ -205,7 +203,6 @@ typedef struct session
|
||||
(sess)->tail.session, (buf))
|
||||
|
||||
SESSION *session_alloc(struct service *, struct dcb *);
|
||||
bool session_pre_alloc(int number);
|
||||
SESSION *session_set_dummy(struct dcb *);
|
||||
bool session_free(SESSION *);
|
||||
int session_isvalid(SESSION *);
|
||||
@ -220,7 +217,6 @@ void dprintSession(struct dcb *, SESSION *);
|
||||
void dListSessions(struct dcb *);
|
||||
char *session_state(session_state_t);
|
||||
bool session_link_dcb(SESSION *, struct dcb *);
|
||||
SESSION* get_session_by_router_ses(void* rses);
|
||||
void session_enable_log_priority(SESSION* ses, int priority);
|
||||
void session_disable_log_priority(SESSION* ses, int priority);
|
||||
RESULTSET *sessionGetList(SESSIONLISTFILTER);
|
||||
|
@ -1,4 +1,4 @@
|
||||
add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c )
|
||||
add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c modulecmd.c )
|
||||
|
||||
target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl pthread crypt dl crypto inih z rt m stdc++)
|
||||
|
||||
|
@ -702,10 +702,6 @@ config_load(const char *filename)
|
||||
{
|
||||
ss_dassert(!config_file);
|
||||
|
||||
/* Temporary - should use configuration values and test return value (bool) */
|
||||
dcb_pre_alloc(1000);
|
||||
session_pre_alloc(250);
|
||||
|
||||
global_defaults();
|
||||
feedback_defaults();
|
||||
|
||||
|
@ -70,7 +70,6 @@
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/server.h>
|
||||
#include <maxscale/session.h>
|
||||
@ -94,10 +93,6 @@
|
||||
#include <maxscale/utils.h>
|
||||
#include <maxscale/platform.h>
|
||||
|
||||
/* The list of all DCBs */
|
||||
static LIST_CONFIG DCBlist =
|
||||
{LIST_TYPE_RECYCLABLE, sizeof(DCB), SPINLOCK_INIT};
|
||||
|
||||
/* A DCB with null values, used for initialization */
|
||||
static DCB dcb_initialized = DCB_INIT;
|
||||
|
||||
@ -193,17 +188,6 @@ bool dcb_get_ses_log_info(
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Pre-allocate memory for a number of DCBs
|
||||
*
|
||||
* @param The number of DCBs to be pre-allocated
|
||||
*/
|
||||
bool
|
||||
dcb_pre_alloc(int number)
|
||||
{
|
||||
return list_pre_alloc(&DCBlist, number, dcb_initialize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a DCB
|
||||
*
|
||||
@ -252,7 +236,6 @@ dcb_alloc(dcb_role_t role, SERV_LISTENER *listener)
|
||||
dcb_initialize(newdcb);
|
||||
newdcb->dcb_role = role;
|
||||
newdcb->listener = listener;
|
||||
newdcb->entry_is_ready = true;
|
||||
|
||||
return newdcb;
|
||||
}
|
||||
@ -1832,6 +1815,11 @@ spin_reporter(void *dcb, char *desc, int value)
|
||||
dcb_printf((DCB *)dcb, "\t\t%-40s %d\n", desc, value);
|
||||
}
|
||||
|
||||
bool printAllDCBs_cb(DCB *dcb, void *data)
|
||||
{
|
||||
printDCB(dcb);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostic to print all DCB allocated in the system
|
||||
@ -1839,15 +1827,7 @@ spin_reporter(void *dcb, char *desc, int value)
|
||||
*/
|
||||
void printAllDCBs()
|
||||
{
|
||||
list_entry_t *current;
|
||||
|
||||
current = list_start_iteration(&DCBlist);
|
||||
|
||||
while (current)
|
||||
{
|
||||
printDCB((DCB *)current);
|
||||
current = list_iterate(&DCBlist, current);
|
||||
}
|
||||
dcb_foreach(printAllDCBs_cb, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2663,6 +2643,57 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall)
|
||||
return count;
|
||||
}
|
||||
|
||||
struct dcb_usage_count
|
||||
{
|
||||
int count;
|
||||
DCB_USAGE type;
|
||||
};
|
||||
|
||||
bool count_by_usage_cb(DCB *dcb, void *data)
|
||||
{
|
||||
struct dcb_usage_count *d = (struct dcb_usage_count*)data;
|
||||
|
||||
switch (d->type)
|
||||
{
|
||||
case DCB_USAGE_CLIENT:
|
||||
if (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role)
|
||||
{
|
||||
d->count++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_LISTENER:
|
||||
if (dcb->state == DCB_STATE_LISTENING)
|
||||
{
|
||||
d->count++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_BACKEND:
|
||||
if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||
{
|
||||
d->count++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_INTERNAL:
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER ||
|
||||
dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||
{
|
||||
d->count++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_ZOMBIE:
|
||||
if (DCB_ISZOMBIE(dcb))
|
||||
{
|
||||
d->count++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_ALL:
|
||||
d->count++;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return DCB counts optionally filtered by usage
|
||||
*
|
||||
@ -2672,55 +2703,11 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall)
|
||||
int
|
||||
dcb_count_by_usage(DCB_USAGE usage)
|
||||
{
|
||||
int rval = 0;
|
||||
DCB *dcb;
|
||||
list_entry_t *current;
|
||||
struct dcb_usage_count val = {.count = 0, .type = usage};
|
||||
|
||||
current = list_start_iteration(&DCBlist);
|
||||
dcb_foreach(count_by_usage_cb, &val);
|
||||
|
||||
while (current)
|
||||
{
|
||||
dcb = (DCB *)current;
|
||||
switch (usage)
|
||||
{
|
||||
case DCB_USAGE_CLIENT:
|
||||
if (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role)
|
||||
{
|
||||
rval++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_LISTENER:
|
||||
if (dcb->state == DCB_STATE_LISTENING)
|
||||
{
|
||||
rval++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_BACKEND:
|
||||
if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||
{
|
||||
rval++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_INTERNAL:
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER ||
|
||||
dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||
{
|
||||
rval++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_ZOMBIE:
|
||||
if (DCB_ISZOMBIE(dcb))
|
||||
{
|
||||
rval++;
|
||||
}
|
||||
break;
|
||||
case DCB_USAGE_ALL:
|
||||
rval++;
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&DCBlist, current);
|
||||
}
|
||||
return rval;
|
||||
return val.count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1935,11 +1935,6 @@ int main(int argc, char **argv)
|
||||
goto return_main;
|
||||
}
|
||||
|
||||
/* Temporary - should use configuration values and test return value (bool)
|
||||
* TODO: Enable the list manager code */
|
||||
dcb_pre_alloc(1);
|
||||
session_pre_alloc(1);
|
||||
|
||||
/** Initialize statistics */
|
||||
ts_stats_init();
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <errno.h>
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/listmanager.h>
|
||||
#include <maxscale/service.h>
|
||||
#include <maxscale/router.h>
|
||||
#include <maxscale/dcb.h>
|
||||
@ -44,10 +43,6 @@
|
||||
#include <maxscale/housekeeper.h>
|
||||
#include <maxscale/poll.h>
|
||||
|
||||
/* This list of all sessions */
|
||||
LIST_CONFIG SESSIONlist =
|
||||
{LIST_TYPE_RECYCLABLE, sizeof(SESSION), SPINLOCK_INIT};
|
||||
|
||||
/* A session with null values, used for initialization */
|
||||
static SESSION session_initialized = SESSION_INIT;
|
||||
|
||||
@ -62,7 +57,6 @@ static void session_simple_free(SESSION *session, DCB *dcb);
|
||||
static void session_add_to_all_list(SESSION *session);
|
||||
static SESSION *session_find_free();
|
||||
static void session_final_free(SESSION *session);
|
||||
static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESSIONLISTFILTER filter);
|
||||
|
||||
/**
|
||||
* @brief Initialize a session
|
||||
@ -83,17 +77,6 @@ session_initialize(void *session)
|
||||
*(SESSION *)session = session_initialized;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Pre-allocate memory for a number of sessions
|
||||
*
|
||||
* @param The number of sessions to be pre-allocated
|
||||
*/
|
||||
bool
|
||||
session_pre_alloc(int number)
|
||||
{
|
||||
return list_pre_alloc(&SESSIONlist, number, session_initialize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new session for a new client of the specified service.
|
||||
*
|
||||
@ -220,7 +203,6 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
CHK_SESSION(session);
|
||||
|
||||
client_dcb->session = session;
|
||||
session->entry_is_ready = true;
|
||||
return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session;
|
||||
}
|
||||
|
||||
@ -238,8 +220,6 @@ session_set_dummy(DCB *client_dcb)
|
||||
SESSION *session;
|
||||
|
||||
session = &session_dummy_struct;
|
||||
session->list_entry_chk_top = CHK_NUM_MANAGED_LIST;
|
||||
session->list_entry_chk_tail = CHK_NUM_MANAGED_LIST;
|
||||
session->ses_chk_top = CHK_NUM_SESSION;
|
||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||
session->ses_is_child = false;
|
||||
@ -252,7 +232,6 @@ session_set_dummy(DCB *client_dcb)
|
||||
session->state = SESSION_STATE_DUMMY;
|
||||
session->refcount = 1;
|
||||
session->ses_id = 0;
|
||||
session->next = NULL;
|
||||
|
||||
client_dcb->session = session;
|
||||
return session;
|
||||
@ -448,20 +427,7 @@ session_final_free(SESSION *session)
|
||||
int
|
||||
session_isvalid(SESSION *session)
|
||||
{
|
||||
int rval = 0;
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
if ((SESSION *)current == session)
|
||||
{
|
||||
rval = 1;
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
|
||||
return rval;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -479,8 +445,19 @@ printSession(SESSION *session)
|
||||
printf("\tState: %s\n", session_state(session->state));
|
||||
printf("\tService: %s (%p)\n", session->service->name, session->service);
|
||||
printf("\tClient DCB: %p\n", session->client_dcb);
|
||||
printf("\tConnected: %s",
|
||||
printf("\tConnected: %s\n",
|
||||
asctime_r(localtime_r(&session->stats.connect, &result), timebuf));
|
||||
printf("\tRouter Session: %p\n", session->router_session);
|
||||
}
|
||||
|
||||
bool printAllSessions_cb(DCB *dcb, void *data)
|
||||
{
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER)
|
||||
{
|
||||
printSession(dcb->session);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -492,76 +469,7 @@ printSession(SESSION *session)
|
||||
void
|
||||
printAllSessions()
|
||||
{
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
printSession((SESSION *)current);
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check sessions
|
||||
*
|
||||
* Designed to be called within a debugger session in order
|
||||
* to display information regarding "interesting" sessions
|
||||
*/
|
||||
void
|
||||
CheckSessions()
|
||||
{
|
||||
list_entry_t *current;
|
||||
int noclients = 0;
|
||||
int norouter = 0;
|
||||
|
||||
current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *list_session = (SESSION *)current;
|
||||
if (list_session->state != SESSION_STATE_LISTENER ||
|
||||
list_session->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
{
|
||||
if (list_session->client_dcb == NULL && list_session->refcount)
|
||||
{
|
||||
if (noclients == 0)
|
||||
{
|
||||
printf("Sessions without a client DCB.\n");
|
||||
printf("==============================\n");
|
||||
}
|
||||
printSession(list_session);
|
||||
noclients++;
|
||||
}
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
if (noclients)
|
||||
{
|
||||
printf("%d Sessions have no clients\n", noclients);
|
||||
}
|
||||
current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *list_session = (SESSION *)current;
|
||||
if (list_session->state != SESSION_STATE_LISTENER ||
|
||||
list_session->state != SESSION_STATE_LISTENER_STOPPED)
|
||||
{
|
||||
if (list_session->router_session == NULL && list_session->refcount)
|
||||
{
|
||||
if (norouter == 0)
|
||||
{
|
||||
printf("Sessions without a router session.\n");
|
||||
printf("==================================\n");
|
||||
}
|
||||
printSession(list_session);
|
||||
norouter++;
|
||||
}
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
if (norouter)
|
||||
{
|
||||
printf("%d Sessions have no router session\n", norouter);
|
||||
}
|
||||
dcb_foreach(printAllSessions_cb, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -572,7 +480,17 @@ CheckSessions()
|
||||
void
|
||||
dprintSessionList(DCB *pdcb)
|
||||
{
|
||||
dprintListStats(pdcb, &SESSIONlist, "All Sessions");
|
||||
}
|
||||
|
||||
/** Callback for dprintAllSessions */
|
||||
bool dprintAllSessions_cb(DCB *dcb, void *data)
|
||||
{
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER)
|
||||
{
|
||||
DCB *out_dcb = (DCB*)data;
|
||||
dprintSession(out_dcb, dcb->session);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -586,14 +504,8 @@ dprintSessionList(DCB *pdcb)
|
||||
void
|
||||
dprintAllSessions(DCB *dcb)
|
||||
{
|
||||
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
dprintSession(dcb, (SESSION *)current);
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
}
|
||||
dcb_foreach(dprintAllSessions_cb, dcb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a particular session to a DCB
|
||||
@ -646,6 +558,22 @@ dprintSession(DCB *dcb, SESSION *print_session)
|
||||
}
|
||||
}
|
||||
|
||||
bool dListSessions_cb(DCB *dcb, void *data)
|
||||
{
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER)
|
||||
{
|
||||
DCB *out_dcb = (DCB*)data;
|
||||
SESSION *session = dcb->session;
|
||||
dcb_printf(out_dcb, "%-16p | %-15s | %-14s | %s\n", session,
|
||||
session->client_dcb && session->client_dcb->remote ?
|
||||
session->client_dcb->remote : "",
|
||||
session->service && session->service->name ?
|
||||
session->service->name : "",
|
||||
session_state(session->state));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* List all sessions in tabular form to a DCB
|
||||
*
|
||||
@ -657,32 +585,13 @@ dprintSession(DCB *dcb, SESSION *print_session)
|
||||
void
|
||||
dListSessions(DCB *dcb)
|
||||
{
|
||||
bool written_heading = false;
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
if (current)
|
||||
{
|
||||
dcb_printf(dcb, "Sessions.\n");
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
dcb_printf(dcb, "Session | Client | Service | State\n");
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
written_heading = true;
|
||||
}
|
||||
while (current)
|
||||
{
|
||||
SESSION *list_session = (SESSION *)current;
|
||||
dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", list_session,
|
||||
((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""),
|
||||
(list_session->service && list_session->service->name ? list_session->service->name
|
||||
: ""),
|
||||
session_state(list_session->state));
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
if (written_heading)
|
||||
{
|
||||
dcb_printf(dcb,
|
||||
"-----------------+-----------------+----------------+--------------------------\n\n");
|
||||
}
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
dcb_printf(dcb, "Session | Client | Service | State\n");
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||
|
||||
dcb_foreach(dListSessions_cb, dcb);
|
||||
|
||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -719,28 +628,6 @@ session_state(session_state_t state)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Find the session that relates to a given router session
|
||||
*
|
||||
* @param rses A router session
|
||||
* @return The related session, or NULL if none
|
||||
*/
|
||||
SESSION* get_session_by_router_ses(void* rses)
|
||||
{
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
if (((SESSION *)current)->router_session == rses)
|
||||
{
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
return (SESSION *)current;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the filter chain for this session.
|
||||
*
|
||||
@ -892,9 +779,44 @@ session_getUser(SESSION *session)
|
||||
typedef struct
|
||||
{
|
||||
int index;
|
||||
int current;
|
||||
SESSIONLISTFILTER filter;
|
||||
RESULT_ROW *row;
|
||||
RESULTSET *set;
|
||||
} SESSIONFILTER;
|
||||
|
||||
bool dcb_iter_cb(DCB *dcb, void *data)
|
||||
{
|
||||
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
||||
|
||||
if (cbdata->current < cbdata->index)
|
||||
{
|
||||
if (cbdata->filter == SESSION_LIST_ALL ||
|
||||
(cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
(dcb->session->state != SESSION_STATE_LISTENER)))
|
||||
{
|
||||
cbdata->current++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[20];
|
||||
SESSION *list_session = dcb->session;
|
||||
|
||||
cbdata->index++;
|
||||
cbdata->row = resultset_make_row(cbdata->set);
|
||||
snprintf(buf, sizeof(buf), "%p", list_session);
|
||||
resultset_row_set(cbdata->row, 0, buf);
|
||||
resultset_row_set(cbdata->row, 1, ((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""));
|
||||
resultset_row_set(cbdata->row, 2, (list_session->service && list_session->service->name
|
||||
? list_session->service->name : ""));
|
||||
resultset_row_set(cbdata->row, 3, session_state(list_session->state));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a row to the result set that defines the set of sessions
|
||||
*
|
||||
@ -905,74 +827,18 @@ typedef struct
|
||||
static RESULT_ROW *
|
||||
sessionRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
SESSIONFILTER *cbdata = (SESSIONFILTER *)data;
|
||||
int i = 0;
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
||||
RESULT_ROW *row = NULL;
|
||||
|
||||
/* Skip to the first non-listener if not showing listeners */
|
||||
current = skip_maybe_to_next_non_listener(current, cbdata->filter);
|
||||
dcb_foreach(dcb_iter_cb, cbdata);
|
||||
|
||||
while (i < cbdata->index && current)
|
||||
if (cbdata->row)
|
||||
{
|
||||
if (cbdata->filter == SESSION_LIST_ALL ||
|
||||
(cbdata->filter == SESSION_LIST_CONNECTION &&
|
||||
((SESSION *)current)->state != SESSION_STATE_LISTENER))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
row = cbdata->row;
|
||||
cbdata->row = NULL;
|
||||
}
|
||||
|
||||
/* Skip to the next non-listener if not showing listeners */
|
||||
current = skip_maybe_to_next_non_listener(current, cbdata->filter);
|
||||
|
||||
if (NULL == current)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
SESSION *list_session = (SESSION *)current;
|
||||
|
||||
cbdata->index++;
|
||||
row = resultset_make_row(set);
|
||||
snprintf(buf,19, "%p", list_session);
|
||||
buf[19] = '\0';
|
||||
resultset_row_set(row, 0, buf);
|
||||
resultset_row_set(row, 1, ((list_session->client_dcb && list_session->client_dcb->remote)
|
||||
? list_session->client_dcb->remote : ""));
|
||||
resultset_row_set(row, 2, (list_session->service && list_session->service->name
|
||||
? list_session->service->name : ""));
|
||||
resultset_row_set(row, 3, session_state(list_session->state));
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Skip to the next non-listener session, if not showing listeners
|
||||
*
|
||||
* Based on a test of the filter that is the second parameter, along with the
|
||||
* state of the sessions.
|
||||
*
|
||||
* @param current The session to start the possible skipping
|
||||
* @param filter The filter the defines the operation
|
||||
*
|
||||
* @result The first session beyond those skipped, or the starting session;
|
||||
* NULL if the list of sessions is exhausted.
|
||||
*/
|
||||
static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESSIONLISTFILTER filter)
|
||||
{
|
||||
/* Skip to the first non-listener if not showing listeners */
|
||||
while (current && filter == SESSION_LIST_CONNECTION &&
|
||||
((SESSION *)current)->state == SESSION_STATE_LISTENER)
|
||||
{
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
return current;
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -985,6 +851,7 @@ static list_entry_t *skip_maybe_to_next_non_listener(list_entry_t *current, SESS
|
||||
* so we suppress the warning. In fact, the function call results in return
|
||||
* of the set structure which includes a pointer to data
|
||||
*/
|
||||
|
||||
/*lint -e429 */
|
||||
RESULTSET *
|
||||
sessionGetList(SESSIONLISTFILTER filter)
|
||||
@ -998,11 +865,16 @@ sessionGetList(SESSIONLISTFILTER filter)
|
||||
}
|
||||
data->index = 0;
|
||||
data->filter = filter;
|
||||
data->current = 0;
|
||||
data->row = NULL;
|
||||
|
||||
if ((set = resultset_create(sessionRowCallback, data)) == NULL)
|
||||
{
|
||||
MXS_FREE(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->set = set;
|
||||
resultset_add_column(set, "Session", 16, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Client", 15, COL_TYPE_VARCHAR);
|
||||
resultset_add_column(set, "Service", 15, COL_TYPE_VARCHAR);
|
||||
|
@ -213,8 +213,6 @@ int route_single_query(TEE_INSTANCE* my_instance,
|
||||
int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer);
|
||||
void create_orphan(SESSION* ses);
|
||||
|
||||
extern LIST_CONFIG SESSIONlist;
|
||||
|
||||
static void
|
||||
orphan_free(void* data)
|
||||
{
|
||||
@ -299,7 +297,7 @@ orphan_free(void* data)
|
||||
tmp->session->router_session);
|
||||
|
||||
tmp->session->state = SESSION_STATE_FREE;
|
||||
list_free_entry(&SESSIONlist, (list_entry_t*)tmp->session);
|
||||
MXS_FREE(tmp->session);
|
||||
MXS_FREE(tmp);
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,6 @@
|
||||
#define ARG_TYPE_FILTER 9
|
||||
#define ARG_TYPE_NUMERIC 10
|
||||
|
||||
extern LIST_CONFIG SESSIONlist;
|
||||
|
||||
/**
|
||||
* The subcommand structure
|
||||
*
|
||||
@ -2115,6 +2113,31 @@ static bool get_log_action(const char* name, struct log_action_entry* entryp)
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
bool seslog_cb(DCB *dcb, void *data)
|
||||
{
|
||||
bool rval = true;
|
||||
struct log_action_entry *entry = ((void**)data)[0];
|
||||
size_t *id = ((void**)data)[1];
|
||||
bool enable = (bool)((void**)data)[2];
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
if (session->ses_id == *id)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
session_enable_log_priority(session, entry->priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
session_disable_log_priority(session, entry->priority);
|
||||
}
|
||||
rval = false;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a log for a single session
|
||||
* @param session The session in question
|
||||
@ -2127,21 +2150,10 @@ static void enable_sess_log_action(DCB *dcb, char *arg1, char *arg2)
|
||||
|
||||
if (get_log_action(arg1, &entry))
|
||||
{
|
||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *session = (SESSION *)current;
|
||||
if (session->ses_id == id)
|
||||
{
|
||||
session_enable_log_priority(session, entry.priority);
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
size_t id = (size_t)strtol(arg2, NULL, 10);
|
||||
void *data[] = {&entry, &id, (void*)true};
|
||||
|
||||
if (!current)
|
||||
if (dcb_foreach(seslog_cb, data))
|
||||
{
|
||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||
}
|
||||
@ -2164,28 +2176,17 @@ static void disable_sess_log_action(DCB *dcb, char *arg1, char *arg2)
|
||||
|
||||
if (get_log_action(arg1, &entry))
|
||||
{
|
||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *session = (SESSION *)current;
|
||||
if (session->ses_id == id)
|
||||
{
|
||||
session_disable_log_priority(session, entry.priority);
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
size_t id = (size_t)strtol(arg2, NULL, 10);
|
||||
void *data[] = {&entry, &id, (void*)false};
|
||||
|
||||
if (!current)
|
||||
if (dcb_foreach(seslog_cb, data))
|
||||
{
|
||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, "%s is not supported for disable log.\n", arg1);
|
||||
dcb_printf(dcb, "%s is not supported for enable log.\n", arg1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2226,6 +2227,30 @@ static int string_to_priority(const char* name)
|
||||
return result ? result->priority : -1;
|
||||
}
|
||||
|
||||
bool sesprio_cb(DCB *dcb, void *data)
|
||||
{
|
||||
bool rval = true;
|
||||
int *priority = ((void**)data)[0];
|
||||
size_t *id = ((void**)data)[1];
|
||||
bool enable = (bool)((void**)data)[2];
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
if (session->ses_id == *id)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
session_enable_log_priority(session, *priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
session_disable_log_priority(session, *priority);
|
||||
}
|
||||
rval = false;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a log priority for a single session
|
||||
* @param session The session in question
|
||||
@ -2238,21 +2263,10 @@ static void enable_sess_log_priority(DCB *dcb, char *arg1, char *arg2)
|
||||
|
||||
if (priority != -1)
|
||||
{
|
||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *session = (SESSION *)current;
|
||||
if (session->ses_id == id)
|
||||
{
|
||||
session_enable_log_priority(session, priority);
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
size_t id = (size_t) strtol(arg2, NULL, 10);
|
||||
void *data[] = {&priority, &id, (void*)true};
|
||||
|
||||
if (!current)
|
||||
if (dcb_foreach(sesprio_cb, data))
|
||||
{
|
||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||
}
|
||||
@ -2275,21 +2289,10 @@ static void disable_sess_log_priority(DCB *dcb, char *arg1, char *arg2)
|
||||
|
||||
if (priority != -1)
|
||||
{
|
||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
while (current)
|
||||
{
|
||||
SESSION *session = (SESSION *)current;
|
||||
if (session->ses_id == id)
|
||||
{
|
||||
session_disable_log_priority(session, priority);
|
||||
list_terminate_iteration_early(&SESSIONlist, current);
|
||||
break;
|
||||
}
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
size_t id = (size_t) strtol(arg2, NULL, 10);
|
||||
void *data[] = {&priority, &id, (void*)false};
|
||||
|
||||
if (!current)
|
||||
if (dcb_foreach(seslog_cb, data))
|
||||
{
|
||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user