2009-09-03 20:20:39 +04:00
/*
ctdb banning code
Copyright ( C ) Ronnie Sahlberg 2009
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 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
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 , see < http : //www.gnu.org/licenses/>.
*/
2015-10-26 08:50:46 +03:00
# include "replace.h"
2009-09-03 20:20:39 +04:00
# include "system/time.h"
# include "system/network.h"
# include "system/filesys.h"
# include "system/wait.h"
2015-10-26 08:50:46 +03:00
# include <talloc.h>
# include <tevent.h>
# include "lib/util/debug.h"
# include "lib/util/samba_util.h"
# include "ctdb_private.h"
# include "ctdb_client.h"
2009-09-03 20:20:39 +04:00
2015-10-23 06:17:34 +03:00
# include "common/common.h"
2015-11-11 07:41:10 +03:00
# include "common/logging.h"
2009-09-03 20:20:39 +04:00
2015-10-26 08:50:09 +03:00
static void ctdb_ban_node_event ( struct tevent_context * ev ,
struct tevent_timer * te ,
struct timeval t , void * private_data )
2009-09-03 20:20:39 +04:00
{
struct ctdb_context * ctdb = talloc_get_type ( private_data , struct ctdb_context ) ;
2013-07-01 11:40:36 +04:00
/* Make sure we were able to freeze databases during banning */
2014-08-21 06:32:02 +04:00
if ( ! ctdb_db_all_frozen ( ctdb ) ) {
2016-06-01 02:16:23 +03:00
DEBUG ( DEBUG_ERR , ( " Banning timed out, but not all databases "
" frozen yet - banning this node again. \n " ) ) ;
2013-07-01 11:40:36 +04:00
ctdb_ban_self ( ctdb ) ;
return ;
}
2009-09-03 20:20:39 +04:00
2016-06-01 01:43:38 +03:00
DEBUG ( DEBUG_ERR , ( " Banning timed out \n " ) ) ;
2009-09-03 20:20:39 +04:00
ctdb - > nodes [ ctdb - > pnn ] - > flags & = ~ NODE_FLAGS_BANNED ;
if ( ctdb - > banning_ctx ! = NULL ) {
talloc_free ( ctdb - > banning_ctx ) ;
ctdb - > banning_ctx = NULL ;
}
}
2013-06-28 08:04:18 +04:00
void ctdb_local_node_got_banned ( struct ctdb_context * ctdb )
2010-08-31 11:28:34 +04:00
{
2015-09-11 07:20:44 +03:00
struct ctdb_db_context * ctdb_db ;
2016-06-01 01:53:54 +03:00
DEBUG ( DEBUG_NOTICE , ( " This node has been banned - releasing all public "
" IPs and setting the generation to INVALID. \n " ) ) ;
2010-08-31 11:28:34 +04:00
/* Reset the generation id to 1 to make us ignore any
REQ / REPLY CALL / DMASTER someone sends to us .
We are now banned so we shouldnt service database calls
anymore .
*/
ctdb - > vnn_map - > generation = INVALID_GENERATION ;
2015-09-11 07:20:44 +03:00
for ( ctdb_db = ctdb - > db_list ; ctdb_db ! = NULL ; ctdb_db = ctdb_db - > next ) {
ctdb_db - > generation = INVALID_GENERATION ;
}
2010-08-31 11:28:34 +04:00
2015-10-30 06:25:50 +03:00
/* Recovery daemon will set the recovery mode ACTIVE and freeze
* databases .
*/
2015-09-16 11:20:31 +03:00
2010-08-31 11:28:34 +04:00
ctdb_release_all_ips ( ctdb ) ;
}
2009-09-03 20:20:39 +04:00
int32_t ctdb_control_set_ban_state ( struct ctdb_context * ctdb , TDB_DATA indata )
{
2015-10-28 10:18:33 +03:00
struct ctdb_ban_state * bantime = ( struct ctdb_ban_state * ) indata . dptr ;
2015-07-27 09:51:08 +03:00
bool already_banned ;
2009-09-03 20:20:39 +04:00
DEBUG ( DEBUG_INFO , ( " SET BAN STATE \n " ) ) ;
if ( bantime - > pnn ! = ctdb - > pnn ) {
2015-07-29 12:34:23 +03:00
DEBUG ( DEBUG_WARNING ,
( " SET_BAN_STATE control for PNN %d ignored \n " ,
bantime - > pnn ) ) ;
return - 1 ;
2009-09-03 20:20:39 +04:00
}
2015-07-27 09:51:08 +03:00
already_banned = false ;
2009-09-03 20:20:39 +04:00
if ( ctdb - > banning_ctx ! = NULL ) {
talloc_free ( ctdb - > banning_ctx ) ;
ctdb - > banning_ctx = NULL ;
2015-07-27 09:51:08 +03:00
already_banned = true ;
2009-09-03 20:20:39 +04:00
}
if ( bantime - > time = = 0 ) {
DEBUG ( DEBUG_ERR , ( " Unbanning this node \n " ) ) ;
ctdb - > nodes [ bantime - > pnn ] - > flags & = ~ NODE_FLAGS_BANNED ;
return 0 ;
}
if ( ctdb - > tunable . enable_bans = = 0 ) {
DEBUG ( DEBUG_ERR , ( " Bans are disabled - ignoring ban of node %u \n " , bantime - > pnn ) ) ;
return 0 ;
}
2015-10-28 10:18:33 +03:00
ctdb - > banning_ctx = talloc ( ctdb , struct ctdb_ban_state ) ;
2009-09-03 20:20:39 +04:00
if ( ctdb - > banning_ctx = = NULL ) {
DEBUG ( DEBUG_CRIT , ( __location__ " ERROR Failed to allocate new banning state \n " ) ) ;
return - 1 ;
}
2015-10-28 10:18:33 +03:00
* ( ( struct ctdb_ban_state * ) ( ctdb - > banning_ctx ) ) = * bantime ;
2009-09-03 20:20:39 +04:00
DEBUG ( DEBUG_ERR , ( " Banning this node for %d seconds \n " , bantime - > time ) ) ;
ctdb - > nodes [ bantime - > pnn ] - > flags | = NODE_FLAGS_BANNED ;
2015-10-26 08:50:09 +03:00
tevent_add_timer ( ctdb - > ev , ctdb - > banning_ctx ,
timeval_current_ofs ( bantime - > time , 0 ) ,
ctdb_ban_node_event , ctdb ) ;
2010-08-31 11:28:34 +04:00
2015-07-27 09:51:08 +03:00
if ( ! already_banned ) {
ctdb_local_node_got_banned ( ctdb ) ;
}
2009-09-03 20:20:39 +04:00
return 0 ;
}
int32_t ctdb_control_get_ban_state ( struct ctdb_context * ctdb , TDB_DATA * outdata )
{
2015-10-28 10:18:33 +03:00
struct ctdb_ban_state * bantime ;
2009-09-03 20:20:39 +04:00
2015-10-28 10:18:33 +03:00
bantime = talloc ( outdata , struct ctdb_ban_state ) ;
2009-09-03 20:20:39 +04:00
CTDB_NO_MEMORY ( ctdb , bantime ) ;
if ( ctdb - > banning_ctx ! = NULL ) {
2015-10-28 10:18:33 +03:00
* bantime = * ( struct ctdb_ban_state * ) ( ctdb - > banning_ctx ) ;
2009-09-03 20:20:39 +04:00
} else {
bantime - > pnn = ctdb - > pnn ;
bantime - > time = 0 ;
}
outdata - > dptr = ( uint8_t * ) bantime ;
2015-10-28 10:18:33 +03:00
outdata - > dsize = sizeof ( struct ctdb_ban_state ) ;
2009-09-03 20:20:39 +04:00
return 0 ;
}
2009-12-07 15:48:40 +03:00
/* Routine to ban ourselves for a while when trouble strikes. */
void ctdb_ban_self ( struct ctdb_context * ctdb )
{
TDB_DATA data ;
2015-10-28 10:18:33 +03:00
struct ctdb_ban_state bantime ;
2009-12-07 15:48:40 +03:00
bantime . pnn = ctdb - > pnn ;
bantime . time = ctdb - > tunable . recovery_ban_period ;
data . dsize = sizeof ( bantime ) ;
data . dptr = ( uint8_t * ) & bantime ;
ctdb_control_set_ban_state ( ctdb , data ) ;
}