2007-05-18 14:06:29 +04:00
/*
monitoring links to all other nodes to detect dead nodes
Copyright ( C ) Ronnie Sahlberg 2007
2007-05-31 07:50:53 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
2007-05-18 14:06:29 +04:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2007-05-31 07:50:53 +04:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
2007-05-18 14:06:29 +04:00
*/
# include "includes.h"
# include "lib/events/events.h"
# include "system/filesys.h"
# include "system/wait.h"
# include "../include/ctdb_private.h"
/*
2007-05-18 17:23:36 +04:00
see if any nodes are dead
*/
2007-05-18 14:06:29 +04:00
static void ctdb_check_for_dead_nodes ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private_data )
{
struct ctdb_context * ctdb = talloc_get_type ( private_data , struct ctdb_context ) ;
int i ;
2007-06-06 04:25:46 +04:00
if ( ctdb - > monitoring_mode = = CTDB_MONITORING_DISABLED ) {
2007-05-21 03:24:34 +04:00
event_add_timed ( ctdb - > ev , ctdb ,
2007-06-06 04:25:46 +04:00
timeval_current_ofs ( ctdb - > tunable . keepalive_interval , 0 ) ,
2007-05-21 03:24:34 +04:00
ctdb_check_for_dead_nodes , ctdb ) ;
return ;
}
2007-05-18 14:06:29 +04:00
/* send a keepalive to all other nodes, unless */
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
2007-05-18 17:23:36 +04:00
struct ctdb_node * node = ctdb - > nodes [ i ] ;
if ( node - > vnn = = ctdb - > vnn ) {
2007-05-18 14:06:29 +04:00
continue ;
}
2007-05-18 17:23:36 +04:00
2007-06-02 04:03:28 +04:00
if ( ! ( node - > flags & NODE_FLAGS_CONNECTED ) ) {
/* it might have come alive again */
if ( node - > rx_cnt ! = 0 ) {
ctdb_node_connected ( node ) ;
}
2007-05-19 11:21:58 +04:00
continue ;
2007-05-18 14:06:29 +04:00
}
2007-06-02 04:03:28 +04:00
2007-05-18 17:23:36 +04:00
if ( node - > rx_cnt = = 0 ) {
node - > dead_count + + ;
2007-05-18 14:06:29 +04:00
} else {
2007-05-18 17:23:36 +04:00
node - > dead_count = 0 ;
2007-05-18 14:06:29 +04:00
}
2007-05-18 17:23:36 +04:00
node - > rx_cnt = 0 ;
2007-06-06 04:25:46 +04:00
if ( node - > dead_count > = ctdb - > tunable . keepalive_limit ) {
2007-06-02 04:03:28 +04:00
DEBUG ( 0 , ( " dead count reached for node %u \n " , node - > vnn ) ) ;
2007-05-19 10:59:10 +04:00
ctdb_node_dead ( node ) ;
2007-05-30 08:46:14 +04:00
ctdb_send_keepalive ( ctdb , node - > vnn ) ;
2007-05-18 17:23:36 +04:00
/* maybe tell the transport layer to kill the
sockets as well ?
2007-05-18 14:06:29 +04:00
*/
continue ;
}
2007-05-19 04:20:19 +04:00
2007-06-02 04:03:28 +04:00
if ( node - > tx_cnt = = 0 ) {
DEBUG ( 5 , ( " sending keepalive to %u \n " , node - > vnn ) ) ;
2007-05-19 04:20:19 +04:00
ctdb_send_keepalive ( ctdb , node - > vnn ) ;
}
2007-05-18 14:06:29 +04:00
2007-05-19 04:20:19 +04:00
node - > tx_cnt = 0 ;
2007-05-18 14:06:29 +04:00
}
event_add_timed ( ctdb - > ev , ctdb ,
2007-06-06 04:25:46 +04:00
timeval_current_ofs ( ctdb - > tunable . keepalive_interval , 0 ) ,
2007-05-18 14:06:29 +04:00
ctdb_check_for_dead_nodes , ctdb ) ;
}
2007-06-06 04:25:46 +04:00
static void ctdb_check_health ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private_data ) ;
/*
called when a health monitoring event script finishes
*/
static void ctdb_health_callback ( struct ctdb_context * ctdb , int status , void * p )
{
struct ctdb_node * node = ctdb - > nodes [ ctdb - > vnn ] ;
TDB_DATA data ;
struct ctdb_node_flag_change c ;
event_add_timed ( ctdb - > ev , ctdb ,
timeval_current_ofs ( ctdb - > tunable . monitor_interval , 0 ) ,
ctdb_check_health , ctdb ) ;
if ( status ! = 0 & & ! ( node - > flags & NODE_FLAGS_DISABLED ) ) {
DEBUG ( 0 , ( " monitor event failed - disabling node \n " ) ) ;
node - > flags | = NODE_FLAGS_DISABLED ;
} else if ( status = = 0 & & ( node - > flags & NODE_FLAGS_DISABLED ) ) {
DEBUG ( 0 , ( " monitor event OK - node re-enabled \n " ) ) ;
ctdb - > nodes [ ctdb - > vnn ] - > flags & = ~ NODE_FLAGS_DISABLED ;
} else {
/* no change */
return ;
}
c . vnn = ctdb - > vnn ;
c . flags = node - > flags ;
data . dptr = ( uint8_t * ) & c ;
data . dsize = sizeof ( c ) ;
/* tell the recmaster that something has changed */
2007-06-06 05:12:45 +04:00
ctdb_daemon_send_message ( ctdb , ctdb - > recovery_master , CTDB_SRVID_NODE_FLAGS_CHANGED , data ) ;
2007-06-06 04:25:46 +04:00
}
/*
see if the event scripts think we are healthy
*/
static void ctdb_check_health ( struct event_context * ev , struct timed_event * te ,
struct timeval t , void * private_data )
{
struct ctdb_context * ctdb = talloc_get_type ( private_data , struct ctdb_context ) ;
int ret ;
if ( ctdb - > monitoring_mode = = CTDB_MONITORING_DISABLED ) {
event_add_timed ( ctdb - > ev , ctdb ,
timeval_current_ofs ( ctdb - > tunable . monitor_interval , 0 ) ,
ctdb_check_health , ctdb ) ;
return ;
}
ret = ctdb_event_script_callback ( ctdb , ctdb , ctdb_health_callback , ctdb , " monitor " ) ;
if ( ret ! = 0 ) {
DEBUG ( 0 , ( " Unable to launch monitor event script \n " ) ) ;
event_add_timed ( ctdb - > ev , ctdb ,
timeval_current_ofs ( ctdb - > tunable . monitor_interval , 0 ) ,
ctdb_check_health , ctdb ) ;
}
}
2007-05-18 17:23:36 +04:00
/*
start watching for nodes that might be dead
*/
2007-05-18 14:06:29 +04:00
int ctdb_start_monitoring ( struct ctdb_context * ctdb )
{
event_add_timed ( ctdb - > ev , ctdb ,
2007-06-06 04:25:46 +04:00
timeval_current_ofs ( ctdb - > tunable . keepalive_interval , 0 ) ,
2007-05-18 14:06:29 +04:00
ctdb_check_for_dead_nodes , ctdb ) ;
2007-06-06 04:25:46 +04:00
event_add_timed ( ctdb - > ev , ctdb ,
timeval_current_ofs ( ctdb - > tunable . monitor_interval , 0 ) ,
ctdb_check_health , ctdb ) ;
2007-05-18 14:06:29 +04:00
return 0 ;
}