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:
@ -48,7 +48,6 @@
|
|||||||
#include <maxscale/cdefs.h>
|
#include <maxscale/cdefs.h>
|
||||||
#include <maxscale/spinlock.h>
|
#include <maxscale/spinlock.h>
|
||||||
#include <maxscale/buffer.h>
|
#include <maxscale/buffer.h>
|
||||||
#include <maxscale/listmanager.h>
|
|
||||||
#include <maxscale/gw_protocol.h>
|
#include <maxscale/gw_protocol.h>
|
||||||
#include <maxscale/gw_authenticator.h>
|
#include <maxscale/gw_authenticator.h>
|
||||||
#include <maxscale/gw_ssl.h>
|
#include <maxscale/gw_ssl.h>
|
||||||
@ -216,7 +215,6 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef struct dcb
|
typedef struct dcb
|
||||||
{
|
{
|
||||||
LIST_ENTRY_FIELDS
|
|
||||||
skygw_chk_t dcb_chk_top;
|
skygw_chk_t dcb_chk_top;
|
||||||
bool dcb_errhandle_called; /*< this can be called only once */
|
bool dcb_errhandle_called; /*< this can be called only once */
|
||||||
bool dcb_is_zombie; /**< Whether the DCB is in the zombie list */
|
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 *);
|
int dcb_write(DCB *, GWBUF *);
|
||||||
DCB *dcb_accept(DCB *listener, GWPROTOCOL *protocol_funcs);
|
DCB *dcb_accept(DCB *listener, GWPROTOCOL *protocol_funcs);
|
||||||
bool dcb_pre_alloc(int number);
|
|
||||||
DCB *dcb_alloc(dcb_role_t, struct servlistener *);
|
DCB *dcb_alloc(dcb_role_t, struct servlistener *);
|
||||||
void dcb_free(DCB *);
|
void dcb_free(DCB *);
|
||||||
void dcb_free_all_memory(DCB *dcb);
|
void dcb_free_all_memory(DCB *dcb);
|
||||||
|
|||||||
@ -37,7 +37,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <maxscale/atomic.h>
|
#include <maxscale/atomic.h>
|
||||||
#include <maxscale/buffer.h>
|
#include <maxscale/buffer.h>
|
||||||
#include <maxscale/listmanager.h>
|
|
||||||
#include <maxscale/spinlock.h>
|
#include <maxscale/spinlock.h>
|
||||||
#include <maxscale/resultset.h>
|
#include <maxscale/resultset.h>
|
||||||
#include <maxscale/log_manager.h>
|
#include <maxscale/log_manager.h>
|
||||||
@ -160,7 +159,6 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef struct session
|
typedef struct session
|
||||||
{
|
{
|
||||||
LIST_ENTRY_FIELDS
|
|
||||||
skygw_chk_t ses_chk_top;
|
skygw_chk_t ses_chk_top;
|
||||||
SPINLOCK ses_lock;
|
SPINLOCK ses_lock;
|
||||||
session_state_t state; /*< Current descriptor state */
|
session_state_t state; /*< Current descriptor state */
|
||||||
@ -205,7 +203,6 @@ typedef struct session
|
|||||||
(sess)->tail.session, (buf))
|
(sess)->tail.session, (buf))
|
||||||
|
|
||||||
SESSION *session_alloc(struct service *, struct dcb *);
|
SESSION *session_alloc(struct service *, struct dcb *);
|
||||||
bool session_pre_alloc(int number);
|
|
||||||
SESSION *session_set_dummy(struct dcb *);
|
SESSION *session_set_dummy(struct dcb *);
|
||||||
bool session_free(SESSION *);
|
bool session_free(SESSION *);
|
||||||
int session_isvalid(SESSION *);
|
int session_isvalid(SESSION *);
|
||||||
@ -220,7 +217,6 @@ void dprintSession(struct dcb *, SESSION *);
|
|||||||
void dListSessions(struct dcb *);
|
void dListSessions(struct dcb *);
|
||||||
char *session_state(session_state_t);
|
char *session_state(session_state_t);
|
||||||
bool session_link_dcb(SESSION *, struct dcb *);
|
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_enable_log_priority(SESSION* ses, int priority);
|
||||||
void session_disable_log_priority(SESSION* ses, int priority);
|
void session_disable_log_priority(SESSION* ses, int priority);
|
||||||
RESULTSET *sessionGetList(SESSIONLISTFILTER);
|
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++)
|
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);
|
ss_dassert(!config_file);
|
||||||
|
|
||||||
/* Temporary - should use configuration values and test return value (bool) */
|
|
||||||
dcb_pre_alloc(1000);
|
|
||||||
session_pre_alloc(250);
|
|
||||||
|
|
||||||
global_defaults();
|
global_defaults();
|
||||||
feedback_defaults();
|
feedback_defaults();
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
#include <maxscale/listmanager.h>
|
|
||||||
#include <maxscale/spinlock.h>
|
#include <maxscale/spinlock.h>
|
||||||
#include <maxscale/server.h>
|
#include <maxscale/server.h>
|
||||||
#include <maxscale/session.h>
|
#include <maxscale/session.h>
|
||||||
@ -94,10 +93,6 @@
|
|||||||
#include <maxscale/utils.h>
|
#include <maxscale/utils.h>
|
||||||
#include <maxscale/platform.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 */
|
/* A DCB with null values, used for initialization */
|
||||||
static DCB dcb_initialized = DCB_INIT;
|
static DCB dcb_initialized = DCB_INIT;
|
||||||
|
|
||||||
@ -193,17 +188,6 @@ bool dcb_get_ses_log_info(
|
|||||||
return false;
|
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
|
* @brief Initialize a DCB
|
||||||
*
|
*
|
||||||
@ -252,7 +236,6 @@ dcb_alloc(dcb_role_t role, SERV_LISTENER *listener)
|
|||||||
dcb_initialize(newdcb);
|
dcb_initialize(newdcb);
|
||||||
newdcb->dcb_role = role;
|
newdcb->dcb_role = role;
|
||||||
newdcb->listener = listener;
|
newdcb->listener = listener;
|
||||||
newdcb->entry_is_ready = true;
|
|
||||||
|
|
||||||
return newdcb;
|
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);
|
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
|
* Diagnostic to print all DCB allocated in the system
|
||||||
@ -1839,15 +1827,7 @@ spin_reporter(void *dcb, char *desc, int value)
|
|||||||
*/
|
*/
|
||||||
void printAllDCBs()
|
void printAllDCBs()
|
||||||
{
|
{
|
||||||
list_entry_t *current;
|
dcb_foreach(printAllDCBs_cb, NULL);
|
||||||
|
|
||||||
current = list_start_iteration(&DCBlist);
|
|
||||||
|
|
||||||
while (current)
|
|
||||||
{
|
|
||||||
printDCB((DCB *)current);
|
|
||||||
current = list_iterate(&DCBlist, current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2663,6 +2643,57 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall)
|
|||||||
return count;
|
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
|
* Return DCB counts optionally filtered by usage
|
||||||
*
|
*
|
||||||
@ -2672,55 +2703,11 @@ dcb_persistent_clean_count(DCB *dcb, bool cleanall)
|
|||||||
int
|
int
|
||||||
dcb_count_by_usage(DCB_USAGE usage)
|
dcb_count_by_usage(DCB_USAGE usage)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
struct dcb_usage_count val = {.count = 0, .type = usage};
|
||||||
DCB *dcb;
|
|
||||||
list_entry_t *current;
|
|
||||||
|
|
||||||
current = list_start_iteration(&DCBlist);
|
dcb_foreach(count_by_usage_cb, &val);
|
||||||
|
|
||||||
while (current)
|
return val.count;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1935,11 +1935,6 @@ int main(int argc, char **argv)
|
|||||||
goto return_main;
|
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 */
|
/** Initialize statistics */
|
||||||
ts_stats_init();
|
ts_stats_init();
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <maxscale/alloc.h>
|
#include <maxscale/alloc.h>
|
||||||
#include <maxscale/session.h>
|
#include <maxscale/session.h>
|
||||||
#include <maxscale/listmanager.h>
|
|
||||||
#include <maxscale/service.h>
|
#include <maxscale/service.h>
|
||||||
#include <maxscale/router.h>
|
#include <maxscale/router.h>
|
||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
@ -44,10 +43,6 @@
|
|||||||
#include <maxscale/housekeeper.h>
|
#include <maxscale/housekeeper.h>
|
||||||
#include <maxscale/poll.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 */
|
/* A session with null values, used for initialization */
|
||||||
static SESSION session_initialized = SESSION_INIT;
|
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 void session_add_to_all_list(SESSION *session);
|
||||||
static SESSION *session_find_free();
|
static SESSION *session_find_free();
|
||||||
static void session_final_free(SESSION *session);
|
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
|
* @brief Initialize a session
|
||||||
@ -83,17 +77,6 @@ session_initialize(void *session)
|
|||||||
*(SESSION *)session = session_initialized;
|
*(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.
|
* 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);
|
CHK_SESSION(session);
|
||||||
|
|
||||||
client_dcb->session = session;
|
client_dcb->session = session;
|
||||||
session->entry_is_ready = true;
|
|
||||||
return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session;
|
return SESSION_STATE_TO_BE_FREED == session->state ? NULL : session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,8 +220,6 @@ session_set_dummy(DCB *client_dcb)
|
|||||||
SESSION *session;
|
SESSION *session;
|
||||||
|
|
||||||
session = &session_dummy_struct;
|
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_top = CHK_NUM_SESSION;
|
||||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||||
session->ses_is_child = false;
|
session->ses_is_child = false;
|
||||||
@ -252,7 +232,6 @@ session_set_dummy(DCB *client_dcb)
|
|||||||
session->state = SESSION_STATE_DUMMY;
|
session->state = SESSION_STATE_DUMMY;
|
||||||
session->refcount = 1;
|
session->refcount = 1;
|
||||||
session->ses_id = 0;
|
session->ses_id = 0;
|
||||||
session->next = NULL;
|
|
||||||
|
|
||||||
client_dcb->session = session;
|
client_dcb->session = session;
|
||||||
return session;
|
return session;
|
||||||
@ -448,20 +427,7 @@ session_final_free(SESSION *session)
|
|||||||
int
|
int
|
||||||
session_isvalid(SESSION *session)
|
session_isvalid(SESSION *session)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -479,8 +445,19 @@ printSession(SESSION *session)
|
|||||||
printf("\tState: %s\n", session_state(session->state));
|
printf("\tState: %s\n", session_state(session->state));
|
||||||
printf("\tService: %s (%p)\n", session->service->name, session->service);
|
printf("\tService: %s (%p)\n", session->service->name, session->service);
|
||||||
printf("\tClient DCB: %p\n", session->client_dcb);
|
printf("\tClient DCB: %p\n", session->client_dcb);
|
||||||
printf("\tConnected: %s",
|
printf("\tConnected: %s\n",
|
||||||
asctime_r(localtime_r(&session->stats.connect, &result), timebuf));
|
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
|
void
|
||||||
printAllSessions()
|
printAllSessions()
|
||||||
{
|
{
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
dcb_foreach(printAllSessions_cb, NULL);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -572,7 +480,17 @@ CheckSessions()
|
|||||||
void
|
void
|
||||||
dprintSessionList(DCB *pdcb)
|
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,13 +504,7 @@ dprintSessionList(DCB *pdcb)
|
|||||||
void
|
void
|
||||||
dprintAllSessions(DCB *dcb)
|
dprintAllSessions(DCB *dcb)
|
||||||
{
|
{
|
||||||
|
dcb_foreach(dprintAllSessions_cb, dcb);
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
|
||||||
while (current)
|
|
||||||
{
|
|
||||||
dprintSession(dcb, (SESSION *)current);
|
|
||||||
current = list_iterate(&SESSIONlist, current);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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
|
* List all sessions in tabular form to a DCB
|
||||||
*
|
*
|
||||||
@ -657,32 +585,13 @@ dprintSession(DCB *dcb, SESSION *print_session)
|
|||||||
void
|
void
|
||||||
dListSessions(DCB *dcb)
|
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, "-----------------+-----------------+----------------+--------------------------\n");
|
||||||
dcb_printf(dcb, "Session | Client | Service | State\n");
|
dcb_printf(dcb, "Session | Client | Service | State\n");
|
||||||
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n");
|
||||||
written_heading = true;
|
|
||||||
}
|
dcb_foreach(dListSessions_cb, dcb);
|
||||||
while (current)
|
|
||||||
{
|
dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n\n");
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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.
|
* Create the filter chain for this session.
|
||||||
*
|
*
|
||||||
@ -892,9 +779,44 @@ session_getUser(SESSION *session)
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
int current;
|
||||||
SESSIONLISTFILTER filter;
|
SESSIONLISTFILTER filter;
|
||||||
|
RESULT_ROW *row;
|
||||||
|
RESULTSET *set;
|
||||||
} SESSIONFILTER;
|
} 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
|
* Provide a row to the result set that defines the set of sessions
|
||||||
*
|
*
|
||||||
@ -906,74 +828,18 @@ static RESULT_ROW *
|
|||||||
sessionRowCallback(RESULTSET *set, void *data)
|
sessionRowCallback(RESULTSET *set, void *data)
|
||||||
{
|
{
|
||||||
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
SESSIONFILTER *cbdata = (SESSIONFILTER*)data;
|
||||||
int i = 0;
|
RESULT_ROW *row = NULL;
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
|
||||||
|
|
||||||
/* Skip to the first non-listener if not showing listeners */
|
dcb_foreach(dcb_iter_cb, cbdata);
|
||||||
current = skip_maybe_to_next_non_listener(current, cbdata->filter);
|
|
||||||
|
|
||||||
while (i < cbdata->index && current)
|
if (cbdata->row)
|
||||||
{
|
{
|
||||||
if (cbdata->filter == SESSION_LIST_ALL ||
|
row = cbdata->row;
|
||||||
(cbdata->filter == SESSION_LIST_CONNECTION &&
|
cbdata->row = NULL;
|
||||||
((SESSION *)current)->state != SESSION_STATE_LISTENER))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
current = list_iterate(&SESSIONlist, current);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
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 a resultset that has the current set of sessions in it
|
* Return a resultset that has the current set of sessions in it
|
||||||
@ -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
|
* so we suppress the warning. In fact, the function call results in return
|
||||||
* of the set structure which includes a pointer to data
|
* of the set structure which includes a pointer to data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*lint -e429 */
|
/*lint -e429 */
|
||||||
RESULTSET *
|
RESULTSET *
|
||||||
sessionGetList(SESSIONLISTFILTER filter)
|
sessionGetList(SESSIONLISTFILTER filter)
|
||||||
@ -998,11 +865,16 @@ sessionGetList(SESSIONLISTFILTER filter)
|
|||||||
}
|
}
|
||||||
data->index = 0;
|
data->index = 0;
|
||||||
data->filter = filter;
|
data->filter = filter;
|
||||||
|
data->current = 0;
|
||||||
|
data->row = NULL;
|
||||||
|
|
||||||
if ((set = resultset_create(sessionRowCallback, data)) == NULL)
|
if ((set = resultset_create(sessionRowCallback, data)) == NULL)
|
||||||
{
|
{
|
||||||
MXS_FREE(data);
|
MXS_FREE(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data->set = set;
|
||||||
resultset_add_column(set, "Session", 16, COL_TYPE_VARCHAR);
|
resultset_add_column(set, "Session", 16, COL_TYPE_VARCHAR);
|
||||||
resultset_add_column(set, "Client", 15, COL_TYPE_VARCHAR);
|
resultset_add_column(set, "Client", 15, COL_TYPE_VARCHAR);
|
||||||
resultset_add_column(set, "Service", 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);
|
int reset_session_state(TEE_SESSION* my_session, GWBUF* buffer);
|
||||||
void create_orphan(SESSION* ses);
|
void create_orphan(SESSION* ses);
|
||||||
|
|
||||||
extern LIST_CONFIG SESSIONlist;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
orphan_free(void* data)
|
orphan_free(void* data)
|
||||||
{
|
{
|
||||||
@ -299,7 +297,7 @@ orphan_free(void* data)
|
|||||||
tmp->session->router_session);
|
tmp->session->router_session);
|
||||||
|
|
||||||
tmp->session->state = SESSION_STATE_FREE;
|
tmp->session->state = SESSION_STATE_FREE;
|
||||||
list_free_entry(&SESSIONlist, (list_entry_t*)tmp->session);
|
MXS_FREE(tmp->session);
|
||||||
MXS_FREE(tmp);
|
MXS_FREE(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -92,8 +92,6 @@
|
|||||||
#define ARG_TYPE_FILTER 9
|
#define ARG_TYPE_FILTER 9
|
||||||
#define ARG_TYPE_NUMERIC 10
|
#define ARG_TYPE_NUMERIC 10
|
||||||
|
|
||||||
extern LIST_CONFIG SESSIONlist;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subcommand structure
|
* The subcommand structure
|
||||||
*
|
*
|
||||||
@ -2115,6 +2113,31 @@ static bool get_log_action(const char* name, struct log_action_entry* entryp)
|
|||||||
return found;
|
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
|
* Enables a log for a single session
|
||||||
* @param session The session in question
|
* @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))
|
if (get_log_action(arg1, &entry))
|
||||||
{
|
{
|
||||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
size_t id = (size_t)strtol(arg2, NULL, 10);
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
void *data[] = {&entry, &id, (void*)true};
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current)
|
if (dcb_foreach(seslog_cb, data))
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
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))
|
if (get_log_action(arg1, &entry))
|
||||||
{
|
{
|
||||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
size_t id = (size_t)strtol(arg2, NULL, 10);
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
void *data[] = {&entry, &id, (void*)false};
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current)
|
if (dcb_foreach(seslog_cb, data))
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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;
|
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
|
* Enables a log priority for a single session
|
||||||
* @param session The session in question
|
* @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)
|
if (priority != -1)
|
||||||
{
|
{
|
||||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
size_t id = (size_t) strtol(arg2, NULL, 10);
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
void *data[] = {&priority, &id, (void*)true};
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current)
|
if (dcb_foreach(sesprio_cb, data))
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
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)
|
if (priority != -1)
|
||||||
{
|
{
|
||||||
size_t id = (size_t) strtol(arg2, 0, 0);
|
size_t id = (size_t) strtol(arg2, NULL, 10);
|
||||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
void *data[] = {&priority, &id, (void*)false};
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current)
|
if (dcb_foreach(seslog_cb, data))
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
dcb_printf(dcb, "Session not found: %s.\n", arg2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user