2007-04-26 16:27:49 +04:00
/*
ctdb_control protocol code
Copyright ( C ) Andrew Tridgell 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
2007-07-10 09:29:31 +04:00
the Free Software Foundation ; either version 3 of the License , or
2007-05-31 07:50:53 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
2007-04-26 16:27:49 +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
2007-07-10 09:29:31 +04:00
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-04-26 16:27:49 +04:00
*/
2015-10-26 08:50:46 +03:00
# include "replace.h"
2007-04-26 16:27:49 +04:00
# 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>
2014-08-15 09:46:33 +04:00
# include "lib/tdb_wrap/tdb_wrap.h"
2015-10-26 08:50:46 +03:00
# include "lib/util/dlinklist.h"
# include "lib/util/debug.h"
# include "lib/util/samba_util.h"
2015-08-16 14:19:15 +03:00
# include "lib/util/talloc_report.h"
2015-10-26 08:50:46 +03:00
# include "ctdb_private.h"
# include "ctdb_client.h"
2015-03-17 06:30:18 +03:00
# include "common/reqid.h"
2015-10-23 06:17:34 +03:00
# include "common/common.h"
2015-11-11 07:41:10 +03:00
# include "common/logging.h"
2007-04-26 16:27:49 +04:00
2007-08-24 09:53:41 +04:00
2007-04-26 16:27:49 +04:00
struct ctdb_control_state {
struct ctdb_context * ctdb ;
uint32_t reqid ;
ctdb_control_callback_fn_t callback ;
void * private_data ;
2007-05-17 08:10:38 +04:00
unsigned flags ;
2007-04-26 16:27:49 +04:00
} ;
2007-08-24 09:53:41 +04:00
2008-01-22 06:22:41 +03:00
/*
dump talloc memory hierarchy , returning it as a blob to the client
*/
2008-04-01 08:34:54 +04:00
int32_t ctdb_dump_memory ( struct ctdb_context * ctdb , TDB_DATA * outdata )
2008-01-22 06:22:41 +03:00
{
2015-08-16 14:19:15 +03:00
char * report ;
size_t reportlen ;
report = talloc_report_str ( outdata , NULL ) ;
if ( report = = NULL ) {
DEBUG ( DEBUG_ERR ,
( __location__ " talloc_report_str failed \n " ) ) ;
2013-11-11 05:39:27 +04:00
return - 1 ;
}
2015-08-16 14:19:15 +03:00
reportlen = talloc_get_size ( report ) ;
if ( reportlen > 0 ) {
reportlen - = 1 ; /* strip trailing zero */
2008-01-22 06:22:41 +03:00
}
2015-08-16 14:19:15 +03:00
outdata - > dptr = ( uint8_t * ) report ;
outdata - > dsize = reportlen ;
2008-01-22 06:22:41 +03:00
return 0 ;
}
2013-09-12 10:36:09 +04:00
static int32_t control_not_implemented ( const char * unsupported ,
const char * alternate )
{
if ( alternate = = NULL ) {
DEBUG ( DEBUG_ERR ,
( " Control %s is not implemented any more \n " ,
unsupported ) ) ;
} else {
DEBUG ( DEBUG_ERR ,
( " Control %s is not implemented any more, use %s instead \n " ,
unsupported , alternate ) ) ;
}
return - 1 ;
}
2008-01-22 06:22:41 +03:00
2007-04-26 16:27:49 +04:00
/*
process a control request
*/
static int32_t ctdb_control_dispatch ( struct ctdb_context * ctdb ,
2015-10-29 08:42:05 +03:00
struct ctdb_req_control_old * c ,
2007-05-04 05:41:29 +04:00
TDB_DATA indata ,
2007-05-12 09:15:27 +04:00
TDB_DATA * outdata , uint32_t srcnode ,
2007-05-12 15:25:26 +04:00
const char * * errormsg ,
2007-05-12 09:15:27 +04:00
bool * async_reply )
2007-04-26 16:27:49 +04:00
{
2007-05-12 09:15:27 +04:00
uint32_t opcode = c - > opcode ;
uint64_t srvid = c - > srvid ;
uint32_t client_id = c - > client_id ;
2007-04-26 16:27:49 +04:00
switch ( opcode ) {
case CTDB_CONTROL_PROCESS_EXISTS : {
2007-05-05 02:11:54 +04:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( pid_t ) ) ;
2009-12-02 05:58:27 +03:00
return ctdb_control_process_exists ( ctdb , * ( pid_t * ) indata . dptr ) ;
2007-04-26 16:27:49 +04:00
}
2007-04-26 21:27:07 +04:00
2007-04-27 17:14:36 +04:00
case CTDB_CONTROL_SET_DEBUG : {
2008-02-05 02:26:23 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( int32_t ) ) ;
2014-09-24 11:12:56 +04:00
DEBUGLEVEL = * ( int32_t * ) indata . dptr ;
2007-04-27 17:14:36 +04:00
return 0 ;
}
case CTDB_CONTROL_GET_DEBUG : {
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2014-09-24 11:12:56 +04:00
outdata - > dptr = ( uint8_t * ) & ( DEBUGLEVEL ) ;
outdata - > dsize = sizeof ( DEBUGLEVEL ) ;
2007-04-27 17:14:36 +04:00
return 0 ;
}
2007-05-29 06:16:59 +04:00
case CTDB_CONTROL_STATISTICS : {
2007-04-27 16:49:44 +04:00
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2008-01-16 01:44:48 +03:00
ctdb - > statistics . memory_used = talloc_total_size ( NULL ) ;
2013-04-19 07:29:04 +04:00
ctdb - > statistics . num_clients = ctdb - > num_clients ;
2014-08-21 06:32:02 +04:00
ctdb - > statistics . frozen = ( ctdb_db_all_frozen ( ctdb ) ? 1 : 0 ) ;
2007-05-29 06:16:59 +04:00
ctdb - > statistics . recovering = ( ctdb - > recovery_mode = = CTDB_RECOVERY_ACTIVE ) ;
2010-06-02 07:13:09 +04:00
ctdb - > statistics . statistics_current_time = timeval_current ( ) ;
2007-05-29 06:16:59 +04:00
outdata - > dptr = ( uint8_t * ) & ctdb - > statistics ;
outdata - > dsize = sizeof ( ctdb - > statistics ) ;
2007-04-26 16:51:41 +04:00
return 0 ;
}
2007-04-26 21:27:07 +04:00
2007-06-07 12:05:25 +04:00
case CTDB_CONTROL_GET_ALL_TUNABLES : {
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
outdata - > dptr = ( uint8_t * ) & ctdb - > tunable ;
outdata - > dsize = sizeof ( ctdb - > tunable ) ;
return 0 ;
}
2007-05-05 05:03:10 +04:00
case CTDB_CONTROL_DUMP_MEMORY : {
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2008-01-22 06:22:41 +03:00
return ctdb_dump_memory ( ctdb , outdata ) ;
2007-05-05 05:03:10 +04:00
}
2007-05-29 06:16:59 +04:00
case CTDB_CONTROL_STATISTICS_RESET : {
2015-04-02 05:53:09 +03:00
struct ctdb_db_context * ctdb_db ;
2007-04-28 21:13:36 +04:00
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2007-05-29 06:16:59 +04:00
ZERO_STRUCT ( ctdb - > statistics ) ;
2015-04-02 05:53:09 +03:00
for ( ctdb_db = ctdb - > db_list ;
ctdb_db ! = NULL ;
ctdb_db = ctdb_db - > next ) {
ctdb_db_statistics_reset ( ctdb_db ) ;
}
2010-06-02 07:13:09 +04:00
ctdb - > statistics . statistics_start_time = timeval_current ( ) ;
2007-04-28 21:13:36 +04:00
return 0 ;
}
2007-05-03 05:06:24 +04:00
case CTDB_CONTROL_GETVNNMAP :
return ctdb_control_getvnnmap ( ctdb , opcode , indata , outdata ) ;
2007-04-27 14:56:10 +04:00
2007-05-03 07:07:34 +04:00
case CTDB_CONTROL_GET_DBMAP :
return ctdb_control_getdbmap ( ctdb , opcode , indata , outdata ) ;
2007-04-28 14:00:50 +04:00
2008-10-14 03:40:29 +04:00
case CTDB_CONTROL_GET_NODEMAPv4 :
2015-03-23 09:06:31 +03:00
return control_not_implemented ( " GET_NODEMAPv4 " , " GET_NODEMAP " ) ;
2008-10-14 03:40:29 +04:00
2007-05-03 07:30:38 +04:00
case CTDB_CONTROL_GET_NODEMAP :
return ctdb_control_getnodemap ( ctdb , opcode , indata , outdata ) ;
2007-04-28 14:40:26 +04:00
2015-02-20 13:19:01 +03:00
case CTDB_CONTROL_GET_NODES_FILE :
return ctdb_control_getnodesfile ( ctdb , opcode , indata , outdata ) ;
2008-02-19 06:44:48 +03:00
case CTDB_CONTROL_RELOAD_NODES_FILE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_reload_nodes_file ( ctdb , opcode ) ;
2012-03-20 09:58:35 +04:00
case CTDB_CONTROL_SET_DB_STICKY : {
uint32_t db_id ;
struct ctdb_db_context * ctdb_db ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( db_id ) ) ;
db_id = * ( uint32_t * ) indata . dptr ;
ctdb_db = find_ctdb_db ( ctdb , db_id ) ;
if ( ctdb_db = = NULL ) return - 1 ;
return ctdb_set_db_sticky ( ctdb , ctdb_db ) ;
}
2007-05-03 05:06:24 +04:00
case CTDB_CONTROL_SETVNNMAP :
return ctdb_control_setvnnmap ( ctdb , opcode , indata , outdata ) ;
2007-04-27 16:08:12 +04:00
2007-05-10 11:43:45 +04:00
case CTDB_CONTROL_PULL_DB :
2015-10-28 11:10:53 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_pulldb ) ) ;
2007-05-10 11:43:45 +04:00
return ctdb_control_pull_db ( ctdb , indata , outdata ) ;
2007-04-28 23:47:13 +04:00
2007-05-10 11:43:45 +04:00
case CTDB_CONTROL_SET_DMASTER :
2013-09-12 10:36:09 +04:00
return control_not_implemented ( " SET_DMASTER " , NULL ) ;
2007-04-28 23:47:13 +04:00
2007-05-10 11:43:45 +04:00
case CTDB_CONTROL_PUSH_DB :
return ctdb_control_push_db ( ctdb , indata ) ;
2007-05-02 15:00:02 +04:00
2007-04-29 16:51:56 +04:00
case CTDB_CONTROL_GET_RECMODE : {
2014-05-06 08:07:00 +04:00
return ctdb - > recovery_mode ;
2007-04-29 16:51:56 +04:00
}
2007-05-06 23:02:48 +04:00
case CTDB_CONTROL_SET_RECMASTER : {
2008-10-22 04:04:41 +04:00
return ctdb_control_set_recmaster ( ctdb , opcode , indata ) ;
2007-05-06 23:02:48 +04:00
}
2007-05-15 04:17:16 +04:00
case CTDB_CONTROL_GET_RECMASTER :
2007-05-06 23:02:48 +04:00
return ctdb - > recovery_master ;
2007-05-15 04:17:16 +04:00
case CTDB_CONTROL_GET_PID :
2007-05-06 02:05:22 +04:00
return getpid ( ) ;
2007-05-15 04:17:16 +04:00
2007-09-04 04:38:48 +04:00
case CTDB_CONTROL_GET_PNN :
2007-09-04 04:06:36 +04:00
return ctdb - > pnn ;
2007-05-05 22:31:22 +04:00
2007-04-26 21:27:07 +04:00
case CTDB_CONTROL_PING :
2007-04-27 16:49:44 +04:00
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2013-04-19 07:29:04 +04:00
return ctdb - > num_clients ;
2007-04-26 21:27:07 +04:00
2013-05-21 10:18:28 +04:00
case CTDB_CONTROL_GET_RUNSTATE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
outdata - > dptr = ( uint8_t * ) & ctdb - > runstate ;
outdata - > dsize = sizeof ( uint32_t ) ;
return 0 ;
2011-09-01 05:08:18 +04:00
case CTDB_CONTROL_SET_DB_READONLY : {
uint32_t db_id ;
struct ctdb_db_context * ctdb_db ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( db_id ) ) ;
db_id = * ( uint32_t * ) indata . dptr ;
ctdb_db = find_ctdb_db ( ctdb , db_id ) ;
if ( ctdb_db = = NULL ) return - 1 ;
return ctdb_set_db_readonly ( ctdb , ctdb_db ) ;
}
2007-05-04 09:21:40 +04:00
case CTDB_CONTROL_GET_DBNAME : {
uint32_t db_id ;
struct ctdb_db_context * ctdb_db ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( db_id ) ) ;
db_id = * ( uint32_t * ) indata . dptr ;
ctdb_db = find_ctdb_db ( ctdb , db_id ) ;
if ( ctdb_db = = NULL ) return - 1 ;
outdata - > dptr = discard_const ( ctdb_db - > db_name ) ;
outdata - > dsize = strlen ( ctdb_db - > db_name ) + 1 ;
return 0 ;
}
2007-04-27 01:10:35 +04:00
case CTDB_CONTROL_GETDBPATH : {
uint32_t db_id ;
struct ctdb_db_context * ctdb_db ;
2007-04-27 17:14:36 +04:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( db_id ) ) ;
2007-04-27 01:10:35 +04:00
db_id = * ( uint32_t * ) indata . dptr ;
ctdb_db = find_ctdb_db ( ctdb , db_id ) ;
if ( ctdb_db = = NULL ) return - 1 ;
outdata - > dptr = discard_const ( ctdb_db - > db_path ) ;
2007-04-27 01:29:26 +04:00
outdata - > dsize = strlen ( ctdb_db - > db_path ) + 1 ;
2007-04-27 01:10:35 +04:00
return 0 ;
}
2007-04-30 17:31:40 +04:00
case CTDB_CONTROL_DB_ATTACH :
2011-02-23 07:46:36 +03:00
return ctdb_control_db_attach ( ctdb , indata , outdata , srvid , false , client_id , c , async_reply ) ;
2007-09-21 06:24:02 +04:00
case CTDB_CONTROL_DB_ATTACH_PERSISTENT :
2011-02-23 07:46:36 +03:00
return ctdb_control_db_attach ( ctdb , indata , outdata , srvid , true , client_id , c , async_reply ) ;
2007-04-30 17:31:40 +04:00
2015-07-09 15:33:23 +03:00
case CTDB_CONTROL_SET_CALL :
return control_not_implemented ( " SET_CALL " , NULL ) ;
2007-04-30 17:31:40 +04:00
2007-05-03 11:12:23 +04:00
case CTDB_CONTROL_TRAVERSE_START :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_traverse_start ) ) ;
2009-05-06 01:32:25 +04:00
return ctdb_control_traverse_start ( ctdb , indata , outdata , srcnode , client_id ) ;
2007-05-03 11:12:23 +04:00
2011-12-03 05:15:30 +04:00
case CTDB_CONTROL_TRAVERSE_START_EXT :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_traverse_start_ext ) ) ;
return ctdb_control_traverse_start_ext ( ctdb , indata , outdata , srcnode , client_id ) ;
2007-05-03 11:12:23 +04:00
case CTDB_CONTROL_TRAVERSE_ALL :
return ctdb_control_traverse_all ( ctdb , indata , outdata ) ;
2013-04-11 07:18:36 +04:00
case CTDB_CONTROL_TRAVERSE_ALL_EXT :
return ctdb_control_traverse_all_ext ( ctdb , indata , outdata ) ;
2007-05-03 11:12:23 +04:00
case CTDB_CONTROL_TRAVERSE_DATA :
return ctdb_control_traverse_data ( ctdb , indata , outdata ) ;
2009-05-06 01:32:25 +04:00
case CTDB_CONTROL_TRAVERSE_KILL :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_traverse_start ) ) ;
return ctdb_control_traverse_kill ( ctdb , indata , outdata , srcnode ) ;
2007-05-04 05:41:29 +04:00
case CTDB_CONTROL_REGISTER_SRVID :
return daemon_register_message_handler ( ctdb , client_id , srvid ) ;
case CTDB_CONTROL_DEREGISTER_SRVID :
return daemon_deregister_message_handler ( ctdb , client_id , srvid ) ;
2011-10-31 16:29:13 +04:00
case CTDB_CONTROL_CHECK_SRVIDS :
return daemon_check_srvids ( ctdb , indata , outdata ) ;
2007-05-04 16:18:00 +04:00
case CTDB_CONTROL_ENABLE_SEQNUM :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_ltdb_enable_seqnum ( ctdb , * ( uint32_t * ) indata . dptr ) ;
case CTDB_CONTROL_UPDATE_SEQNUM :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_ltdb_update_seqnum ( ctdb , * ( uint32_t * ) indata . dptr , srcnode ) ;
2007-05-12 09:15:27 +04:00
case CTDB_CONTROL_FREEZE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_freeze ( ctdb , c , async_reply ) ;
case CTDB_CONTROL_THAW :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2014-05-06 08:20:44 +04:00
return ctdb_control_thaw ( ctdb , ( uint32_t ) c - > srvid , true ) ;
2007-05-12 09:15:27 +04:00
case CTDB_CONTROL_SET_RECMODE :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
2007-06-02 02:41:19 +04:00
return ctdb_control_set_recmode ( ctdb , c , indata , async_reply , errormsg ) ;
2007-05-12 09:15:27 +04:00
2007-05-21 03:24:34 +04:00
case CTDB_CONTROL_GET_MONMODE :
2008-03-25 00:27:38 +03:00
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2008-01-10 06:40:56 +03:00
return ctdb_monitoring_mode ( ctdb ) ;
2008-03-25 00:27:38 +03:00
case CTDB_CONTROL_ENABLE_MONITOR :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
ctdb_enable_monitoring ( ctdb ) ;
return 0 ;
2008-04-02 04:13:30 +04:00
case CTDB_CONTROL_RUN_EVENTSCRIPTS :
return ctdb_run_eventscripts ( ctdb , c , indata , async_reply ) ;
2008-03-25 00:27:38 +03:00
case CTDB_CONTROL_DISABLE_MONITOR :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
ctdb_disable_monitoring ( ctdb ) ;
return 0 ;
2007-05-21 03:24:34 +04:00
2007-05-17 04:45:31 +04:00
case CTDB_CONTROL_SHUTDOWN :
2013-06-19 04:58:14 +04:00
DEBUG ( DEBUG_NOTICE , ( " Received SHUTDOWN command. \n " ) ) ;
ctdb_shutdown_sequence ( ctdb , 0 ) ;
2013-06-22 09:44:28 +04:00
/* In case above returns due to duplicate shutdown */
return 0 ;
2007-05-17 04:45:31 +04:00
2008-10-14 03:40:29 +04:00
case CTDB_CONTROL_TAKEOVER_IPv4 :
2015-03-23 09:06:31 +03:00
return control_not_implemented ( " TAKEOVER_IPv4 " , " TAKEOVER_IP " ) ;
2008-10-14 03:40:29 +04:00
2007-05-25 07:05:25 +04:00
case CTDB_CONTROL_TAKEOVER_IP :
2007-06-04 14:07:37 +04:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_public_ip ) ) ;
2007-06-01 13:05:41 +04:00
return ctdb_control_takeover_ip ( ctdb , c , indata , async_reply ) ;
2007-05-25 07:05:25 +04:00
2008-10-14 03:40:29 +04:00
case CTDB_CONTROL_RELEASE_IPv4 :
2015-03-23 09:06:31 +03:00
return control_not_implemented ( " RELEASE_IPv4 " , " RELEASE_IP " ) ;
2008-10-14 03:40:29 +04:00
2007-05-25 07:05:25 +04:00
case CTDB_CONTROL_RELEASE_IP :
2007-06-04 14:07:37 +04:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_public_ip ) ) ;
2007-06-01 13:05:41 +04:00
return ctdb_control_release_ip ( ctdb , c , indata , async_reply ) ;
2007-05-25 07:05:25 +04:00
2013-04-19 07:05:02 +04:00
case CTDB_CONTROL_IPREALLOCATED :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_ipreallocated ( ctdb , c , async_reply ) ;
2008-10-14 03:40:29 +04:00
case CTDB_CONTROL_GET_PUBLIC_IPSv4 :
2015-03-23 09:06:31 +03:00
return control_not_implemented ( " GET_PUBLIC_IPSv4 " ,
" GET_PUBLIC_IPS " ) ;
2008-10-14 03:40:29 +04:00
2007-06-04 15:11:51 +04:00
case CTDB_CONTROL_GET_PUBLIC_IPS :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_get_public_ips ( ctdb , c , outdata ) ;
2015-03-23 09:32:34 +03:00
case CTDB_CONTROL_TCP_CLIENT :
2015-10-29 06:25:34 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_connection ) ) ;
2007-07-20 04:06:41 +04:00
return ctdb_control_tcp_client ( ctdb , client_id , indata ) ;
2007-05-27 18:34:40 +04:00
case CTDB_CONTROL_STARTUP :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_startup ( ctdb , srcnode ) ;
2007-05-27 09:26:29 +04:00
case CTDB_CONTROL_TCP_ADD :
2015-10-28 10:14:21 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_connection ) ) ;
2010-08-18 06:36:03 +04:00
return ctdb_control_tcp_add ( ctdb , indata , false ) ;
case CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE :
2015-10-28 10:14:21 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_connection ) ) ;
2010-08-18 06:36:03 +04:00
return ctdb_control_tcp_add ( ctdb , indata , true ) ;
case CTDB_CONTROL_TCP_REMOVE :
2015-10-28 10:14:21 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_connection ) ) ;
2010-08-18 06:36:03 +04:00
return ctdb_control_tcp_remove ( ctdb , indata ) ;
2007-05-27 09:26:29 +04:00
2007-06-04 13:53:19 +04:00
case CTDB_CONTROL_SET_TUNABLE :
return ctdb_control_set_tunable ( ctdb , indata ) ;
case CTDB_CONTROL_GET_TUNABLE :
return ctdb_control_get_tunable ( ctdb , indata , outdata ) ;
case CTDB_CONTROL_LIST_TUNABLES :
return ctdb_control_list_tunables ( ctdb , outdata ) ;
2007-06-07 09:18:55 +04:00
case CTDB_CONTROL_MODIFY_FLAGS :
2008-11-19 06:43:46 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_node_flag_change ) ) ;
2007-06-07 09:18:55 +04:00
return ctdb_control_modflags ( ctdb , indata ) ;
2007-06-07 03:16:17 +04:00
2016-03-11 07:57:44 +03:00
case CTDB_CONTROL_KILL_TCP :
return control_not_implemented ( " KILL_TCP " , NULL ) ;
2007-07-11 12:24:25 +04:00
2007-07-20 09:05:55 +04:00
case CTDB_CONTROL_GET_TCP_TICKLE_LIST :
2008-08-19 08:58:29 +04:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( ctdb_sock_addr ) ) ;
2007-07-20 09:05:55 +04:00
return ctdb_control_get_tcp_tickle_list ( ctdb , indata , outdata ) ;
case CTDB_CONTROL_SET_TCP_TICKLE_LIST :
2007-07-20 04:06:41 +04:00
/* data size is verified in the called function */
2007-07-20 09:05:55 +04:00
return ctdb_control_set_tcp_tickle_list ( ctdb , indata ) ;
2007-07-20 04:06:41 +04:00
2007-08-24 09:53:41 +04:00
case CTDB_CONTROL_REGISTER_SERVER_ID :
2015-10-28 09:47:03 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_client_id ) ) ;
2007-08-24 09:53:41 +04:00
return ctdb_control_register_server_id ( ctdb , client_id , indata ) ;
case CTDB_CONTROL_UNREGISTER_SERVER_ID :
2015-10-28 09:47:03 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_client_id ) ) ;
2007-08-24 09:53:41 +04:00
return ctdb_control_unregister_server_id ( ctdb , indata ) ;
case CTDB_CONTROL_CHECK_SERVER_ID :
2015-10-28 09:47:03 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_client_id ) ) ;
2007-08-24 09:53:41 +04:00
return ctdb_control_check_server_id ( ctdb , indata ) ;
2007-08-26 04:57:02 +04:00
case CTDB_CONTROL_GET_SERVER_ID_LIST :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_get_server_id_list ( ctdb , outdata ) ;
2007-09-21 06:24:02 +04:00
case CTDB_CONTROL_PERSISTENT_STORE :
2013-09-12 10:27:39 +04:00
return control_not_implemented ( " PERSISTENT_STORE " , NULL ) ;
2007-09-21 06:24:02 +04:00
case CTDB_CONTROL_UPDATE_RECORD :
return ctdb_control_update_record ( ctdb , c , indata , async_reply ) ;
2015-10-29 09:51:52 +03:00
case CTDB_CONTROL_SEND_GRATUITOUS_ARP :
2007-10-09 05:56:09 +04:00
return ctdb_control_send_gratious_arp ( ctdb , indata ) ;
2008-01-06 04:38:01 +03:00
case CTDB_CONTROL_TRANSACTION_START :
2008-01-06 05:24:55 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_transaction_start ( ctdb , * ( uint32_t * ) indata . dptr ) ;
2008-01-06 04:38:01 +03:00
case CTDB_CONTROL_TRANSACTION_COMMIT :
2008-01-06 05:24:55 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_transaction_commit ( ctdb , * ( uint32_t * ) indata . dptr ) ;
2008-01-06 04:38:01 +03:00
case CTDB_CONTROL_WIPE_DATABASE :
2015-10-28 11:22:23 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_transdb ) ) ;
2008-01-06 04:38:01 +03:00
return ctdb_control_wipe_database ( ctdb , indata ) ;
2008-01-17 03:33:23 +03:00
case CTDB_CONTROL_UPTIME :
return ctdb_control_uptime ( ctdb , outdata ) ;
2008-01-29 05:59:28 +03:00
case CTDB_CONTROL_START_RECOVERY :
return ctdb_control_start_recovery ( ctdb , c , async_reply ) ;
case CTDB_CONTROL_END_RECOVERY :
return ctdb_control_end_recovery ( ctdb , c , async_reply ) ;
2008-02-29 02:03:39 +03:00
2008-03-12 23:53:29 +03:00
case CTDB_CONTROL_TRY_DELETE_RECORDS :
return ctdb_control_try_delete_records ( ctdb , indata , outdata ) ;
2008-03-27 01:23:27 +03:00
case CTDB_CONTROL_ADD_PUBLIC_IP :
return ctdb_control_add_public_address ( ctdb , indata ) ;
case CTDB_CONTROL_DEL_PUBLIC_IP :
2014-01-22 06:30:47 +04:00
return ctdb_control_del_public_address ( ctdb , c , indata ,
async_reply ) ;
2008-03-27 01:23:27 +03:00
2008-05-06 04:02:27 +04:00
case CTDB_CONTROL_GET_CAPABILITIES :
2008-05-06 09:42:59 +04:00
return ctdb_control_get_capabilities ( ctdb , outdata ) ;
2008-05-06 04:02:27 +04:00
2008-07-17 07:50:55 +04:00
case CTDB_CONTROL_START_PERSISTENT_UPDATE :
return ctdb_control_start_persistent_update ( ctdb , c , indata ) ;
case CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE :
return ctdb_control_cancel_persistent_update ( ctdb , c , indata ) ;
2008-07-30 13:57:00 +04:00
case CTDB_CONTROL_TRANS2_COMMIT :
2008-08-08 07:11:28 +04:00
case CTDB_CONTROL_TRANS2_COMMIT_RETRY :
2013-09-12 10:27:39 +04:00
return control_not_implemented ( " TRANS2_COMMIT " , " TRANS3_COMMIT " ) ;
2008-07-30 13:57:00 +04:00
case CTDB_CONTROL_TRANS2_ERROR :
2013-09-12 10:27:39 +04:00
return control_not_implemented ( " TRANS2_ERROR " , NULL ) ;
2008-07-30 13:57:00 +04:00
case CTDB_CONTROL_TRANS2_FINISHED :
2013-09-12 10:27:39 +04:00
return control_not_implemented ( " TRANS2_FINISHED " , NULL ) ;
2008-07-30 13:57:00 +04:00
2009-10-29 02:49:00 +03:00
case CTDB_CONTROL_TRANS2_ACTIVE :
2013-09-12 10:27:39 +04:00
return control_not_implemented ( " TRANS2_ACTIVE " , NULL ) ;
2009-10-29 02:49:00 +03:00
2009-12-03 19:59:49 +03:00
case CTDB_CONTROL_TRANS3_COMMIT :
return ctdb_control_trans3_commit ( ctdb , c , indata , async_reply ) ;
2008-09-09 07:44:46 +04:00
case CTDB_CONTROL_RECD_PING :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_recd_ping ( ctdb ) ;
2009-03-23 11:07:45 +03:00
case CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS :
2009-12-07 18:20:55 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_get_event_script_status ( ctdb , * ( uint32_t * ) indata . dptr , outdata ) ;
2009-03-23 11:07:45 +03:00
2009-05-14 04:33:25 +04:00
case CTDB_CONTROL_RECD_RECLOCK_LATENCY :
CHECK_CONTROL_DATA_SIZE ( sizeof ( double ) ) ;
2010-09-29 04:38:41 +04:00
CTDB_UPDATE_RECLOCK_LATENCY ( ctdb , " recd reclock " , reclock . recd , * ( ( double * ) indata . dptr ) ) ;
2009-05-14 04:33:25 +04:00
return 0 ;
2009-06-25 06:17:19 +04:00
case CTDB_CONTROL_GET_RECLOCK_FILE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
if ( ctdb - > recovery_lock_file ! = NULL ) {
outdata - > dptr = discard_const ( ctdb - > recovery_lock_file ) ;
outdata - > dsize = strlen ( ctdb - > recovery_lock_file ) + 1 ;
}
return 0 ;
2014-12-09 05:40:23 +03:00
case CTDB_CONTROL_SET_RECLOCK_FILE : {
char * t ;
if ( indata . dsize = = 0 ) {
TALLOC_FREE ( ctdb - > recovery_lock_file ) ;
return 0 ;
}
/* Return silent success if unchanged. Recovery
* master updates all nodes on each recovery - we
* don ' t need the extra memory allocation or log
* message each time . */
2015-01-28 10:51:42 +03:00
if ( ctdb - > recovery_lock_file ! = NULL & &
strcmp ( discard_const ( indata . dptr ) ,
2014-12-09 05:40:23 +03:00
ctdb - > recovery_lock_file ) = = 0 ) {
return 0 ;
2009-06-25 08:25:18 +04:00
}
2014-12-09 05:40:23 +03:00
t = talloc_strdup ( ctdb , discard_const ( indata . dptr ) ) ;
if ( t = = NULL ) {
DEBUG ( DEBUG_ERR , ( " Out of memory in SET_RECLOCK_FILE \n " ) ) ;
return - 1 ;
2009-06-25 08:25:18 +04:00
}
2014-12-09 05:40:23 +03:00
talloc_free ( ctdb - > recovery_lock_file ) ;
ctdb - > recovery_lock_file = t ;
DEBUG ( DEBUG_NOTICE , ( " Updated recovery lock file to %s \n " , t ) ) ;
2009-06-25 08:25:18 +04:00
return 0 ;
2014-12-09 05:40:23 +03:00
}
2009-10-12 11:31:59 +04:00
2009-07-09 06:22:46 +04:00
case CTDB_CONTROL_STOP_NODE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2013-02-21 07:28:13 +04:00
return ctdb_control_stop_node ( ctdb ) ;
2009-07-09 06:22:46 +04:00
case CTDB_CONTROL_CONTINUE_NODE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_continue_node ( ctdb ) ;
2016-01-05 08:02:09 +03:00
case CTDB_CONTROL_SET_NATGWSTATE :
return control_not_implemented ( " SET_NATGWSTATE " , NULL ) ;
2009-07-28 03:58:11 +04:00
2009-07-28 07:45:13 +04:00
case CTDB_CONTROL_SET_LMASTERROLE : {
uint32_t lmasterrole ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
lmasterrole = * ( uint32_t * ) indata . dptr ;
if ( lmasterrole = = 0 ) {
ctdb - > capabilities & = ~ CTDB_CAP_LMASTER ;
} else {
ctdb - > capabilities | = CTDB_CAP_LMASTER ;
}
return 0 ;
}
case CTDB_CONTROL_SET_RECMASTERROLE : {
uint32_t recmasterrole ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
recmasterrole = * ( uint32_t * ) indata . dptr ;
if ( recmasterrole = = 0 ) {
ctdb - > capabilities & = ~ CTDB_CAP_RECMASTER ;
} else {
ctdb - > capabilities | = CTDB_CAP_RECMASTER ;
}
return 0 ;
}
2009-08-13 07:04:08 +04:00
case CTDB_CONTROL_ENABLE_SCRIPT :
return ctdb_control_enable_script ( ctdb , indata ) ;
case CTDB_CONTROL_DISABLE_SCRIPT :
return ctdb_control_disable_script ( ctdb , indata ) ;
2009-09-03 20:20:39 +04:00
case CTDB_CONTROL_SET_BAN_STATE :
2015-10-28 10:18:33 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_ban_state ) ) ;
2009-09-03 20:20:39 +04:00
return ctdb_control_set_ban_state ( ctdb , indata ) ;
case CTDB_CONTROL_GET_BAN_STATE :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_get_ban_state ( ctdb , outdata ) ;
2009-10-10 07:26:09 +04:00
case CTDB_CONTROL_SET_DB_PRIORITY :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_db_priority ) ) ;
2014-04-02 10:17:47 +04:00
return ctdb_control_set_db_priority ( ctdb , indata , client_id ) ;
2009-10-10 07:26:09 +04:00
2009-10-10 08:04:18 +04:00
case CTDB_CONTROL_GET_DB_PRIORITY : {
uint32_t db_id ;
struct ctdb_db_context * ctdb_db ;
CHECK_CONTROL_DATA_SIZE ( sizeof ( db_id ) ) ;
db_id = * ( uint32_t * ) indata . dptr ;
ctdb_db = find_ctdb_db ( ctdb , db_id ) ;
if ( ctdb_db = = NULL ) return - 1 ;
return ctdb_db - > priority ;
}
2009-10-12 11:31:59 +04:00
case CTDB_CONTROL_TRANSACTION_CANCEL :
2009-10-12 11:41:57 +04:00
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
2009-10-12 11:31:59 +04:00
return ctdb_control_transaction_cancel ( ctdb ) ;
2009-10-23 08:24:51 +04:00
case CTDB_CONTROL_REGISTER_NOTIFY :
return ctdb_control_register_notify ( ctdb , client_id , indata ) ;
case CTDB_CONTROL_DEREGISTER_NOTIFY :
2015-10-28 09:47:03 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint64_t ) ) ;
2009-10-23 08:24:51 +04:00
return ctdb_control_deregister_notify ( ctdb , client_id , indata ) ;
2009-11-18 04:44:18 +03:00
case CTDB_CONTROL_GET_LOG :
2014-08-08 06:51:03 +04:00
return control_not_implemented ( " GET_LOG " , NULL ) ;
2009-11-18 04:44:18 +03:00
case CTDB_CONTROL_CLEAR_LOG :
2014-08-08 06:51:03 +04:00
return control_not_implemented ( " CLEAR_LOG " , NULL ) ;
2009-11-18 04:44:18 +03:00
2009-12-11 17:31:02 +03:00
case CTDB_CONTROL_GET_DB_SEQNUM :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint64_t ) ) ;
return ctdb_control_get_db_seqnum ( ctdb , indata , outdata ) ;
2009-12-02 14:48:22 +03:00
case CTDB_CONTROL_DB_SET_HEALTHY :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_set_healthy ( ctdb , indata ) ;
case CTDB_CONTROL_DB_GET_HEALTH :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_get_health ( ctdb , indata , outdata ) ;
2009-12-16 16:40:21 +03:00
case CTDB_CONTROL_GET_PUBLIC_IP_INFO :
CHECK_CONTROL_DATA_SIZE ( sizeof ( ctdb_sock_addr ) ) ;
return ctdb_control_get_public_ip_info ( ctdb , c , indata , outdata ) ;
case CTDB_CONTROL_GET_IFACES :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_get_ifaces ( ctdb , c , outdata ) ;
case CTDB_CONTROL_SET_IFACE_LINK_STATE :
2015-10-28 11:37:17 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_iface ) ) ;
2009-12-16 16:40:21 +03:00
return ctdb_control_set_iface_link ( ctdb , c , indata ) ;
2010-09-29 06:13:05 +04:00
case CTDB_CONTROL_GET_STAT_HISTORY :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_get_stat_history ( ctdb , c , outdata ) ;
2010-12-21 16:25:48 +03:00
case CTDB_CONTROL_SCHEDULE_FOR_DELETION : {
struct ctdb_control_schedule_for_deletion * d ;
size_t size = offsetof ( struct ctdb_control_schedule_for_deletion , key ) ;
CHECK_CONTROL_MIN_DATA_SIZE ( size ) ;
d = ( struct ctdb_control_schedule_for_deletion * ) indata . dptr ;
size + = d - > keylen ;
CHECK_CONTROL_DATA_SIZE ( size ) ;
return ctdb_control_schedule_for_deletion ( ctdb , indata ) ;
}
2013-07-15 08:52:07 +04:00
case CTDB_CONTROL_GET_DB_STATISTICS :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_get_db_statistics ( ctdb , * ( uint32_t * ) indata . dptr , outdata ) ;
2012-02-08 08:29:27 +04:00
2012-04-30 09:50:44 +04:00
case CTDB_CONTROL_RELOAD_PUBLIC_IPS :
CHECK_CONTROL_DATA_SIZE ( 0 ) ;
return ctdb_control_reload_public_ips ( ctdb , c , async_reply ) ;
2012-12-21 03:24:47 +04:00
case CTDB_CONTROL_RECEIVE_RECORDS :
return ctdb_control_receive_records ( ctdb , indata , outdata ) ;
2014-03-31 08:44:21 +04:00
case CTDB_CONTROL_DB_DETACH :
return ctdb_control_db_detach ( ctdb , indata , client_id ) ;
2014-08-05 08:16:29 +04:00
case CTDB_CONTROL_DB_FREEZE :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_freeze ( ctdb , c , * ( uint32_t * ) indata . dptr ,
async_reply ) ;
case CTDB_CONTROL_DB_THAW :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_thaw ( ctdb , * ( uint32_t * ) indata . dptr ) ;
2015-09-09 08:38:36 +03:00
case CTDB_CONTROL_DB_TRANSACTION_START :
2015-10-28 11:22:23 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_transdb ) ) ;
2015-09-09 08:38:36 +03:00
return ctdb_control_db_transaction_start ( ctdb , indata ) ;
case CTDB_CONTROL_DB_TRANSACTION_COMMIT :
2015-10-28 11:22:23 +03:00
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_transdb ) ) ;
2015-09-09 08:38:36 +03:00
return ctdb_control_db_transaction_commit ( ctdb , indata ) ;
case CTDB_CONTROL_DB_TRANSACTION_CANCEL :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_transaction_cancel ( ctdb , indata ) ;
2016-02-19 09:32:09 +03:00
case CTDB_CONTROL_DB_PULL :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_pulldb_ext ) ) ;
return ctdb_control_db_pull ( ctdb , c , indata , outdata ) ;
case CTDB_CONTROL_DB_PUSH_START :
CHECK_CONTROL_DATA_SIZE ( sizeof ( struct ctdb_pulldb_ext ) ) ;
return ctdb_control_db_push_start ( ctdb , indata ) ;
case CTDB_CONTROL_DB_PUSH_CONFIRM :
CHECK_CONTROL_DATA_SIZE ( sizeof ( uint32_t ) ) ;
return ctdb_control_db_push_confirm ( ctdb , indata , outdata ) ;
2007-04-26 16:27:49 +04:00
default :
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( __location__ " Unknown CTDB control opcode %u \n " , opcode ) ) ;
2007-04-26 16:27:49 +04:00
return - 1 ;
}
}
/*
2007-05-12 08:34:21 +04:00
send a reply for a ctdb control
*/
2015-10-29 08:42:05 +03:00
void ctdb_request_control_reply ( struct ctdb_context * ctdb , struct ctdb_req_control_old * c ,
2007-05-12 15:25:26 +04:00
TDB_DATA * outdata , int32_t status , const char * errormsg )
2007-04-26 16:27:49 +04:00
{
2015-10-29 08:44:08 +03:00
struct ctdb_reply_control_old * r ;
2007-04-26 16:27:49 +04:00
size_t len ;
2007-05-12 15:25:26 +04:00
2007-04-30 17:31:40 +04:00
/* some controls send no reply */
if ( c - > flags & CTDB_CTRL_FLAG_NOREPLY ) {
return ;
}
2015-10-29 08:44:08 +03:00
len = offsetof ( struct ctdb_reply_control_old , data ) + ( outdata ? outdata - > dsize : 0 ) ;
2007-05-12 15:25:26 +04:00
if ( errormsg ) {
len + = strlen ( errormsg ) ;
}
2015-10-29 08:44:08 +03:00
r = ctdb_transport_allocate ( ctdb , ctdb , CTDB_REPLY_CONTROL , len , struct ctdb_reply_control_old ) ;
2011-11-16 08:25:14 +04:00
if ( r = = NULL ) {
DEBUG ( DEBUG_ERR , ( __location__ " Unable to allocate transport - OOM or transport is down \n " ) ) ;
return ;
}
2007-04-26 16:27:49 +04:00
2007-05-12 08:34:21 +04:00
r - > hdr . destnode = c - > hdr . srcnode ;
r - > hdr . reqid = c - > hdr . reqid ;
2007-04-26 16:27:49 +04:00
r - > status = status ;
2007-05-12 08:34:21 +04:00
r - > datalen = outdata ? outdata - > dsize : 0 ;
if ( outdata & & outdata - > dsize ) {
2007-04-27 14:56:10 +04:00
memcpy ( & r - > data [ 0 ] , outdata - > dptr , outdata - > dsize ) ;
2007-04-26 16:27:49 +04:00
}
2007-05-12 15:25:26 +04:00
if ( errormsg ) {
r - > errorlen = strlen ( errormsg ) ;
memcpy ( & r - > data [ r - > datalen ] , errormsg , r - > errorlen ) ;
}
2008-07-04 12:00:24 +04:00
ctdb_queue_packet_opcode ( ctdb , & r - > hdr , c - > opcode ) ;
2007-04-26 16:27:49 +04:00
talloc_free ( r ) ;
}
2007-05-12 08:34:21 +04:00
/*
called when a CTDB_REQ_CONTROL packet comes in
*/
void ctdb_request_control ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr )
{
2015-10-29 08:42:05 +03:00
struct ctdb_req_control_old * c = ( struct ctdb_req_control_old * ) hdr ;
2007-05-12 08:34:21 +04:00
TDB_DATA data , * outdata ;
int32_t status ;
2012-05-17 10:08:37 +04:00
bool async_reply = false ;
2007-05-12 15:25:26 +04:00
const char * errormsg = NULL ;
2007-05-12 08:34:21 +04:00
data . dptr = & c - > data [ 0 ] ;
data . dsize = c - > datalen ;
outdata = talloc_zero ( c , TDB_DATA ) ;
2007-05-12 15:25:26 +04:00
status = ctdb_control_dispatch ( ctdb , c , data , outdata , hdr - > srcnode ,
& errormsg , & async_reply ) ;
2007-05-12 08:34:21 +04:00
2007-05-12 09:15:27 +04:00
if ( ! async_reply ) {
2007-05-12 15:25:26 +04:00
ctdb_request_control_reply ( ctdb , c , outdata , status , errormsg ) ;
2007-05-12 09:15:27 +04:00
}
2007-05-12 08:34:21 +04:00
}
2007-04-26 16:27:49 +04:00
/*
called when a CTDB_REPLY_CONTROL packet comes in
*/
void ctdb_reply_control ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr )
{
2015-10-29 08:44:08 +03:00
struct ctdb_reply_control_old * c = ( struct ctdb_reply_control_old * ) hdr ;
2007-04-26 16:27:49 +04:00
TDB_DATA data ;
struct ctdb_control_state * state ;
2007-05-12 15:25:26 +04:00
const char * errormsg = NULL ;
2007-04-26 16:27:49 +04:00
2015-03-17 06:30:18 +03:00
state = reqid_find ( ctdb - > idr , hdr - > reqid , struct ctdb_control_state ) ;
2007-04-26 16:27:49 +04:00
if ( state = = NULL ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " pnn %u Invalid reqid %u in ctdb_reply_control \n " ,
2007-09-04 04:06:36 +04:00
ctdb - > pnn , hdr - > reqid ) ) ;
2007-04-26 16:27:49 +04:00
return ;
}
if ( hdr - > reqid ! = state - > reqid ) {
/* we found a record but it was the wrong one */
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " Dropped orphaned control reply with reqid:%u \n " , hdr - > reqid ) ) ;
2007-04-26 16:27:49 +04:00
return ;
}
data . dptr = & c - > data [ 0 ] ;
data . dsize = c - > datalen ;
2007-05-12 15:25:26 +04:00
if ( c - > errorlen ) {
errormsg = talloc_strndup ( state ,
( char * ) & c - > data [ c - > datalen ] , c - > errorlen ) ;
}
2007-04-26 16:27:49 +04:00
2007-05-05 02:33:35 +04:00
/* make state a child of the packet, so it goes away when the packet
is freed . */
talloc_steal ( hdr , state ) ;
2007-05-12 15:25:26 +04:00
state - > callback ( ctdb , c - > status , data , errormsg , state - > private_data ) ;
2007-04-26 16:27:49 +04:00
}
static int ctdb_control_destructor ( struct ctdb_control_state * state )
{
2015-03-17 06:30:18 +03:00
reqid_remove ( state - > ctdb - > idr , state - > reqid ) ;
2007-04-26 16:27:49 +04:00
return 0 ;
}
2007-05-10 08:06:48 +04:00
/*
handle a timeout of a control
*/
2015-10-26 08:50:09 +03:00
static void ctdb_control_timeout ( struct tevent_context * ev ,
struct tevent_timer * te ,
struct timeval t , void * private_data )
2007-05-10 08:06:48 +04:00
{
struct ctdb_control_state * state = talloc_get_type ( private_data , struct ctdb_control_state ) ;
2007-05-12 08:34:21 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( ev ) ;
2007-05-10 08:06:48 +04:00
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( state - > ctdb , timeouts . control ) ;
2007-05-10 08:06:48 +04:00
2007-05-12 08:34:21 +04:00
talloc_steal ( tmp_ctx , state ) ;
2007-05-17 08:10:38 +04:00
state - > callback ( state - > ctdb , - 1 , tdb_null ,
" ctdb_control timed out " ,
state - > private_data ) ;
2007-05-12 08:34:21 +04:00
talloc_free ( tmp_ctx ) ;
2007-05-10 08:06:48 +04:00
}
2007-04-26 16:27:49 +04:00
/*
send a control message to a node
*/
int ctdb_daemon_send_control ( struct ctdb_context * ctdb , uint32_t destnode ,
2007-05-04 05:41:29 +04:00
uint64_t srvid , uint32_t opcode , uint32_t client_id ,
uint32_t flags ,
2007-04-30 17:31:40 +04:00
TDB_DATA data ,
2007-04-26 16:27:49 +04:00
ctdb_control_callback_fn_t callback ,
void * private_data )
{
2015-10-29 08:42:05 +03:00
struct ctdb_req_control_old * c ;
2007-04-26 16:27:49 +04:00
struct ctdb_control_state * state ;
size_t len ;
2009-06-30 06:03:12 +04:00
if ( ctdb - > methods = = NULL ) {
2010-10-28 06:38:34 +04:00
DEBUG ( DEBUG_INFO , ( __location__ " Failed to send control. Transport is DOWN \n " ) ) ;
2009-06-30 06:03:12 +04:00
return - 1 ;
}
2007-06-09 15:58:50 +04:00
if ( ( ( destnode = = CTDB_BROADCAST_VNNMAP ) | |
( destnode = = CTDB_BROADCAST_ALL ) | |
( destnode = = CTDB_BROADCAST_CONNECTED ) ) & &
! ( flags & CTDB_CTRL_FLAG_NOREPLY ) ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( " Attempt to broadcast control without NOREPLY \n " ) ) ;
2007-04-30 17:31:40 +04:00
return - 1 ;
}
2007-06-09 15:58:50 +04:00
if ( destnode ! = CTDB_BROADCAST_VNNMAP & &
destnode ! = CTDB_BROADCAST_ALL & &
destnode ! = CTDB_BROADCAST_CONNECTED & &
2007-09-04 04:09:58 +04:00
( ! ctdb_validate_pnn ( ctdb , destnode ) | |
2007-06-07 09:18:55 +04:00
( ctdb - > nodes [ destnode ] - > flags & NODE_FLAGS_DISCONNECTED ) ) ) {
2007-05-17 17:23:41 +04:00
if ( ! ( flags & CTDB_CTRL_FLAG_NOREPLY ) ) {
callback ( ctdb , - 1 , tdb_null , " ctdb_control to disconnected node " , private_data ) ;
}
return 0 ;
}
2007-05-05 02:33:35 +04:00
/* the state is made a child of private_data if possible. This means any reply
will be discarded if the private_data goes away */
state = talloc ( private_data ? private_data : ctdb , struct ctdb_control_state ) ;
2007-04-26 16:27:49 +04:00
CTDB_NO_MEMORY ( ctdb , state ) ;
2015-03-17 06:30:18 +03:00
state - > reqid = reqid_new ( ctdb - > idr , state ) ;
2007-04-26 16:27:49 +04:00
state - > callback = callback ;
state - > private_data = private_data ;
state - > ctdb = ctdb ;
2007-05-17 08:10:38 +04:00
state - > flags = flags ;
2007-04-26 16:27:49 +04:00
talloc_set_destructor ( state , ctdb_control_destructor ) ;
2015-10-29 08:42:05 +03:00
len = offsetof ( struct ctdb_req_control_old , data ) + data . dsize ;
2007-04-28 12:50:32 +04:00
c = ctdb_transport_allocate ( ctdb , state , CTDB_REQ_CONTROL , len ,
2015-10-29 08:42:05 +03:00
struct ctdb_req_control_old ) ;
2007-04-26 16:27:49 +04:00
CTDB_NO_MEMORY ( ctdb , c ) ;
talloc_set_name_const ( c , " ctdb_req_control packet " ) ;
c - > hdr . destnode = destnode ;
c - > hdr . reqid = state - > reqid ;
c - > opcode = opcode ;
2007-05-04 05:41:29 +04:00
c - > client_id = client_id ;
2007-04-30 17:31:40 +04:00
c - > flags = flags ;
2007-04-26 16:27:49 +04:00
c - > srvid = srvid ;
c - > datalen = data . dsize ;
if ( data . dsize ) {
memcpy ( & c - > data [ 0 ] , data . dptr , data . dsize ) ;
}
2007-04-30 17:31:40 +04:00
2007-04-26 16:27:49 +04:00
ctdb_queue_packet ( ctdb , & c - > hdr ) ;
2007-04-30 17:31:40 +04:00
if ( flags & CTDB_CTRL_FLAG_NOREPLY ) {
talloc_free ( state ) ;
return 0 ;
}
2007-06-04 11:46:37 +04:00
if ( ctdb - > tunable . control_timeout ) {
2015-10-26 08:50:09 +03:00
tevent_add_timer ( ctdb - > ev , state ,
timeval_current_ofs ( ctdb - > tunable . control_timeout , 0 ) ,
ctdb_control_timeout , state ) ;
2007-06-04 11:46:37 +04:00
}
2007-04-26 16:27:49 +04:00
talloc_free ( c ) ;
return 0 ;
}