2007-01-02 20:16:39 +03:00
/*
* Unix SMB / CIFS implementation .
* Join infiniband wrapper and ctdb .
*
* Copyright ( C ) Sven Oehme < oehmes @ de . ibm . com > 2006
*
* Major code contributions by Peter Somogyi < psomogyi @ gamax . hu >
*
* 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-01-02 20:16:39 +03:00
* ( 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
2007-07-10 09:46:05 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-01-02 20:16:39 +03:00
*/
2015-10-26 08:50:46 +03:00
# include "replace.h"
# include "system/network.h"
2007-01-02 20:16:39 +03:00
# include <assert.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 "ctdb_logging.h"
2007-01-02 20:16:39 +03:00
# include "ctdb_private.h"
2015-10-26 08:50:46 +03:00
2007-01-02 20:16:39 +03:00
# include "ibwrapper.h"
# include "ibw_ctdb.h"
static int ctdb_ibw_listen ( struct ctdb_context * ctdb , int backlog )
{
2007-04-13 14:38:24 +04:00
struct ibw_ctx * ictx = talloc_get_type ( ctdb - > private_data , struct ibw_ctx ) ;
2007-01-02 20:16:39 +03:00
assert ( ictx ! = NULL ) ;
2015-10-13 08:19:21 +03:00
if ( ibw_bind ( ictx , & ctdb - > address - > ip ) ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( " ctdb_ibw_listen: ibw_bind failed \n " ) ) ;
2007-01-02 20:16:39 +03:00
return - 1 ;
}
if ( ibw_listen ( ictx , backlog ) ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( " ctdb_ibw_listen: ibw_listen failed \n " ) ) ;
2007-01-02 20:16:39 +03:00
return - 1 ;
}
return 0 ;
}
2007-04-26 17:28:13 +04:00
/*
* initialise ibw portion of a ctdb node
*/
static int ctdb_ibw_add_node ( struct ctdb_node * node )
{
struct ibw_ctx * ictx = talloc_get_type ( node - > ctdb - > private_data , struct ibw_ctx ) ;
struct ctdb_ibw_node * cn = talloc_zero ( node , struct ctdb_ibw_node ) ;
assert ( cn ! = NULL ) ;
cn - > conn = ibw_conn_new ( ictx , node ) ;
node - > private_data = ( void * ) cn ;
return ( cn - > conn ! = NULL ? 0 : - 1 ) ;
}
2007-01-02 20:16:39 +03:00
/*
2007-05-30 07:26:50 +04:00
* initialise infiniband
2007-01-02 20:16:39 +03:00
*/
2007-05-30 07:26:50 +04:00
static int ctdb_ibw_initialise ( struct ctdb_context * ctdb )
2007-01-02 20:16:39 +03:00
{
2007-04-26 17:28:13 +04:00
int i , ret ;
ret = ctdb_ibw_init ( ctdb ) ;
if ( ret ! = 0 ) {
return ret ;
}
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
if ( ctdb_ibw_add_node ( ctdb - > nodes [ i ] ) ! = 0 ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( " methods->add_node failed at %d \n " , i ) ) ;
2007-04-26 17:28:13 +04:00
return - 1 ;
}
}
2007-01-02 20:16:39 +03:00
2007-05-30 08:46:14 +04:00
/* listen on our own address */
if ( ctdb_ibw_listen ( ctdb , 10 ) ) /* TODO: backlog as param */
return - 1 ;
2007-05-30 07:26:50 +04:00
return 0 ;
}
/*
* Start infiniband
*/
static int ctdb_ibw_start ( struct ctdb_context * ctdb )
{
2014-05-28 04:40:29 +04:00
int i ;
2007-05-30 07:26:50 +04:00
2007-01-02 20:16:39 +03:00
/* everything async here */
for ( i = 0 ; i < ctdb - > num_nodes ; i + + ) {
struct ctdb_node * node = ctdb - > nodes [ i ] ;
2015-10-13 08:19:21 +03:00
if ( ! ctdb_same_address ( ctdb - > address , & node - > address ) ) {
2007-06-05 11:57:07 +04:00
ctdb_ibw_node_connect ( node ) ;
}
2007-01-02 20:16:39 +03:00
}
return 0 ;
}
2007-02-26 13:59:20 +03:00
static int ctdb_ibw_send_pkt ( struct ibw_conn * conn , uint8_t * data , uint32_t length )
{
void * buf , * key ;
if ( ibw_alloc_send_buf ( conn , & buf , & key , length ) ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " queue_pkt/ibw_alloc_send_buf failed \n " ) ) ;
2007-02-26 13:59:20 +03:00
return - 1 ;
}
memcpy ( buf , data , length ) ;
return ibw_send ( conn , buf , key , length ) ;
}
int ctdb_flush_cn_queue ( struct ctdb_ibw_node * cn )
{
struct ctdb_ibw_msg * p ;
int rc = 0 ;
while ( cn - > queue ) {
p = cn - > queue ;
rc = ctdb_ibw_send_pkt ( cn - > conn , p - > data , p - > length ) ;
if ( rc )
return - 1 ; /* will be retried later when conn is up */
DLIST_REMOVE ( cn - > queue , p ) ;
cn - > qcnt - - ;
talloc_free ( p ) ; /* it will talloc_free p->data as well */
}
assert ( cn - > qcnt = = 0 ) ;
/* cn->queue_last = NULL is not needed - see DLIST_ADD_AFTER */
return rc ;
2007-01-02 20:16:39 +03:00
}
2007-01-25 16:22:03 +03:00
static int ctdb_ibw_queue_pkt ( struct ctdb_node * node , uint8_t * data , uint32_t length )
{
2007-04-13 14:38:24 +04:00
struct ctdb_ibw_node * cn = talloc_get_type ( node - > private_data , struct ctdb_ibw_node ) ;
2007-01-25 16:22:03 +03:00
int rc ;
2007-02-14 20:58:20 +03:00
assert ( length > = sizeof ( uint32_t ) ) ;
2007-02-26 13:59:20 +03:00
assert ( cn ! = NULL ) ;
2007-02-14 20:58:20 +03:00
2007-02-26 13:59:20 +03:00
if ( cn - > conn = = NULL ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " ctdb_ibw_queue_pkt: conn is NULL \n " ) ) ;
2007-02-14 20:58:20 +03:00
return - 1 ;
}
2007-02-26 13:59:20 +03:00
if ( cn - > conn - > state = = IBWC_CONNECTED ) {
rc = ctdb_ibw_send_pkt ( cn - > conn , data , length ) ;
} else {
struct ctdb_ibw_msg * p = talloc_zero ( cn , struct ctdb_ibw_msg ) ;
2009-05-21 05:49:16 +04:00
CTDB_NO_MEMORY ( node - > ctdb , p ) ;
2007-02-26 13:59:20 +03:00
p - > data = talloc_memdup ( p , data , length ) ;
2009-05-21 05:49:16 +04:00
CTDB_NO_MEMORY ( node - > ctdb , p - > data ) ;
2007-02-26 13:59:20 +03:00
p - > length = length ;
2007-01-25 16:22:03 +03:00
2007-02-26 13:59:20 +03:00
DLIST_ADD_AFTER ( cn - > queue , p , cn - > queue_last ) ;
cn - > queue_last = p ;
cn - > qcnt + + ;
rc = 0 ;
}
2007-01-25 16:22:03 +03:00
return rc ;
}
2007-10-19 03:04:52 +04:00
static void ctdb_ibw_restart ( struct ctdb_node * node )
{
/* TODO: implement this method for IB */
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ALERT , ( " WARNING: method restart is not yet implemented for IB \n " ) ) ;
2007-10-19 03:04:52 +04:00
}
2007-01-02 20:16:39 +03:00
/*
* transport packet allocator - allows transport to control memory for packets
*/
2007-04-19 04:37:44 +04:00
static void * ctdb_ibw_allocate_pkt ( TALLOC_CTX * mem_ctx , size_t size )
2007-01-02 20:16:39 +03:00
{
2007-02-14 20:58:20 +03:00
/* TODO: use ibw_alloc_send_buf instead... */
2007-04-19 04:37:44 +04:00
return talloc_size ( mem_ctx , size ) ;
2007-01-02 20:16:39 +03:00
}
2007-02-14 20:58:20 +03:00
# ifdef __NOTDEF__
2007-01-05 20:13:35 +03:00
static int ctdb_ibw_stop ( struct ctdb_context * cctx )
{
2007-04-13 14:38:24 +04:00
struct ibw_ctx * ictx = talloc_get_type ( cctx - > private_data , struct ibw_ctx ) ;
2007-01-05 20:13:35 +03:00
assert ( ictx ! = NULL ) ;
return ibw_stop ( ictx ) ;
2007-01-02 20:16:39 +03:00
}
2007-01-25 16:22:03 +03:00
# endif /* __NOTDEF__ */
2007-01-02 20:16:39 +03:00
static const struct ctdb_methods ctdb_ibw_methods = {
2007-05-30 07:26:50 +04:00
. initialise = ctdb_ibw_initialise ,
2007-01-02 20:16:39 +03:00
. start = ctdb_ibw_start ,
. queue_pkt = ctdb_ibw_queue_pkt ,
2007-04-26 17:28:13 +04:00
. add_node = ctdb_ibw_add_node ,
2007-02-14 20:58:20 +03:00
. allocate_pkt = ctdb_ibw_allocate_pkt ,
2007-10-19 03:04:52 +04:00
. restart = ctdb_ibw_restart ,
2007-01-05 20:13:35 +03:00
2007-01-25 16:22:03 +03:00
// .stop = ctdb_ibw_stop
2007-01-02 20:16:39 +03:00
} ;
/*
* initialise ibw portion of ctdb
*/
int ctdb_ibw_init ( struct ctdb_context * ctdb )
{
struct ibw_ctx * ictx ;
2007-01-05 20:13:35 +03:00
2008-02-04 09:44:24 +03:00
DEBUG ( DEBUG_DEBUG , ( " ctdb_ibw_init invoked... \n " ) ) ;
2007-01-02 20:16:39 +03:00
ictx = ibw_init (
NULL , //struct ibw_initattr *attr, /* TODO */
0 , //int nattr, /* TODO */
ctdb ,
ctdb_ibw_connstate_handler ,
ctdb_ibw_receive_handler ,
ctdb - > ev ) ;
if ( ictx = = NULL ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_CRIT , ( " ctdb_ibw_init: ibw_init failed \n " ) ) ;
2007-01-02 20:16:39 +03:00
return - 1 ;
}
ctdb - > methods = & ctdb_ibw_methods ;
2007-04-13 14:38:24 +04:00
ctdb - > private_data = ictx ;
2007-02-14 20:58:20 +03:00
2008-02-04 09:44:24 +03:00
DEBUG ( DEBUG_DEBUG , ( " ctdb_ibw_init succeeded. \n " ) ) ;
2007-01-02 20:16:39 +03:00
return 0 ;
}