2023-03-22 11:35:55 +03:00
/*
2006-11-28 09:56:10 +03:00
ctdb main protocol code
2006-11-27 13:38:13 +03:00
Copyright ( C ) Andrew Tridgell 2006
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 .
2023-03-22 11:35:55 +03:00
2007-05-31 07:50:53 +04:00
This program is distributed in the hope that it will be useful ,
2006-11-27 13:38:13 +03: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 .
2023-03-22 11:35:55 +03:00
2007-05-31 07:50:53 +04:00
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/>.
2006-11-27 13:38:13 +03:00
*/
2015-10-26 08:50:46 +03:00
# include "replace.h"
2006-11-27 13:38:13 +03:00
# include "system/network.h"
# include "system/filesys.h"
2015-10-26 08:50:46 +03:00
# include <talloc.h>
# include <tevent.h>
# include "lib/util/dlinklist.h"
# include "lib/util/debug.h"
# include "lib/util/samba_util.h"
# include "ctdb_private.h"
# include "ctdb_client.h"
2006-11-27 13:38:13 +03: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"
2015-10-23 06:17:34 +03:00
2006-11-27 13:38:13 +03:00
/*
choose the transport we will use
*/
int ctdb_set_transport ( struct ctdb_context * ctdb , const char * transport )
{
2007-04-20 16:26:19 +04:00
ctdb - > transport = talloc_strdup ( ctdb , transport ) ;
2009-05-21 05:49:16 +04:00
CTDB_NO_MEMORY ( ctdb , ctdb - > transport ) ;
2007-04-20 16:26:19 +04:00
return 0 ;
2006-11-27 13:38:13 +03:00
}
2019-08-08 09:20:44 +03:00
/* Return the node structure for nodeip, NULL if nodeip is invalid */
struct ctdb_node * ctdb_ip_to_node ( struct ctdb_context * ctdb ,
const ctdb_sock_addr * nodeip )
2007-11-26 02:52:55 +03:00
{
2019-06-21 22:53:15 +03:00
unsigned int nodeid ;
2007-11-26 02:52:55 +03:00
for ( nodeid = 0 ; nodeid < ctdb - > num_nodes ; nodeid + + ) {
2009-06-01 08:18:34 +04:00
if ( ctdb - > nodes [ nodeid ] - > flags & NODE_FLAGS_DELETED ) {
continue ;
}
2015-02-20 03:47:23 +03:00
if ( ctdb_same_ip ( & ctdb - > nodes [ nodeid ] - > address , nodeip ) ) {
2019-08-08 09:20:44 +03:00
return ctdb - > nodes [ nodeid ] ;
2007-11-26 02:52:55 +03:00
}
}
2019-08-08 09:20:44 +03:00
return NULL ;
}
/* Return the PNN for nodeip, CTDB_UNKNOWN_PNN if nodeip is invalid */
uint32_t ctdb_ip_to_pnn ( struct ctdb_context * ctdb ,
const ctdb_sock_addr * nodeip )
{
struct ctdb_node * node ;
node = ctdb_ip_to_node ( ctdb , nodeip ) ;
if ( node = = NULL ) {
return CTDB_UNKNOWN_PNN ;
}
return node - > pnn ;
2007-11-26 02:52:55 +03:00
}
2015-02-17 07:35:07 +03:00
/* Load a nodes list file into a nodes array */
static int convert_node_map_to_list ( struct ctdb_context * ctdb ,
TALLOC_CTX * mem_ctx ,
2015-10-29 09:22:48 +03:00
struct ctdb_node_map_old * node_map ,
2015-02-17 07:35:07 +03:00
struct ctdb_node * * * nodes ,
uint32_t * num_nodes )
{
2019-06-07 23:38:56 +03:00
unsigned int i ;
2015-02-17 07:35:07 +03:00
* nodes = talloc_zero_array ( mem_ctx ,
struct ctdb_node * , node_map - > num ) ;
CTDB_NO_MEMORY ( ctdb , * nodes ) ;
* num_nodes = node_map - > num ;
for ( i = 0 ; i < node_map - > num ; i + + ) {
struct ctdb_node * node ;
node = talloc_zero ( * nodes , struct ctdb_node ) ;
CTDB_NO_MEMORY ( ctdb , node ) ;
( * nodes ) [ i ] = node ;
node - > address = node_map - > nodes [ i ] . addr ;
node - > name = talloc_asprintf ( node , " %s:%u " ,
ctdb_addr_to_str ( & node - > address ) ,
ctdb_addr_to_port ( & node - > address ) ) ;
node - > flags = node_map - > nodes [ i ] . flags ;
if ( ! ( node - > flags & NODE_FLAGS_DELETED ) ) {
node - > flags = NODE_FLAGS_UNHEALTHY ;
}
node - > flags | = NODE_FLAGS_DISCONNECTED ;
node - > pnn = i ;
node - > ctdb = ctdb ;
node - > dead_count = 0 ;
}
2006-11-27 13:38:13 +03:00
return 0 ;
}
2015-02-17 07:35:07 +03:00
/* Load the nodes list from a file */
2013-10-21 12:33:10 +04:00
void ctdb_load_nodes_file ( struct ctdb_context * ctdb )
{
2015-10-29 09:22:48 +03:00
struct ctdb_node_map_old * node_map ;
2013-10-21 12:33:10 +04:00
int ret ;
2015-02-17 07:35:07 +03:00
node_map = ctdb_read_nodes_file ( ctdb , ctdb - > nodes_file ) ;
if ( node_map = = NULL ) {
goto fail ;
}
TALLOC_FREE ( ctdb - > nodes ) ;
ret = convert_node_map_to_list ( ctdb , ctdb , node_map ,
& ctdb - > nodes , & ctdb - > num_nodes ) ;
2013-10-21 12:33:10 +04:00
if ( ret = = - 1 ) {
2015-02-17 07:35:07 +03:00
goto fail ;
2013-10-21 12:33:10 +04:00
}
2015-02-17 07:35:07 +03:00
talloc_free ( node_map ) ;
return ;
fail :
DEBUG ( DEBUG_ERR , ( " Failed to load nodes file \" %s \" \n " ,
ctdb - > nodes_file ) ) ;
talloc_free ( node_map ) ;
exit ( 1 ) ;
2013-10-21 12:33:10 +04:00
}
2007-05-25 11:04:13 +04:00
2006-11-27 13:38:13 +03:00
/*
setup the local node address
*/
int ctdb_set_address ( struct ctdb_context * ctdb , const char * address )
{
2015-02-20 03:47:23 +03:00
ctdb - > address = talloc ( ctdb , ctdb_sock_addr ) ;
CTDB_NO_MEMORY ( ctdb , ctdb - > address ) ;
if ( ctdb_parse_address ( ctdb , address , ctdb - > address ) ! = 0 ) {
2006-11-28 09:56:10 +03:00
return - 1 ;
}
2015-02-20 03:47:23 +03:00
ctdb - > name = talloc_asprintf ( ctdb , " %s:%u " ,
ctdb_addr_to_str ( ctdb - > address ) ,
ctdb_addr_to_port ( ctdb - > address ) ) ;
2006-11-28 09:56:10 +03:00
return 0 ;
2006-11-27 13:38:13 +03:00
}
2007-04-26 16:27:49 +04:00
2007-05-17 17:23:41 +04:00
/*
2007-06-18 21:54:06 +04:00
return the number of active nodes
2007-05-17 17:23:41 +04:00
*/
2007-06-18 21:54:06 +04:00
uint32_t ctdb_get_num_active_nodes ( struct ctdb_context * ctdb )
2007-05-17 17:23:41 +04:00
{
2019-06-07 23:38:56 +03:00
unsigned int i ;
2007-05-17 17:23:41 +04:00
uint32_t count = 0 ;
2009-06-01 08:39:34 +04:00
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
if ( ! ( ctdb - > nodes [ i ] - > flags & NODE_FLAGS_INACTIVE ) ) {
2007-05-17 17:23:41 +04:00
count + + ;
}
}
return count ;
}
2007-02-09 04:45:58 +03:00
2006-11-27 13:38:13 +03:00
/*
2007-05-19 07:45:24 +04:00
called when we need to process a packet . This can be a requeued packet
after a lockwait , or a real packet from another node
2006-11-27 13:38:13 +03:00
*/
2007-05-19 07:45:24 +04:00
void ctdb_input_pkt ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr )
2006-11-27 13:38:13 +03:00
{
2007-04-18 05:20:24 +04:00
TALLOC_CTX * tmp_ctx ;
/* place the packet as a child of the tmp_ctx. We then use
talloc_free ( ) below to free it . If any of the calls want
to keep it , then they will steal it somewhere else , and the
talloc_free ( ) will only free the tmp_ctx */
tmp_ctx = talloc_new ( ctdb ) ;
talloc_steal ( tmp_ctx , hdr ) ;
2007-02-07 05:26:07 +03:00
2008-02-04 09:44:24 +03:00
DEBUG ( DEBUG_DEBUG , ( __location__ " ctdb request %u of type %u length %u from "
2007-05-23 14:15:09 +04:00
" node %u to %u \n " , hdr - > reqid , hdr - > operation , hdr - > length ,
2007-04-17 19:59:39 +04:00
hdr - > srcnode , hdr - > destnode ) ) ;
2007-04-17 16:13:06 +04:00
2006-12-01 07:45:24 +03:00
switch ( hdr - > operation ) {
case CTDB_REQ_CALL :
2007-05-12 13:54:40 +04:00
case CTDB_REPLY_CALL :
case CTDB_REQ_DMASTER :
case CTDB_REPLY_DMASTER :
2015-07-27 00:02:57 +03:00
/* we don't allow these calls when banned */
2007-09-04 04:06:36 +04:00
if ( ctdb - > nodes [ ctdb - > pnn ] - > flags & NODE_FLAGS_BANNED ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_DEBUG , ( __location__ " ctdb operation %u "
2007-08-22 06:53:24 +04:00
" request %u "
" length %u from node %u to %u while node "
" is banned \n " ,
hdr - > operation , hdr - > reqid ,
2023-03-22 11:35:55 +03:00
hdr - > length ,
2007-08-22 06:53:24 +04:00
hdr - > srcnode , hdr - > destnode ) ) ;
goto done ;
}
2016-02-02 07:58:37 +03:00
/* for ctdb_call inter-node operations verify that the
remote node that sent us the call is running in the
same generation instance as this node
*/
if ( ctdb - > vnn_map - > generation ! = hdr - > generation ) {
DEBUG ( DEBUG_DEBUG , ( __location__ " ctdb operation %u "
" request %u "
" length %u from node %u to %u had an "
" invalid generation id:%u while our "
2023-03-22 11:35:55 +03:00
" generation id is:%u \n " ,
2016-02-02 07:58:37 +03:00
hdr - > operation , hdr - > reqid ,
2023-03-22 11:35:55 +03:00
hdr - > length ,
hdr - > srcnode , hdr - > destnode ,
2016-02-02 07:58:37 +03:00
hdr - > generation , ctdb - > vnn_map - > generation ) ) ;
goto done ;
}
2007-05-12 13:54:40 +04:00
}
2007-04-29 16:51:56 +04:00
2007-05-12 13:54:40 +04:00
switch ( hdr - > operation ) {
case CTDB_REQ_CALL :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . req_call ) ;
2006-12-01 07:45:24 +03:00
ctdb_request_call ( ctdb , hdr ) ;
break ;
case CTDB_REPLY_CALL :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . reply_call ) ;
2006-12-01 07:45:24 +03:00
ctdb_reply_call ( ctdb , hdr ) ;
break ;
2006-12-18 06:27:20 +03:00
case CTDB_REPLY_ERROR :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . reply_error ) ;
2006-12-18 06:27:20 +03:00
ctdb_reply_error ( ctdb , hdr ) ;
break ;
2006-12-18 08:01:11 +03:00
case CTDB_REQ_DMASTER :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . req_dmaster ) ;
2006-12-18 08:01:11 +03:00
ctdb_request_dmaster ( ctdb , hdr ) ;
break ;
case CTDB_REPLY_DMASTER :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . reply_dmaster ) ;
2006-12-18 08:01:11 +03:00
ctdb_reply_dmaster ( ctdb , hdr ) ;
break ;
2007-02-09 01:42:04 +03:00
case CTDB_REQ_MESSAGE :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . req_message ) ;
2007-02-09 01:42:04 +03:00
ctdb_request_message ( ctdb , hdr ) ;
break ;
2007-04-26 16:27:49 +04:00
case CTDB_REQ_CONTROL :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . req_control ) ;
2007-04-26 16:27:49 +04:00
ctdb_request_control ( ctdb , hdr ) ;
break ;
case CTDB_REPLY_CONTROL :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node . reply_control ) ;
2007-04-26 16:27:49 +04:00
ctdb_reply_control ( ctdb , hdr ) ;
break ;
2007-05-18 13:19:35 +04:00
case CTDB_REQ_KEEPALIVE :
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , keepalive_packets_recv ) ;
2017-04-21 10:55:11 +03:00
ctdb_request_keepalive ( ctdb , hdr ) ;
2007-05-18 13:19:35 +04:00
break ;
2017-04-06 12:09:58 +03:00
case CTDB_REQ_TUNNEL :
CTDB_INCREMENT_STAT ( ctdb , node . req_tunnel ) ;
ctdb_request_tunnel ( ctdb , hdr ) ;
break ;
2006-12-01 07:45:24 +03:00
default :
2023-03-22 11:35:55 +03:00
DEBUG ( DEBUG_CRIT , ( " %s: Packet with unknown operation %u \n " ,
2007-04-17 16:13:06 +04:00
__location__ , hdr - > operation ) ) ;
2006-12-01 07:45:24 +03:00
break ;
}
2007-04-18 05:20:24 +04:00
done :
talloc_free ( tmp_ctx ) ;
2006-11-27 13:38:13 +03:00
}
2007-05-19 07:45:24 +04:00
2006-11-28 03:51:33 +03:00
/*
2006-11-28 09:56:10 +03:00
called by the transport layer when a node is dead
2006-11-28 03:51:33 +03:00
*/
2007-05-19 10:59:10 +04:00
void ctdb_node_dead ( struct ctdb_node * node )
2006-11-28 03:51:33 +03:00
{
2020-02-29 14:26:19 +03:00
if ( node - > ctdb - > methods = = NULL ) {
2020-03-01 08:40:41 +03:00
DBG_ERR ( " Can not restart transport while shutting down \n " ) ;
2020-02-29 14:26:19 +03:00
return ;
}
node - > ctdb - > methods - > restart ( node ) ;
2020-03-01 08:40:41 +03:00
2007-06-07 09:18:55 +04:00
if ( node - > flags & NODE_FLAGS_DISCONNECTED ) {
2023-03-22 11:35:55 +03:00
DEBUG ( DEBUG_INFO , ( " %s: node %s is already marked disconnected: %u connected \n " ,
node - > ctdb - > name , node - > name ,
2007-05-30 08:35:22 +04:00
node - > ctdb - > num_connected ) ) ;
return ;
}
2006-12-01 00:58:08 +03:00
node - > ctdb - > num_connected - - ;
2007-10-10 04:45:22 +04:00
node - > flags | = NODE_FLAGS_DISCONNECTED | NODE_FLAGS_UNHEALTHY ;
2007-05-19 08:04:48 +04:00
node - > rx_cnt = 0 ;
2007-05-19 11:21:58 +04:00
node - > dead_count = 0 ;
2007-10-19 02:58:30 +04:00
2017-07-04 08:18:39 +03:00
DEBUG ( DEBUG_ERR , ( " %s: node %s is dead: %u connected \n " ,
2007-04-17 16:13:06 +04:00
node - > ctdb - > name , node - > name , node - > ctdb - > num_connected ) ) ;
2007-05-18 17:48:29 +04:00
ctdb_daemon_cancel_controls ( node - > ctdb , node ) ;
2006-11-28 03:51:33 +03:00
}
2006-11-28 06:15:46 +03:00
/*
2007-02-07 05:26:07 +03:00
called by the transport layer when a node is connected
2006-11-28 06:15:46 +03:00
*/
2007-05-19 11:21:58 +04:00
void ctdb_node_connected ( struct ctdb_node * node )
2006-11-28 06:15:46 +03:00
{
2007-06-07 09:18:55 +04:00
if ( ! ( node - > flags & NODE_FLAGS_DISCONNECTED ) ) {
2023-03-22 11:35:55 +03:00
DEBUG ( DEBUG_INFO , ( " %s: node %s is already marked connected: %u connected \n " ,
node - > ctdb - > name , node - > name ,
2007-05-30 08:35:22 +04:00
node - > ctdb - > num_connected ) ) ;
return ;
}
2006-12-01 00:58:08 +03:00
node - > ctdb - > num_connected + + ;
2007-05-19 11:21:58 +04:00
node - > dead_count = 0 ;
2007-06-07 09:18:55 +04:00
node - > flags & = ~ NODE_FLAGS_DISCONNECTED ;
2017-07-04 08:18:39 +03:00
DEBUG ( DEBUG_ERR ,
2023-03-22 11:35:55 +03:00
( " %s: connected to %s - %u connected \n " ,
2013-10-29 07:05:41 +04:00
node - > ctdb - > name , node - > name , node - > ctdb - > num_connected ) ) ;
2006-12-01 00:58:08 +03:00
}
2007-04-20 11:58:37 +04:00
struct queue_next {
struct ctdb_context * ctdb ;
struct ctdb_req_header * hdr ;
} ;
/*
2009-12-09 19:14:16 +03:00
triggered when a deferred packet is due
2007-04-20 11:58:37 +04:00
*/
2015-10-26 08:50:09 +03:00
static void queue_next_trigger ( struct tevent_context * ev ,
struct tevent_timer * te ,
2007-04-20 11:58:37 +04:00
struct timeval t , void * private_data )
{
struct queue_next * q = talloc_get_type ( private_data , struct queue_next ) ;
2007-05-19 07:45:24 +04:00
ctdb_input_pkt ( q - > ctdb , q - > hdr ) ;
2007-05-23 14:06:37 +04:00
talloc_free ( q ) ;
2023-03-22 11:35:55 +03:00
}
2007-04-20 11:58:37 +04:00
/*
defer a packet , so it is processed on the next event loop
this is used for sending packets to ourselves
*/
static void ctdb_defer_packet ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr )
{
struct queue_next * q ;
q = talloc ( ctdb , struct queue_next ) ;
if ( q = = NULL ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( __location__ " Failed to allocate deferred packet \n " ) ) ;
2007-04-20 11:58:37 +04:00
return ;
}
q - > ctdb = ctdb ;
2018-06-06 16:47:13 +03:00
q - > hdr = talloc_memdup ( q , hdr , hdr - > length ) ;
2007-04-20 11:58:37 +04:00
if ( q - > hdr = = NULL ) {
2018-06-06 16:47:13 +03:00
talloc_free ( q ) ;
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " Error copying deferred packet to self \n " ) ) ;
2007-04-20 11:58:37 +04:00
return ;
}
2007-04-22 16:26:45 +04:00
#if 0
/* use this to put packets directly into our recv function */
2007-05-19 07:45:24 +04:00
ctdb_input_pkt ( q - > ctdb , q - > hdr ) ;
2007-04-22 16:26:45 +04:00
# else
2015-10-26 08:50:09 +03:00
tevent_add_timer ( ctdb - > ev , q , timeval_zero ( ) , queue_next_trigger , q ) ;
2007-04-22 16:26:45 +04:00
# endif
2007-04-20 11:58:37 +04:00
}
2007-04-30 17:31:40 +04:00
/*
broadcast a packet to all nodes
*/
2023-03-22 11:35:55 +03:00
static void ctdb_broadcast_packet_all ( struct ctdb_context * ctdb ,
2007-06-09 15:58:50 +04:00
struct ctdb_req_header * hdr )
2007-04-30 17:31:40 +04:00
{
2019-06-07 23:38:56 +03:00
unsigned int i ;
2009-06-01 08:18:34 +04:00
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
if ( ctdb - > nodes [ i ] - > flags & NODE_FLAGS_DELETED ) {
continue ;
}
2007-09-04 03:50:07 +04:00
hdr - > destnode = ctdb - > nodes [ i ] - > pnn ;
2007-04-30 17:31:40 +04:00
ctdb_queue_packet ( ctdb , hdr ) ;
}
}
2007-05-05 07:17:26 +04:00
/*
2018-06-14 23:01:52 +03:00
broadcast a packet to all active nodes
2007-05-05 07:17:26 +04:00
*/
2018-06-14 23:01:52 +03:00
static void ctdb_broadcast_packet_active ( struct ctdb_context * ctdb ,
2007-06-09 15:58:50 +04:00
struct ctdb_req_header * hdr )
2007-05-05 07:17:26 +04:00
{
2019-06-07 23:38:56 +03:00
unsigned int i ;
2018-06-14 23:01:52 +03:00
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
if ( ctdb - > nodes [ i ] - > flags & NODE_FLAGS_INACTIVE ) {
continue ;
}
hdr - > destnode = ctdb - > nodes [ i ] - > pnn ;
2007-05-05 07:17:26 +04:00
ctdb_queue_packet ( ctdb , hdr ) ;
}
}
2007-06-09 15:58:50 +04:00
/*
broadcast a packet to all connected nodes
*/
2023-03-22 11:35:55 +03:00
static void ctdb_broadcast_packet_connected ( struct ctdb_context * ctdb ,
2007-06-09 15:58:50 +04:00
struct ctdb_req_header * hdr )
{
2019-06-07 23:38:56 +03:00
unsigned int i ;
2009-06-01 08:18:34 +04:00
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
if ( ctdb - > nodes [ i ] - > flags & NODE_FLAGS_DELETED ) {
continue ;
}
2007-06-09 15:58:50 +04:00
if ( ! ( ctdb - > nodes [ i ] - > flags & NODE_FLAGS_DISCONNECTED ) ) {
2007-09-04 03:50:07 +04:00
hdr - > destnode = ctdb - > nodes [ i ] - > pnn ;
2007-06-09 15:58:50 +04:00
ctdb_queue_packet ( ctdb , hdr ) ;
}
}
}
2007-02-09 01:42:04 +03:00
/*
queue a packet or die
*/
void ctdb_queue_packet ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr )
{
struct ctdb_node * node ;
2007-04-30 17:31:40 +04:00
2007-05-05 07:17:26 +04:00
switch ( hdr - > destnode ) {
case CTDB_BROADCAST_ALL :
ctdb_broadcast_packet_all ( ctdb , hdr ) ;
return ;
2018-06-14 23:01:52 +03:00
case CTDB_BROADCAST_ACTIVE :
ctdb_broadcast_packet_active ( ctdb , hdr ) ;
2007-04-30 17:31:40 +04:00
return ;
2007-06-09 15:58:50 +04:00
case CTDB_BROADCAST_CONNECTED :
ctdb_broadcast_packet_connected ( ctdb , hdr ) ;
return ;
2007-04-30 17:31:40 +04:00
}
2010-09-29 04:38:41 +04:00
CTDB_INCREMENT_STAT ( ctdb , node_packets_sent ) ;
2007-04-26 17:38:33 +04:00
2007-09-04 04:09:58 +04:00
if ( ! ctdb_validate_pnn ( ctdb , hdr - > destnode ) ) {
2023-03-22 11:36:23 +03:00
DEBUG ( DEBUG_CRIT , ( __location__ " can't send to node %u that does not exist \n " ,
2007-04-26 17:38:33 +04:00
hdr - > destnode ) ) ;
return ;
}
2007-02-09 01:42:04 +03:00
node = ctdb - > nodes [ hdr - > destnode ] ;
2007-04-26 17:38:33 +04:00
2009-06-01 08:56:19 +04:00
if ( node - > flags & NODE_FLAGS_DELETED ) {
DEBUG ( DEBUG_ERR , ( __location__ " Can not queue packet to DELETED node %d \n " , hdr - > destnode ) ) ;
return ;
}
if ( node - > pnn = = ctdb - > pnn ) {
2007-04-20 11:58:37 +04:00
ctdb_defer_packet ( ctdb , hdr ) ;
2009-12-09 19:20:23 +03:00
return ;
}
2008-05-11 08:28:33 +04:00
2009-12-09 19:20:23 +03:00
if ( ctdb - > methods = = NULL ) {
DEBUG ( DEBUG_ALERT , ( __location__ " Can not queue packet. "
" Transport is DOWN \n " ) ) ;
return ;
}
node - > tx_cnt + + ;
if ( ctdb - > methods - > queue_pkt ( node , ( uint8_t * ) hdr , hdr - > length ) ! = 0 ) {
ctdb_fatal ( ctdb , " Unable to queue packet \n " ) ;
2007-02-09 01:42:04 +03:00
}
}
2008-07-04 12:00:24 +04:00
/*
a valgrind hack to allow us to get opcode specific backtraces
very ugly , and relies on no compiler optimisation !
*/
void ctdb_queue_packet_opcode ( struct ctdb_context * ctdb , struct ctdb_req_header * hdr , unsigned opcode )
{
switch ( opcode ) {
2008-07-07 02:52:04 +04:00
# define DO_OP(x) case x: ctdb_queue_packet(ctdb, hdr); break
2008-07-04 12:00:24 +04:00
DO_OP ( 1 ) ;
DO_OP ( 2 ) ;
DO_OP ( 3 ) ;
DO_OP ( 4 ) ;
DO_OP ( 5 ) ;
DO_OP ( 6 ) ;
DO_OP ( 7 ) ;
DO_OP ( 8 ) ;
DO_OP ( 9 ) ;
DO_OP ( 10 ) ;
DO_OP ( 11 ) ;
DO_OP ( 12 ) ;
DO_OP ( 13 ) ;
DO_OP ( 14 ) ;
DO_OP ( 15 ) ;
DO_OP ( 16 ) ;
DO_OP ( 17 ) ;
DO_OP ( 18 ) ;
DO_OP ( 19 ) ;
DO_OP ( 20 ) ;
DO_OP ( 21 ) ;
DO_OP ( 22 ) ;
DO_OP ( 23 ) ;
DO_OP ( 24 ) ;
DO_OP ( 25 ) ;
DO_OP ( 26 ) ;
DO_OP ( 27 ) ;
DO_OP ( 28 ) ;
DO_OP ( 29 ) ;
DO_OP ( 30 ) ;
DO_OP ( 31 ) ;
DO_OP ( 32 ) ;
DO_OP ( 33 ) ;
DO_OP ( 34 ) ;
DO_OP ( 35 ) ;
DO_OP ( 36 ) ;
DO_OP ( 37 ) ;
DO_OP ( 38 ) ;
DO_OP ( 39 ) ;
DO_OP ( 40 ) ;
DO_OP ( 41 ) ;
DO_OP ( 42 ) ;
DO_OP ( 43 ) ;
DO_OP ( 44 ) ;
DO_OP ( 45 ) ;
DO_OP ( 46 ) ;
DO_OP ( 47 ) ;
DO_OP ( 48 ) ;
DO_OP ( 49 ) ;
DO_OP ( 50 ) ;
DO_OP ( 51 ) ;
DO_OP ( 52 ) ;
DO_OP ( 53 ) ;
DO_OP ( 54 ) ;
DO_OP ( 55 ) ;
DO_OP ( 56 ) ;
DO_OP ( 57 ) ;
DO_OP ( 58 ) ;
DO_OP ( 59 ) ;
DO_OP ( 60 ) ;
DO_OP ( 61 ) ;
DO_OP ( 62 ) ;
DO_OP ( 63 ) ;
DO_OP ( 64 ) ;
DO_OP ( 65 ) ;
DO_OP ( 66 ) ;
DO_OP ( 67 ) ;
DO_OP ( 68 ) ;
DO_OP ( 69 ) ;
DO_OP ( 70 ) ;
DO_OP ( 71 ) ;
DO_OP ( 72 ) ;
DO_OP ( 73 ) ;
DO_OP ( 74 ) ;
DO_OP ( 75 ) ;
DO_OP ( 76 ) ;
DO_OP ( 77 ) ;
DO_OP ( 78 ) ;
DO_OP ( 79 ) ;
DO_OP ( 80 ) ;
DO_OP ( 81 ) ;
DO_OP ( 82 ) ;
DO_OP ( 83 ) ;
DO_OP ( 84 ) ;
DO_OP ( 85 ) ;
DO_OP ( 86 ) ;
DO_OP ( 87 ) ;
DO_OP ( 88 ) ;
DO_OP ( 89 ) ;
DO_OP ( 90 ) ;
DO_OP ( 91 ) ;
DO_OP ( 92 ) ;
DO_OP ( 93 ) ;
DO_OP ( 94 ) ;
DO_OP ( 95 ) ;
DO_OP ( 96 ) ;
DO_OP ( 97 ) ;
DO_OP ( 98 ) ;
DO_OP ( 99 ) ;
DO_OP ( 100 ) ;
2023-03-22 11:35:55 +03:00
default :
2008-07-04 12:00:24 +04:00
ctdb_queue_packet ( ctdb , hdr ) ;
break ;
}
}