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:
Markus Makela 2016-11-22 11:03:05 +02:00
parent e53b9585dd
commit 2efa862944
9 changed files with 222 additions and 378 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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++)

View File

@ -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();

View File

@ -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;
}
/**

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}