User friendly bit mask display for DCB print; monitors to work via inserting hangups instead of callbacks.
This commit is contained in:
@ -58,6 +58,7 @@
|
|||||||
* 04/09/2015 Martin Brampton Changes to ensure DCB always has session pointer
|
* 04/09/2015 Martin Brampton Changes to ensure DCB always has session pointer
|
||||||
* 28/09/2015 Martin Brampton Add counters, maxima for DCBs and zombies
|
* 28/09/2015 Martin Brampton Add counters, maxima for DCBs and zombies
|
||||||
* 29/05/2015 Martin Brampton Impose locking in dcb_call_foreach callbacks
|
* 29/05/2015 Martin Brampton Impose locking in dcb_call_foreach callbacks
|
||||||
|
* 17/10/2015 Martin Brampton Add hangup for each and bitmask display MaxAdmin
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -544,6 +545,7 @@ dcb_process_victim_queue(DCB *listofdcb)
|
|||||||
/*<
|
/*<
|
||||||
* Stop dcb's listening and modify state accordingly.
|
* Stop dcb's listening and modify state accordingly.
|
||||||
*/
|
*/
|
||||||
|
spinlock_acquire(&dcb->dcb_initlock);
|
||||||
if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING)
|
if (dcb->state == DCB_STATE_POLLING || dcb->state == DCB_STATE_LISTENING)
|
||||||
{
|
{
|
||||||
if (dcb->state == DCB_STATE_LISTENING)
|
if (dcb->state == DCB_STATE_LISTENING)
|
||||||
@ -560,6 +562,7 @@ dcb_process_victim_queue(DCB *listofdcb)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Must be DCB_STATE_POLLING */
|
/* Must be DCB_STATE_POLLING */
|
||||||
|
spinlock_release(&dcb->dcb_initlock);
|
||||||
if (0 == dcb->persistentstart && dcb_maybe_add_persistent(dcb))
|
if (0 == dcb->persistentstart && dcb_maybe_add_persistent(dcb))
|
||||||
{
|
{
|
||||||
/* Have taken DCB into persistent pool, no further killing */
|
/* Have taken DCB into persistent pool, no further killing */
|
||||||
@ -635,6 +638,7 @@ dcb_process_victim_queue(DCB *listofdcb)
|
|||||||
|
|
||||||
dcb->state = DCB_STATE_DISCONNECTED;
|
dcb->state = DCB_STATE_DISCONNECTED;
|
||||||
nextdcb = dcb->memdata.next;
|
nextdcb = dcb->memdata.next;
|
||||||
|
spinlock_release(&dcb->dcb_initlock);
|
||||||
dcb_final_free(dcb);
|
dcb_final_free(dcb);
|
||||||
dcb = nextdcb;
|
dcb = nextdcb;
|
||||||
}
|
}
|
||||||
@ -1831,7 +1835,10 @@ dcb_close(DCB *dcb)
|
|||||||
/*< Set bit for each maxscale thread. This should be done before
|
/*< Set bit for each maxscale thread. This should be done before
|
||||||
* the state is changed, so as to protect the DCB from premature
|
* the state is changed, so as to protect the DCB from premature
|
||||||
* destruction. */
|
* destruction. */
|
||||||
bitmask_copy(&dcb->memdata.bitmask, poll_bitmask());
|
if (dcb->server)
|
||||||
|
{
|
||||||
|
bitmask_copy(&dcb->memdata.bitmask, poll_bitmask());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
spinlock_release(&zombiespin);
|
spinlock_release(&zombiespin);
|
||||||
}
|
}
|
||||||
@ -2036,6 +2043,15 @@ dprintOneDCB(DCB *pdcb, DCB *dcb)
|
|||||||
dcb_printf(pdcb, "\tRole: %s\n", rolename);
|
dcb_printf(pdcb, "\tRole: %s\n", rolename);
|
||||||
free(rolename);
|
free(rolename);
|
||||||
}
|
}
|
||||||
|
if (!bitmask_isallclear(&dcb->memdata.bitmask))
|
||||||
|
{
|
||||||
|
char *bitmasktext = bitmask_render_readable(&dcb->memdata.bitmask);
|
||||||
|
if (bitmasktext)
|
||||||
|
{
|
||||||
|
dcb_printf(pdcb, "\tBitMask: %s\n", bitmasktext);
|
||||||
|
free(bitmasktext);
|
||||||
|
}
|
||||||
|
}
|
||||||
dcb_printf(pdcb, "\tStatistics:\n");
|
dcb_printf(pdcb, "\tStatistics:\n");
|
||||||
dcb_printf(pdcb, "\t\tNo. of Reads: %d\n", dcb->stats.n_reads);
|
dcb_printf(pdcb, "\t\tNo. of Reads: %d\n", dcb->stats.n_reads);
|
||||||
dcb_printf(pdcb, "\t\tNo. of Writes: %d\n", dcb->stats.n_writes);
|
dcb_printf(pdcb, "\t\tNo. of Writes: %d\n", dcb->stats.n_writes);
|
||||||
@ -2245,7 +2261,7 @@ gw_dcb_state2string (int state)
|
|||||||
case DCB_STATE_POLLING:
|
case DCB_STATE_POLLING:
|
||||||
return "DCB in the polling loop";
|
return "DCB in the polling loop";
|
||||||
case DCB_STATE_NOPOLLING:
|
case DCB_STATE_NOPOLLING:
|
||||||
return "DCB not in the polling loop";
|
return "DCB not in polling loop";
|
||||||
case DCB_STATE_LISTENING:
|
case DCB_STATE_LISTENING:
|
||||||
return "DCB for listening socket";
|
return "DCB for listening socket";
|
||||||
case DCB_STATE_DISCONNECTED:
|
case DCB_STATE_DISCONNECTED:
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <gwbitmask.h>
|
#include <gwbitmask.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,10 +48,14 @@
|
|||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 28/06/13 Mark Riddoch Initial implementation
|
* 28/06/13 Mark Riddoch Initial implementation
|
||||||
* 20/08/15 Martin Brampton Added caveats about limitations (above)
|
* 20/08/15 Martin Brampton Added caveats about limitations (above)
|
||||||
|
* 17/10/15 Martin Brampton Added display of bitmask
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int bitmask_isset_without_spinlock(GWBITMASK *bitmask, int bit);
|
||||||
|
static int bitmask_count_bits_set(GWBITMASK *bitmask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise a bitmask
|
* Initialise a bitmask
|
||||||
*
|
*
|
||||||
@ -151,19 +156,42 @@ unsigned char mask;
|
|||||||
* Return a non-zero value if the bit at the specified bit
|
* Return a non-zero value if the bit at the specified bit
|
||||||
* position in the bitmask is set.
|
* position in the bitmask is set.
|
||||||
* The bitmask will automatically be extended if the bit is
|
* The bitmask will automatically be extended if the bit is
|
||||||
* beyond the current bitmask length. This could be optimised
|
* beyond the current bitmask length. The work is done in the function
|
||||||
* by assuming that a bit beyond the length is unset.
|
* bitmask_isset_without_spinlock, which can be called when a spinlock
|
||||||
|
* has already been acquired.
|
||||||
*
|
*
|
||||||
* @param bitmask Pointer the bitmask
|
* @param bitmask Pointer the bitmask
|
||||||
* @param bit Bit to clear
|
* @param bit Bit to test
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
bitmask_isset(GWBITMASK *bitmask, int bit)
|
bitmask_isset(GWBITMASK *bitmask, int bit)
|
||||||
{
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
spinlock_acquire(&bitmask->lock);
|
||||||
|
result = bitmask_isset_without_spinlock(bitmask, bit);
|
||||||
|
spinlock_release(&bitmask->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a non-zero value if the bit at the specified bit
|
||||||
|
* position in the bitmask is set. Should be called while holding a
|
||||||
|
* lock on the bitmask.
|
||||||
|
*
|
||||||
|
* The bitmask will automatically be extended if the bit is
|
||||||
|
* beyond the current bitmask length. This could be optimised
|
||||||
|
* by assuming that a bit beyond the length is unset.
|
||||||
|
*
|
||||||
|
* @param bitmask Pointer the bitmask
|
||||||
|
* @param bit Bit to test
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
bitmask_isset_without_spinlock(GWBITMASK *bitmask, int bit)
|
||||||
|
{
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
||||||
spinlock_acquire(&bitmask->lock);
|
|
||||||
if (bit >= bitmask->length)
|
if (bit >= bitmask->length)
|
||||||
{
|
{
|
||||||
bitmask->bits = realloc(bitmask->bits,
|
bitmask->bits = realloc(bitmask->bits,
|
||||||
@ -174,7 +202,6 @@ unsigned char mask;
|
|||||||
}
|
}
|
||||||
ptr = bitmask->bits + (bit / 8);
|
ptr = bitmask->bits + (bit / 8);
|
||||||
mask = 1 << (bit % 8);
|
mask = 1 << (bit % 8);
|
||||||
spinlock_release(&bitmask->lock);
|
|
||||||
return *ptr & mask;
|
return *ptr & mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,3 +266,90 @@ bitmask_copy(GWBITMASK *dest, GWBITMASK *src)
|
|||||||
spinlock_release(&src->lock);
|
spinlock_release(&src->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a comma separated list of the numbers of the bits that are set in
|
||||||
|
* a bitmask, numbering starting at zero. Constrained to reject requests that
|
||||||
|
* could require more than three digit numbers. The returned string must be
|
||||||
|
* freed by the caller (unless it is null on account of memory allocation
|
||||||
|
* failure).
|
||||||
|
*
|
||||||
|
* @param bitmask Bitmap to make readable
|
||||||
|
* @return pointer to the newly allocated string, or null if no memory
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
bitmask_render_readable(GWBITMASK *bitmask)
|
||||||
|
{
|
||||||
|
char *toobig = "Bitmask is too large to render readable";
|
||||||
|
char *empty = "No bits are set";t
|
||||||
|
char onebit[5];
|
||||||
|
char *result;
|
||||||
|
int count_set = 0;
|
||||||
|
|
||||||
|
spinlock_acquire(&bitmask->lock);
|
||||||
|
if (999 < bitmask->length)
|
||||||
|
{
|
||||||
|
result = malloc(strlen(toobig));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
strcpy(result, toobig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count_set = bitmask_count_bits_set(bitmask);
|
||||||
|
if (count_set)
|
||||||
|
{
|
||||||
|
result = malloc(1 + (4 * count_set));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
result[0] = 0;
|
||||||
|
for (int i = 0; i<bitmask->length; i++)
|
||||||
|
{
|
||||||
|
if (bitmask_isset_without_spinlock(bitmask, i))
|
||||||
|
{
|
||||||
|
sprintf(onebit, "%d,", i);
|
||||||
|
strcat(result, onebit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[strlen(result)-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = malloc(strlen(empty));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
strcpy(result, empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_release(&bitmask->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a count of the number of bits set in a bitmask. Helpful for setting
|
||||||
|
* the size of string needed to show the set bits in readable form.
|
||||||
|
*
|
||||||
|
* @param bitmask Bitmap whose bits are to be counted
|
||||||
|
* @return int Number of set bits
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
bitmask_count_bits_set(GWBITMASK *bitmask)
|
||||||
|
{
|
||||||
|
const unsigned char oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
|
||||||
|
unsigned char partresults;
|
||||||
|
int result = 0;
|
||||||
|
unsigned char *ptr, *eptr;
|
||||||
|
|
||||||
|
ptr = bitmask->bits;
|
||||||
|
eptr = ptr + (bitmask->length / 8);
|
||||||
|
while (ptr < eptr)
|
||||||
|
{
|
||||||
|
partresults = oneBits[*ptr&0x0f];
|
||||||
|
partresults += oneBits[*ptr>>4];
|
||||||
|
result += partresults;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
@ -27,6 +27,7 @@
|
|||||||
*
|
*
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 28/06/13 Mark Riddoch Initial implementation
|
* 28/06/13 Mark Riddoch Initial implementation
|
||||||
|
* 17/10/15 Martin Brampton Add bitmask_render_readable
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -51,4 +52,6 @@ extern void bitmask_clear(GWBITMASK *, int);
|
|||||||
extern int bitmask_isset(GWBITMASK *, int);
|
extern int bitmask_isset(GWBITMASK *, int);
|
||||||
extern int bitmask_isallclear(GWBITMASK *);
|
extern int bitmask_isallclear(GWBITMASK *);
|
||||||
extern void bitmask_copy(GWBITMASK *, GWBITMASK *);
|
extern void bitmask_copy(GWBITMASK *, GWBITMASK *);
|
||||||
|
extern char *bitmask_render_readable(GWBITMASK *bitmask);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
*
|
*
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 19/06/13 Mark Riddoch Initial implementation
|
* 19/06/13 Mark Riddoch Initial implementation
|
||||||
|
* 17/10/15 Martin Brampton Declare fake event functions
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -60,9 +61,11 @@ extern void poll_set_maxwait(unsigned int);
|
|||||||
extern void poll_set_nonblocking_polls(unsigned int);
|
extern void poll_set_nonblocking_polls(unsigned int);
|
||||||
extern void dprintPollStats(DCB *);
|
extern void dprintPollStats(DCB *);
|
||||||
extern void dShowThreads(DCB *dcb);
|
extern void dShowThreads(DCB *dcb);
|
||||||
void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf);
|
void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf);
|
||||||
extern void dShowEventQ(DCB *dcb);
|
extern void dShowEventQ(DCB *dcb);
|
||||||
extern void dShowEventStats(DCB *dcb);
|
extern void dShowEventStats(DCB *dcb);
|
||||||
extern int poll_get_stat(POLL_STAT stat);
|
extern int poll_get_stat(POLL_STAT stat);
|
||||||
extern RESULTSET *eventTimesGetList();
|
extern RESULTSET *eventTimesGetList();
|
||||||
|
extern void poll_fake_hangup_event(DCB *dcb);
|
||||||
|
extern void poll_fake_write_event(DCB *dcb);
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
* 20/04/15 Guillaume Lefranc Added availableWhenDonor feature
|
* 20/04/15 Guillaume Lefranc Added availableWhenDonor feature
|
||||||
* 22/04/15 Martin Brampton Addition of disableMasterRoleSetting
|
* 22/04/15 Martin Brampton Addition of disableMasterRoleSetting
|
||||||
* 08/05/15 Markus Makela Addition of launchable scripts
|
* 08/05/15 Markus Makela Addition of launchable scripts
|
||||||
|
* 17/10/15 Martin Brampton Change DCB callback to hangup
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -541,13 +542,13 @@ monitor_event_t evtype;
|
|||||||
if (!(SERVER_IS_RUNNING(ptr->server)) ||
|
if (!(SERVER_IS_RUNNING(ptr->server)) ||
|
||||||
!(SERVER_IS_IN_CLUSTER(ptr->server)))
|
!(SERVER_IS_IN_CLUSTER(ptr->server)))
|
||||||
{
|
{
|
||||||
dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING);
|
dcb_hangup_foreach(ptr->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SERVER_IS_DOWN(ptr->server))
|
if (SERVER_IS_DOWN(ptr->server))
|
||||||
{
|
{
|
||||||
/** Increase this server'e error count */
|
/** Increase this server'e error count */
|
||||||
dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING);
|
dcb_hangup_foreach(ptr->server);
|
||||||
ptr->mon_err_count += 1;
|
ptr->mon_err_count += 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 08/09/14 Massimiliano Pinto Initial implementation
|
* 08/09/14 Massimiliano Pinto Initial implementation
|
||||||
* 08/05/15 Markus Makela Addition of launchable scripts
|
* 08/05/15 Markus Makela Addition of launchable scripts
|
||||||
|
* 17/10/15 Martin Brampton Change DCB callback to hangup
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -625,7 +626,7 @@ detect_stale_master = handle->detectStaleMaster;
|
|||||||
|
|
||||||
if (mon_status_changed(ptr))
|
if (mon_status_changed(ptr))
|
||||||
{
|
{
|
||||||
dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING);
|
dcb_hangup_foreach(ptr->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mon_status_changed(ptr) ||
|
if (mon_status_changed(ptr) ||
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
* 18/11/14 Massimiliano Pinto One server only in configuration becomes master.
|
* 18/11/14 Massimiliano Pinto One server only in configuration becomes master.
|
||||||
* servers=server1 must be present in mysql_mon and in router sections as well.
|
* servers=server1 must be present in mysql_mon and in router sections as well.
|
||||||
* 08/05/15 Markus Makela Added launchable scripts
|
* 08/05/15 Markus Makela Added launchable scripts
|
||||||
|
* 17/10/15 Martin Brampton Change DCB callback to hangup
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -861,8 +862,7 @@ detect_stale_master = handle->detectStaleMaster;
|
|||||||
if (!(SERVER_IS_RUNNING(ptr->server)) ||
|
if (!(SERVER_IS_RUNNING(ptr->server)) ||
|
||||||
!(SERVER_IS_IN_CLUSTER(ptr->server)))
|
!(SERVER_IS_IN_CLUSTER(ptr->server)))
|
||||||
{
|
{
|
||||||
dcb_call_foreach(ptr->server,DCB_REASON_NOT_RESPONDING);
|
dcb_hangup_foreach(ptr->server);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user