2006-11-28 09:56:10 +03:00
/*
ctdb utility code
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 .
This program is distributed in the hope that it will be useful ,
2006-11-28 09:56:10 +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 .
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-28 09:56:10 +03:00
*/
# include "includes.h"
# include "lib/events/events.h"
2007-04-16 04:21:44 +04:00
# include "lib/tdb/include/tdb.h"
2006-11-28 09:56:10 +03:00
# include "system/network.h"
# include "system/filesys.h"
2008-01-10 01:43:14 +03:00
# include "system/wait.h"
2007-04-16 04:21:44 +04:00
# include "../include/ctdb_private.h"
2006-11-28 09:56:10 +03:00
2008-02-04 09:44:24 +03:00
int LogLevel = DEBUG_NOTICE ;
int this_log_level = 0 ;
2007-04-17 16:13:06 +04:00
2006-11-28 09:56:10 +03:00
/*
return error string for last error
*/
const char * ctdb_errstr ( struct ctdb_context * ctdb )
{
return ctdb - > err_msg ;
}
/*
remember an error message
*/
void ctdb_set_error ( struct ctdb_context * ctdb , const char * fmt , . . . )
{
va_list ap ;
talloc_free ( ctdb - > err_msg ) ;
va_start ( ap , fmt ) ;
ctdb - > err_msg = talloc_vasprintf ( ctdb , fmt , ap ) ;
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " ctdb error: %s \n " , ctdb - > err_msg ) ) ;
2006-11-28 09:56:10 +03:00
va_end ( ap ) ;
}
2006-12-18 08:01:11 +03:00
/*
a fatal internal error occurred - no hope for recovery
*/
void ctdb_fatal ( struct ctdb_context * ctdb , const char * msg )
{
2008-02-04 09:44:24 +03:00
DEBUG ( DEBUG_ALERT , ( " ctdb fatal error: %s \n " , msg ) ) ;
2006-12-18 08:01:11 +03:00
abort ( ) ;
}
2006-11-28 09:56:10 +03:00
/*
parse a IP : port pair
*/
int ctdb_parse_address ( struct ctdb_context * ctdb ,
TALLOC_CTX * mem_ctx , const char * str ,
struct ctdb_address * address )
{
2007-05-29 09:15:00 +04:00
struct servent * se ;
setservent ( 0 ) ;
se = getservbyname ( " ctdb " , " tcp " ) ;
endservent ( ) ;
2006-11-28 09:56:10 +03:00
2007-05-29 09:15:00 +04:00
address - > address = talloc_strdup ( mem_ctx , str ) ;
2009-05-21 05:49:16 +04:00
CTDB_NO_MEMORY ( ctdb , address - > address ) ;
2007-05-29 09:15:00 +04:00
if ( se = = NULL ) {
address - > port = CTDB_PORT ;
} else {
address - > port = ntohs ( se - > s_port ) ;
}
2006-11-28 09:56:10 +03:00
return 0 ;
}
/*
check if two addresses are the same
*/
bool ctdb_same_address ( struct ctdb_address * a1 , struct ctdb_address * a2 )
{
return strcmp ( a1 - > address , a2 - > address ) = = 0 & & a1 - > port = = a2 - > port ;
}
/*
hash function for mapping data to a VNN - taken from tdb
*/
2006-12-18 08:01:11 +03:00
uint32_t ctdb_hash ( const TDB_DATA * key )
2006-11-28 09:56:10 +03:00
{
uint32_t value ; /* Used to compute the hash value. */
uint32_t i ; /* Used to cycle through random values. */
/* Set the initial value from the key size. */
for ( value = 0x238F13AF * key - > dsize , i = 0 ; i < key - > dsize ; i + + )
value = ( value + ( key - > dptr [ i ] < < ( i * 5 % 24 ) ) ) ;
return ( 1103515243 * value + 12345 ) ;
}
2007-04-18 12:39:02 +04:00
2007-04-19 05:28:01 +04:00
/*
a type checking varient of idr_find
*/
2007-04-23 12:19:50 +04:00
static void * _idr_find_type ( struct idr_context * idp , int id , const char * type , const char * location )
2007-04-19 05:28:01 +04:00
{
void * p = idr_find ( idp , id ) ;
if ( p & & talloc_check_name ( p , type ) = = NULL ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " %s idr_find_type expected type %s but got %s \n " ,
2007-04-19 05:28:01 +04:00
location , type , talloc_get_name ( p ) ) ) ;
return NULL ;
}
return p ;
}
2007-04-20 14:07:47 +04:00
/*
update a max latency number
*/
2008-10-30 04:49:53 +03:00
void ctdb_latency ( struct ctdb_db_context * ctdb_db , const char * name , double * latency , struct timeval t )
2007-04-20 14:07:47 +04:00
{
double l = timeval_elapsed ( & t ) ;
if ( l > * latency ) {
* latency = l ;
}
2008-10-30 04:49:53 +03:00
if ( ctdb_db - > ctdb - > tunable . log_latency_ms ! = 0 ) {
2008-10-30 05:34:10 +03:00
if ( l * 1000 > ctdb_db - > ctdb - > tunable . log_latency_ms ) {
DEBUG ( DEBUG_WARNING , ( " High latency %fs for operation %s on database %s \n " , l * 1000000 , name , ctdb_db - > db_name ) ) ;
2008-10-30 04:49:53 +03:00
}
}
2007-04-20 14:07:47 +04:00
}
2007-04-23 12:19:50 +04:00
2009-05-14 04:33:25 +04:00
/*
update a reclock latency number
*/
void ctdb_reclock_latency ( struct ctdb_context * ctdb , const char * name , double * latency , double l )
{
if ( l > * latency ) {
* latency = l ;
}
if ( ctdb - > tunable . reclock_latency_ms ! = 0 ) {
if ( l * 1000 > ctdb - > tunable . reclock_latency_ms ) {
DEBUG ( DEBUG_ERR , ( " High RECLOCK latency %fs for operation %s \n " , l , name ) ) ;
}
}
}
2007-04-23 12:19:50 +04:00
uint32_t ctdb_reqid_new ( struct ctdb_context * ctdb , void * state )
{
uint32_t id ;
id = ctdb - > idr_cnt + + & 0xFFFF ;
id | = ( idr_get_new ( ctdb - > idr , state , 0xFFFF ) < < 16 ) ;
return id ;
}
void * _ctdb_reqid_find ( struct ctdb_context * ctdb , uint32_t reqid , const char * type , const char * location )
{
void * p ;
p = _idr_find_type ( ctdb - > idr , ( reqid > > 16 ) & 0xFFFF , type , location ) ;
if ( p = = NULL ) {
2008-09-09 07:59:48 +04:00
DEBUG ( DEBUG_WARNING , ( " Could not find idr:%u \n " , reqid ) ) ;
2007-04-23 12:19:50 +04:00
}
return p ;
}
void ctdb_reqid_remove ( struct ctdb_context * ctdb , uint32_t reqid )
{
int ret ;
ret = idr_remove ( ctdb - > idr , ( reqid > > 16 ) & 0xFFFF ) ;
if ( ret ! = 0 ) {
2008-02-04 12:07:15 +03:00
DEBUG ( DEBUG_ERR , ( " Removing idr that does not exist \n " ) ) ;
2007-04-23 12:19:50 +04:00
}
}
2007-05-10 11:43:45 +04:00
/*
form a ctdb_rec_data record from a key / data pair
2007-09-21 06:24:02 +04:00
note that header may be NULL . If not NULL then it is included in the data portion
of the record
2007-05-10 11:43:45 +04:00
*/
2007-09-21 06:24:02 +04:00
struct ctdb_rec_data * ctdb_marshall_record ( TALLOC_CTX * mem_ctx , uint32_t reqid ,
TDB_DATA key ,
struct ctdb_ltdb_header * header ,
TDB_DATA data )
2007-05-10 11:43:45 +04:00
{
size_t length ;
struct ctdb_rec_data * d ;
2007-09-21 06:24:02 +04:00
length = offsetof ( struct ctdb_rec_data , data ) + key . dsize +
data . dsize + ( header ? sizeof ( * header ) : 0 ) ;
2007-05-10 11:43:45 +04:00
d = ( struct ctdb_rec_data * ) talloc_size ( mem_ctx , length ) ;
if ( d = = NULL ) {
return NULL ;
}
d - > length = length ;
d - > reqid = reqid ;
d - > keylen = key . dsize ;
memcpy ( & d - > data [ 0 ] , key . dptr , key . dsize ) ;
2007-09-21 06:24:02 +04:00
if ( header ) {
d - > datalen = data . dsize + sizeof ( * header ) ;
memcpy ( & d - > data [ key . dsize ] , header , sizeof ( * header ) ) ;
memcpy ( & d - > data [ key . dsize + sizeof ( * header ) ] , data . dptr , data . dsize ) ;
} else {
d - > datalen = data . dsize ;
memcpy ( & d - > data [ key . dsize ] , data . dptr , data . dsize ) ;
}
2007-05-10 11:43:45 +04:00
return d ;
}
2008-07-30 13:58:17 +04:00
/* helper function for marshalling multiple records */
struct ctdb_marshall_buffer * ctdb_marshall_add ( TALLOC_CTX * mem_ctx ,
struct ctdb_marshall_buffer * m ,
uint64_t db_id ,
uint32_t reqid ,
TDB_DATA key ,
struct ctdb_ltdb_header * header ,
TDB_DATA data )
{
struct ctdb_rec_data * r ;
size_t m_size , r_size ;
struct ctdb_marshall_buffer * m2 ;
r = ctdb_marshall_record ( mem_ctx , reqid , key , header , data ) ;
if ( r = = NULL ) {
talloc_free ( m ) ;
return NULL ;
}
if ( m = = NULL ) {
m = talloc_zero_size ( mem_ctx , offsetof ( struct ctdb_marshall_buffer , data ) ) ;
if ( m = = NULL ) {
return NULL ;
}
m - > db_id = db_id ;
}
m_size = talloc_get_size ( m ) ;
r_size = talloc_get_size ( r ) ;
m2 = talloc_realloc_size ( mem_ctx , m , m_size + r_size ) ;
if ( m2 = = NULL ) {
talloc_free ( m ) ;
return NULL ;
}
memcpy ( m_size + ( uint8_t * ) m2 , r , r_size ) ;
talloc_free ( r ) ;
m2 - > count + + ;
return m2 ;
}
/* we've finished marshalling, return a data blob with the marshalled records */
TDB_DATA ctdb_marshall_finish ( struct ctdb_marshall_buffer * m )
{
TDB_DATA data ;
data . dptr = ( uint8_t * ) m ;
data . dsize = talloc_get_size ( m ) ;
return data ;
}
/*
loop over a marshalling buffer
- pass r = = NULL to start
- loop the number of times indicated by m - > count
*/
struct ctdb_rec_data * ctdb_marshall_loop_next ( struct ctdb_marshall_buffer * m , struct ctdb_rec_data * r ,
uint32_t * reqid ,
struct ctdb_ltdb_header * header ,
TDB_DATA * key , TDB_DATA * data )
{
if ( r = = NULL ) {
r = ( struct ctdb_rec_data * ) & m - > data [ 0 ] ;
} else {
r = ( struct ctdb_rec_data * ) ( r - > length + ( uint8_t * ) r ) ;
}
if ( reqid ! = NULL ) {
* reqid = r - > reqid ;
}
if ( key ! = NULL ) {
key - > dptr = & r - > data [ 0 ] ;
key - > dsize = r - > keylen ;
}
if ( data ! = NULL ) {
data - > dptr = & r - > data [ r - > keylen ] ;
data - > dsize = r - > datalen ;
if ( header ! = NULL ) {
data - > dptr + = sizeof ( * header ) ;
data - > dsize - = sizeof ( * header ) ;
}
}
if ( header ! = NULL ) {
if ( r - > datalen < sizeof ( * header ) ) {
return NULL ;
}
* header = * ( struct ctdb_ltdb_header * ) & r - > data [ r - > keylen ] ;
}
return r ;
}
2007-05-24 08:52:10 +04:00
/*
2009-12-16 11:56:22 +03:00
if possible , make this task very high priority
2007-05-24 08:52:10 +04:00
*/
2009-12-16 11:56:22 +03:00
void ctdb_high_priority ( struct ctdb_context * ctdb )
2007-05-24 08:52:10 +04:00
{
2009-12-16 11:56:22 +03:00
errno = 0 ;
if ( nice ( - 20 ) = = - 1 & & errno ! = 0 ) {
DEBUG ( DEBUG_WARNING , ( " Unable to renice self: %s \n " ,
strerror ( errno ) ) ) ;
2007-05-24 08:52:10 +04:00
} else {
2009-12-16 11:56:22 +03:00
DEBUG ( DEBUG_NOTICE , ( " Scheduler says I'm nice: %i \n " ,
getpriority ( PRIO_PROCESS , getpid ( ) ) ) ) ;
2007-05-24 08:52:10 +04:00
}
}
2007-05-30 09:43:25 +04:00
void set_nonblocking ( int fd )
{
unsigned v ;
v = fcntl ( fd , F_GETFL , 0 ) ;
fcntl ( fd , F_SETFL , v | O_NONBLOCK ) ;
}
void set_close_on_exec ( int fd )
{
unsigned v ;
v = fcntl ( fd , F_GETFD , 0 ) ;
fcntl ( fd , F_SETFD , v | FD_CLOEXEC ) ;
}
2007-07-04 10:51:13 +04:00
2008-10-14 03:40:29 +04:00
bool parse_ipv4 ( const char * s , unsigned port , struct sockaddr_in * sin )
2008-05-14 09:47:47 +04:00
{
2008-10-14 03:40:29 +04:00
sin - > sin_family = AF_INET ;
sin - > sin_port = htons ( port ) ;
2008-05-14 09:47:47 +04:00
2008-10-14 03:40:29 +04:00
if ( inet_pton ( AF_INET , s , & sin - > sin_addr ) ! = 1 ) {
2008-05-14 09:47:47 +04:00
DEBUG ( DEBUG_ERR , ( __location__ " Failed to translate %s into sin_addr \n " , s ) ) ;
return false ;
}
return true ;
}
2009-01-19 17:33:24 +03:00
static bool parse_ipv6 ( const char * s , const char * iface , unsigned port , ctdb_sock_addr * saddr )
2008-05-14 09:47:47 +04:00
{
saddr - > ip6 . sin6_family = AF_INET6 ;
saddr - > ip6 . sin6_port = htons ( port ) ;
saddr - > ip6 . sin6_flowinfo = 0 ;
saddr - > ip6 . sin6_scope_id = 0 ;
if ( inet_pton ( AF_INET6 , s , & saddr - > ip6 . sin6_addr ) ! = 1 ) {
DEBUG ( DEBUG_ERR , ( __location__ " Failed to translate %s into sin6_addr \n " , s ) ) ;
return false ;
}
2009-01-19 17:33:24 +03:00
if ( iface & & IN6_IS_ADDR_LINKLOCAL ( & saddr - > ip6 . sin6_addr ) ) {
saddr - > ip6 . sin6_scope_id = if_nametoindex ( iface ) ;
}
2008-05-14 09:47:47 +04:00
return true ;
}
2007-09-10 08:27:29 +04:00
/*
parse a ip : port pair
*/
2008-05-14 09:47:47 +04:00
bool parse_ip_port ( const char * addr , ctdb_sock_addr * saddr )
2007-09-10 08:27:29 +04:00
{
2008-05-14 09:47:47 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
char * s , * p ;
2007-09-10 08:27:29 +04:00
unsigned port ;
2008-05-14 09:47:47 +04:00
char * endp = NULL ;
bool ret ;
s = talloc_strdup ( tmp_ctx , addr ) ;
if ( s = = NULL ) {
DEBUG ( DEBUG_ERR , ( __location__ " Failed strdup() \n " ) ) ;
talloc_free ( tmp_ctx ) ;
2007-09-10 08:27:29 +04:00
return false ;
}
2008-05-14 09:47:47 +04:00
p = rindex ( s , ' : ' ) ;
if ( p = = NULL ) {
DEBUG ( DEBUG_ERR , ( __location__ " This addr: %s does not contain a port number \n " , s ) ) ;
talloc_free ( tmp_ctx ) ;
return false ;
}
port = strtoul ( p + 1 , & endp , 10 ) ;
if ( endp = = NULL | | * endp ! = 0 ) {
/* trailing garbage */
DEBUG ( DEBUG_ERR , ( __location__ " Trailing garbage after the port in %s \n " , s ) ) ;
talloc_free ( tmp_ctx ) ;
return false ;
}
* p = 0 ;
/* now is this a ipv4 or ipv6 address ?*/
2009-03-24 05:45:11 +03:00
ret = parse_ip ( s , NULL , port , saddr ) ;
2008-05-14 09:47:47 +04:00
talloc_free ( tmp_ctx ) ;
return ret ;
2007-09-10 08:27:29 +04:00
}
2008-06-04 09:13:00 +04:00
/*
parse an ip
*/
2009-03-24 05:45:11 +03:00
bool parse_ip ( const char * addr , const char * iface , unsigned port , ctdb_sock_addr * saddr )
2008-06-04 09:13:00 +04:00
{
char * p ;
bool ret ;
/* now is this a ipv4 or ipv6 address ?*/
p = index ( addr , ' : ' ) ;
if ( p = = NULL ) {
2009-03-24 05:45:11 +03:00
ret = parse_ipv4 ( addr , port , & saddr - > ip ) ;
2008-06-04 09:13:00 +04:00
} else {
2009-03-24 05:45:11 +03:00
ret = parse_ipv6 ( addr , iface , port , saddr ) ;
2008-06-04 09:13:00 +04:00
}
return ret ;
}
2007-09-10 08:27:29 +04:00
/*
parse a ip / mask pair
*/
2009-01-19 17:33:24 +03:00
bool parse_ip_mask ( const char * str , const char * iface , ctdb_sock_addr * addr , unsigned * mask )
2007-09-10 08:27:29 +04:00
{
2008-08-19 08:58:29 +04:00
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
char * s , * p ;
char * endp = NULL ;
bool ret ;
ZERO_STRUCT ( * addr ) ;
s = talloc_strdup ( tmp_ctx , str ) ;
if ( s = = NULL ) {
DEBUG ( DEBUG_ERR , ( __location__ " Failed strdup() \n " ) ) ;
talloc_free ( tmp_ctx ) ;
return false ;
}
2008-07-07 02:53:22 +04:00
2008-08-19 08:58:29 +04:00
p = rindex ( s , ' / ' ) ;
if ( p = = NULL ) {
DEBUG ( DEBUG_ERR , ( __location__ " This addr: %s does not contain a mask \n " , s ) ) ;
talloc_free ( tmp_ctx ) ;
2007-09-10 08:27:29 +04:00
return false ;
}
2008-08-19 08:58:29 +04:00
* mask = strtoul ( p + 1 , & endp , 10 ) ;
if ( endp = = NULL | | * endp ! = 0 ) {
/* trailing garbage */
DEBUG ( DEBUG_ERR , ( __location__ " Trailing garbage after the mask in %s \n " , s ) ) ;
talloc_free ( tmp_ctx ) ;
2007-09-10 08:27:29 +04:00
return false ;
}
2008-08-19 08:58:29 +04:00
* p = 0 ;
2007-09-10 08:27:29 +04:00
2008-08-19 08:58:29 +04:00
/* now is this a ipv4 or ipv6 address ?*/
2009-03-24 05:45:11 +03:00
ret = parse_ip ( s , iface , 0 , addr ) ;
2008-08-19 08:58:29 +04:00
talloc_free ( tmp_ctx ) ;
return ret ;
2007-09-10 08:27:29 +04:00
}
2008-08-20 05:52:36 +04:00
/*
This is used to canonicalize a ctdb_sock_addr structure .
*/
2008-08-20 05:58:27 +04:00
void ctdb_canonicalize_ip ( const ctdb_sock_addr * ip , ctdb_sock_addr * cip )
2008-06-04 11:12:57 +04:00
{
2008-08-20 05:52:36 +04:00
char prefix [ 12 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xff , 0xff } ;
memcpy ( cip , ip , sizeof ( * cip ) ) ;
if ( ( ip - > sa . sa_family = = AF_INET6 )
& & ! memcmp ( & ip - > ip6 . sin6_addr , prefix , 12 ) ) {
memset ( cip , 0 , sizeof ( * cip ) ) ;
# ifdef HAVE_SOCK_SIN_LEN
cip - > ip . sin_len = sizeof ( * cip ) ;
# endif
cip - > ip . sin_family = AF_INET ;
cip - > ip . sin_port = ip - > ip6 . sin6_port ;
memcpy ( & cip - > ip . sin_addr , & ip - > ip6 . sin6_addr . s6_addr32 [ 3 ] , 4 ) ;
}
}
bool ctdb_same_ip ( const ctdb_sock_addr * tip1 , const ctdb_sock_addr * tip2 )
{
ctdb_sock_addr ip1 , ip2 ;
2008-08-20 05:58:27 +04:00
ctdb_canonicalize_ip ( tip1 , & ip1 ) ;
ctdb_canonicalize_ip ( tip2 , & ip2 ) ;
2008-08-20 05:52:36 +04:00
if ( ip1 . sa . sa_family ! = ip2 . sa . sa_family ) {
2008-06-04 11:12:57 +04:00
return false ;
}
2008-08-20 05:52:36 +04:00
switch ( ip1 . sa . sa_family ) {
2008-06-04 11:12:57 +04:00
case AF_INET :
2008-08-20 05:52:36 +04:00
return ip1 . ip . sin_addr . s_addr = = ip2 . ip . sin_addr . s_addr ;
2008-06-04 11:12:57 +04:00
case AF_INET6 :
2008-08-20 05:52:36 +04:00
return ! memcmp ( & ip1 . ip6 . sin6_addr . s6_addr [ 0 ] ,
& ip2 . ip6 . sin6_addr . s6_addr [ 0 ] ,
2008-06-04 11:12:57 +04:00
16 ) ;
default :
2008-08-20 05:52:36 +04:00
DEBUG ( DEBUG_ERR , ( __location__ " CRITICAL Can not compare sockaddr structures of type %u \n " , ip1 . sa . sa_family ) ) ;
2008-06-04 11:12:57 +04:00
return false ;
}
return true ;
}
2007-09-10 08:27:29 +04:00
/*
2008-08-19 08:58:29 +04:00
compare two ctdb_sock_addr structures
2007-09-10 08:27:29 +04:00
*/
2008-08-19 08:58:29 +04:00
bool ctdb_same_sockaddr ( const ctdb_sock_addr * ip1 , const ctdb_sock_addr * ip2 )
2007-09-10 08:27:29 +04:00
{
2008-08-19 08:58:29 +04:00
return ctdb_same_ip ( ip1 , ip2 ) & & ip1 - > ip . sin_port = = ip2 - > ip . sin_port ;
2007-09-10 08:27:29 +04:00
}
2008-01-10 01:43:14 +03:00
2008-08-19 08:58:29 +04:00
char * ctdb_addr_to_str ( ctdb_sock_addr * addr )
{
static char cip [ 128 ] = " " ;
switch ( addr - > sa . sa_family ) {
case AF_INET :
inet_ntop ( addr - > ip . sin_family , & addr - > ip . sin_addr , cip , sizeof ( cip ) ) ;
break ;
case AF_INET6 :
inet_ntop ( addr - > ip6 . sin6_family , & addr - > ip6 . sin6_addr , cip , sizeof ( cip ) ) ;
break ;
default :
DEBUG ( DEBUG_ERR , ( __location__ " ERROR, unknown family %u \n " , addr - > sa . sa_family ) ) ;
}
return cip ;
}
2008-01-10 01:43:14 +03:00
2009-03-24 05:45:11 +03:00
unsigned ctdb_addr_to_port ( ctdb_sock_addr * addr )
{
switch ( addr - > sa . sa_family ) {
case AF_INET :
return ntohs ( addr - > ip . sin_port ) ;
break ;
case AF_INET6 :
return ntohs ( addr - > ip6 . sin6_port ) ;
break ;
default :
DEBUG ( DEBUG_ERR , ( __location__ " ERROR, unknown family %u \n " , addr - > sa . sa_family ) ) ;
}
return 0 ;
}
2008-01-10 01:43:14 +03:00
void ctdb_block_signal ( int signum )
{
sigset_t set ;
sigemptyset ( & set ) ;
sigaddset ( & set , signum ) ;
sigprocmask ( SIG_BLOCK , & set , NULL ) ;
}
void ctdb_unblock_signal ( int signum )
{
sigset_t set ;
sigemptyset ( & set ) ;
sigaddset ( & set , signum ) ;
sigprocmask ( SIG_UNBLOCK , & set , NULL ) ;
}
2009-07-01 03:17:13 +04:00
struct debug_levels debug_levels [ ] = {
{ DEBUG_EMERG , " EMERG " } ,
{ DEBUG_ALERT , " ALERT " } ,
{ DEBUG_CRIT , " CRIT " } ,
{ DEBUG_ERR , " ERR " } ,
{ DEBUG_WARNING , " WARNING " } ,
{ DEBUG_NOTICE , " NOTICE " } ,
{ DEBUG_INFO , " INFO " } ,
{ DEBUG_DEBUG , " DEBUG " } ,
{ 0 , NULL }
} ;
const char * get_debug_by_level ( int32_t level )
{
int i ;
for ( i = 0 ; debug_levels [ i ] . description ! = NULL ; i + + ) {
if ( debug_levels [ i ] . level = = level ) {
return debug_levels [ i ] . description ;
}
}
return " Unknown " ;
}
int32_t get_debug_by_desc ( const char * desc )
{
int i ;
for ( i = 0 ; debug_levels [ i ] . description ! = NULL ; i + + ) {
if ( ! strcmp ( debug_levels [ i ] . description , desc ) ) {
return debug_levels [ i ] . level ;
}
}
return DEBUG_ERR ;
}
2009-12-07 18:17:13 +03:00
const char * ctdb_eventscript_call_names [ ] = {
" startup " ,
" startrecovery " ,
" recovered " ,
" takeip " ,
" releaseip " ,
" stopped " ,
" monitor " ,
" status " ,
" shutdown " ,
" reload "
} ;