2007-04-11 18:54:22 +10:00
/*
standalone ctdb daemon
Copyright ( C ) Andrew Tridgell 2006
2007-05-31 13:50:53 +10: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 15:29:31 +10:00
the Free Software Foundation ; either version 3 of the License , or
2007-05-31 13:50:53 +10:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
2007-04-11 18:54:22 +10:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2007-05-31 13:50:53 +10: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 15:29:31 +10:00
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-04-11 18:54:22 +10:00
*/
# include "includes.h"
# include "system/filesys.h"
# include "popt.h"
2008-01-17 11:33:23 +11:00
# include "system/time.h"
2007-04-11 22:19:46 +10:00
# include "system/wait.h"
2007-10-16 11:29:33 +10:00
# include "system/network.h"
2007-04-17 22:16:50 +10:00
# include "cmdline.h"
2007-04-29 22:42:23 +02:00
# include "../include/ctdb_private.h"
2007-04-11 13:17:36 +02:00
2007-05-29 12:49:25 +10:00
static struct {
2007-06-02 10:03:28 +10:00
const char * nlist ;
const char * transport ;
const char * myaddress ;
2007-05-29 12:49:25 +10:00
const char * public_address_list ;
2007-08-15 14:44:03 +10:00
const char * event_script_dir ;
2009-03-31 14:23:31 +11:00
const char * notification_script ;
2007-05-29 15:26:38 +10:00
const char * logfile ;
2007-06-02 10:03:28 +10:00
const char * recovery_lock_file ;
const char * db_dir ;
2007-09-21 12:24:02 +10:00
const char * db_dir_persistent ;
2009-11-23 14:38:03 +01:00
const char * db_dir_state ;
2007-09-10 14:26:35 +10:00
const char * public_interface ;
2007-10-10 09:42:32 +10:00
const char * single_public_ip ;
2009-12-16 20:59:15 +10:30
int valgrinding ;
2011-01-24 11:42:50 +11:00
int nosetsched ;
2008-01-16 22:03:01 +11:00
int use_syslog ;
2008-02-22 09:42:52 +11:00
int start_as_disabled ;
2009-07-09 11:57:20 +10:00
int start_as_stopped ;
2008-05-06 10:41:22 +10:00
int no_lmaster ;
int no_recmaster ;
2008-07-10 10:37:22 +10:00
int lvs ;
2008-10-17 07:56:12 +11:00
int script_log_level ;
2008-11-24 19:06:02 +11:00
int no_publicipcheck ;
2009-12-07 13:28:11 +01:00
int max_persistent_check_errors ;
2007-05-29 12:49:25 +10:00
} options = {
2013-10-21 19:33:10 +11:00
. nlist = NULL ,
2007-06-02 10:03:28 +10:00
. transport = " tcp " ,
2013-10-15 14:10:58 +11:00
. event_script_dir = NULL ,
2009-02-04 00:15:57 +01:00
. logfile = LOGDIR " /log.ctdb " ,
2007-06-02 10:03:28 +10:00
. db_dir = VARDIR " /ctdb " ,
2007-09-21 12:24:02 +10:00
. db_dir_persistent = VARDIR " /ctdb/persistent " ,
2009-11-23 14:38:03 +01:00
. db_dir_state = VARDIR " /ctdb/state " ,
2008-10-17 07:56:12 +11:00
. script_log_level = DEBUG_ERR ,
2007-05-29 12:49:25 +10:00
} ;
2008-10-17 07:56:12 +11:00
int script_log_level ;
2010-06-22 22:52:34 +09:30
bool fast_start ;
2007-04-11 18:54:22 +10:00
2007-06-07 22:06:19 +10:00
/*
called by the transport layer when a packet comes in
*/
static void ctdb_recv_pkt ( struct ctdb_context * ctdb , uint8_t * data , uint32_t length )
{
struct ctdb_req_header * hdr = ( struct ctdb_req_header * ) data ;
2010-09-29 10:38:41 +10:00
CTDB_INCREMENT_STAT ( ctdb , node_packets_recv ) ;
2007-06-07 22:06:19 +10:00
/* up the counter for this source node, so we know its alive */
2007-09-04 10:09:58 +10:00
if ( ctdb_validate_pnn ( ctdb , hdr - > srcnode ) ) {
2007-06-07 22:06:19 +10:00
/* as a special case, redirected calls don't increment the rx_cnt */
if ( hdr - > operation ! = CTDB_REQ_CALL | |
( ( struct ctdb_req_call * ) hdr ) - > hopcount = = 0 ) {
ctdb - > nodes [ hdr - > srcnode ] - > rx_cnt + + ;
}
}
ctdb_input_pkt ( ctdb , hdr ) ;
}
static const struct ctdb_upcalls ctdb_upcalls = {
. recv_pkt = ctdb_recv_pkt ,
. node_dead = ctdb_node_dead ,
. node_connected = ctdb_node_connected
} ;
2007-05-29 15:26:38 +10:00
2007-04-11 18:54:22 +10:00
/*
main program
*/
int main ( int argc , const char * argv [ ] )
{
struct ctdb_context * ctdb ;
2007-05-15 09:44:33 +10:00
int interactive = 0 ;
2007-04-11 18:54:22 +10:00
struct poptOption popt_options [ ] = {
POPT_AUTOHELP
2007-04-17 22:13:06 +10:00
POPT_CTDB_CMDLINE
2007-05-15 09:44:33 +10:00
{ " interactive " , ' i ' , POPT_ARG_NONE , & interactive , 0 , " don't fork " , NULL } ,
2007-05-29 12:49:25 +10:00
{ " public-addresses " , 0 , POPT_ARG_STRING , & options . public_address_list , 0 , " public address list file " , " filename " } ,
2007-09-10 14:26:35 +10:00
{ " public-interface " , 0 , POPT_ARG_STRING , & options . public_interface , 0 , " public interface " , " interface " } ,
2007-10-10 09:42:32 +10:00
{ " single-public-ip " , 0 , POPT_ARG_STRING , & options . single_public_ip , 0 , " single public ip " , " ip-address " } ,
2007-08-15 14:44:03 +10:00
{ " event-script-dir " , 0 , POPT_ARG_STRING , & options . event_script_dir , 0 , " event script directory " , " dirname " } ,
2007-05-29 15:26:38 +10:00
{ " logfile " , 0 , POPT_ARG_STRING , & options . logfile , 0 , " log file location " , " filename " } ,
2007-06-02 10:03:28 +10:00
{ " nlist " , 0 , POPT_ARG_STRING , & options . nlist , 0 , " node list file " , " filename " } ,
2009-03-31 14:23:31 +11:00
{ " notification-script " , 0 , POPT_ARG_STRING , & options . notification_script , 0 , " notification script " , " filename " } ,
2007-06-02 10:03:28 +10:00
{ " listen " , 0 , POPT_ARG_STRING , & options . myaddress , 0 , " address to listen on " , " address " } ,
{ " transport " , 0 , POPT_ARG_STRING , & options . transport , 0 , " protocol transport " , NULL } ,
{ " dbdir " , 0 , POPT_ARG_STRING , & options . db_dir , 0 , " directory for the tdb files " , NULL } ,
2007-09-21 12:24:02 +10:00
{ " dbdir-persistent " , 0 , POPT_ARG_STRING , & options . db_dir_persistent , 0 , " directory for persistent tdb files " , NULL } ,
2009-11-23 14:38:03 +01:00
{ " dbdir-state " , 0 , POPT_ARG_STRING , & options . db_dir_state , 0 , " directory for internal state tdb files " , NULL } ,
2007-06-02 11:36:42 +10:00
{ " reclock " , 0 , POPT_ARG_STRING , & options . recovery_lock_file , 0 , " location of recovery lock file " , " filename " } ,
2013-04-15 13:32:57 +10:00
{ " pidfile " , 0 , POPT_ARG_STRING , & ctdbd_pidfile , 0 , " location of PID file " , " filename " } ,
2011-01-10 13:35:39 +11:00
{ " valgrinding " , 0 , POPT_ARG_NONE , & options . valgrinding , 0 , " disable setscheduler SCHED_FIFO call, use mmap for tdbs " , NULL } ,
2011-01-24 11:42:50 +11:00
{ " nosetsched " , 0 , POPT_ARG_NONE , & options . nosetsched , 0 , " disable setscheduler SCHED_FIFO call, use mmap for tdbs " , NULL } ,
2008-01-16 22:03:01 +11:00
{ " syslog " , 0 , POPT_ARG_NONE , & options . use_syslog , 0 , " log messages to syslog " , NULL } ,
2008-02-22 09:42:52 +11:00
{ " start-as-disabled " , 0 , POPT_ARG_NONE , & options . start_as_disabled , 0 , " Node starts in disabled state " , NULL } ,
2009-07-09 11:57:20 +10:00
{ " start-as-stopped " , 0 , POPT_ARG_NONE , & options . start_as_stopped , 0 , " Node starts in stopped state " , NULL } ,
2008-05-06 10:41:22 +10:00
{ " no-lmaster " , 0 , POPT_ARG_NONE , & options . no_lmaster , 0 , " disable lmaster role on this node " , NULL } ,
{ " no-recmaster " , 0 , POPT_ARG_NONE , & options . no_recmaster , 0 , " disable recmaster role on this node " , NULL } ,
2008-07-10 10:37:22 +10:00
{ " lvs " , 0 , POPT_ARG_NONE , & options . lvs , 0 , " lvs is enabled on this node " , NULL } ,
2013-10-21 19:42:32 +11:00
{ " script-log-level " , 0 , POPT_ARG_INT , & options . script_log_level , 0 , " log level of event script output " , NULL } ,
2010-01-05 11:04:24 +01:00
{ " nopublicipcheck " , 0 , POPT_ARG_NONE , & options . no_publicipcheck , 0 , " don't check we have/don't have the correct public ip addresses " , NULL } ,
2009-12-07 13:28:11 +01:00
{ " max-persistent-check-errors " , 0 , POPT_ARG_INT ,
& options . max_persistent_check_errors , 0 ,
" max allowed persistent check errors (default 0) " , NULL } ,
2013-10-21 19:42:32 +11:00
{ " log-ringbuf-size " , 0 , POPT_ARG_INT , & log_ringbuf_size , 0 , " Number of log messages we can store in the memory ringbuffer " , NULL } ,
2010-06-22 22:52:34 +09:30
{ " sloppy-start " , 0 , POPT_ARG_NONE , & fast_start , 0 , " Do not perform full recovery on start " , NULL } ,
2007-04-11 18:54:22 +10:00
POPT_TABLEEND
} ;
2007-05-29 12:49:25 +10:00
int opt , ret ;
2007-04-11 18:54:22 +10:00
const char * * extra_argv ;
int extra_argc = 0 ;
poptContext pc ;
struct event_context * ev ;
pc = poptGetContext ( argv [ 0 ] , argc , argv , popt_options , POPT_CONTEXT_KEEP_FIRST ) ;
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
default :
fprintf ( stderr , " Invalid option %s: %s \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
exit ( 1 ) ;
}
}
/* setup the remaining options for the main program to use */
extra_argv = poptGetArgs ( pc ) ;
if ( extra_argv ) {
extra_argv + + ;
while ( extra_argv [ extra_argc ] ) extra_argc + + ;
}
2008-01-16 09:44:48 +11:00
talloc_enable_null_tracking ( ) ;
2008-01-10 09:43:14 +11:00
ctdb_block_signal ( SIGPIPE ) ;
2010-01-07 09:21:56 +01:00
fault_setup ( " ctdbd " ) ;
2007-04-11 13:17:36 +02:00
2007-04-11 18:54:22 +10:00
ev = event_context_init ( NULL ) ;
2010-08-18 10:11:59 +10:00
tevent_loop_allow_nesting ( ev ) ;
2007-04-11 18:54:22 +10:00
2007-04-17 22:13:06 +10:00
ctdb = ctdb_cmdline_init ( ev ) ;
2007-04-11 18:54:22 +10:00
2008-02-22 09:42:52 +11:00
ctdb - > start_as_disabled = options . start_as_disabled ;
2009-07-09 11:57:20 +10:00
ctdb - > start_as_stopped = options . start_as_stopped ;
2008-02-22 09:42:52 +11:00
2008-10-17 07:56:12 +11:00
script_log_level = options . script_log_level ;
2008-01-16 22:03:01 +11:00
ret = ctdb_set_logfile ( ctdb , options . logfile , options . use_syslog ) ;
2007-08-21 09:33:03 +10:00
if ( ret = = - 1 ) {
2008-01-16 22:03:01 +11:00
printf ( " ctdb_set_logfile to %s failed - %s \n " ,
options . use_syslog ? " syslog " : options . logfile , ctdb_errstr ( ctdb ) ) ;
2007-08-21 09:33:03 +10:00
exit ( 1 ) ;
}
2011-08-04 13:44:25 +10:00
DEBUG ( DEBUG_NOTICE , ( " CTDB starting on node \n " ) ) ;
2010-09-22 10:59:01 +10:00
2008-01-17 11:33:23 +11:00
gettimeofday ( & ctdb - > ctdbd_start_time , NULL ) ;
2008-07-02 13:55:59 +10:00
gettimeofday ( & ctdb - > last_recovery_started , NULL ) ;
gettimeofday ( & ctdb - > last_recovery_finished , NULL ) ;
2007-06-07 22:06:19 +10:00
ctdb - > recovery_mode = CTDB_RECOVERY_NORMAL ;
ctdb - > recovery_master = ( uint32_t ) - 1 ;
ctdb - > upcalls = & ctdb_upcalls ;
ctdb - > idr = idr_init ( ctdb ) ;
ctdb - > recovery_lock_fd = - 1 ;
ctdb_tunables_set_defaults ( ctdb ) ;
2007-06-02 11:36:42 +10:00
ret = ctdb_set_recovery_lock_file ( ctdb , options . recovery_lock_file ) ;
if ( ret = = - 1 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " ctdb_set_recovery_lock_file failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
2007-06-02 11:36:42 +10:00
exit ( 1 ) ;
}
2007-06-02 10:03:28 +10:00
ret = ctdb_set_transport ( ctdb , options . transport ) ;
if ( ret = = - 1 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " ctdb_set_transport failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
2007-06-02 10:03:28 +10:00
exit ( 1 ) ;
}
/* tell ctdb what address to listen on */
if ( options . myaddress ) {
ret = ctdb_set_address ( ctdb , options . myaddress ) ;
if ( ret = = - 1 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " ctdb_set_address failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
2007-06-02 10:03:28 +10:00
exit ( 1 ) ;
}
}
2008-05-06 10:02:27 +10:00
/* set ctdbd capabilities */
2008-05-06 10:41:22 +10:00
ctdb - > capabilities = 0 ;
if ( options . no_lmaster = = 0 ) {
ctdb - > capabilities | = CTDB_CAP_LMASTER ;
}
if ( options . no_recmaster = = 0 ) {
ctdb - > capabilities | = CTDB_CAP_RECMASTER ;
}
2008-07-10 10:37:22 +10:00
if ( options . lvs ! = 0 ) {
ctdb - > capabilities | = CTDB_CAP_LVS ;
}
2008-05-06 10:02:27 +10:00
2012-12-04 14:28:06 +11:00
/* Initialise this node's PNN to the unknown value. This will
* be set to the correct value by either ctdb_add_node ( ) as
* part of loading the nodes file or by
* ctdb_tcp_listen_automatic ( ) when the transport is
* initialised . At some point we should de - optimise this and
* pull it out into ctdb_start_daemon ( ) so it is done clearly
* and only in one place .
*/
ctdb - > pnn = - 1 ;
2013-10-21 19:33:10 +11:00
/* Default value for CTDB_BASE - don't override */
setenv ( " CTDB_BASE " , ETCDIR " /ctdb " , 0 ) ;
2007-06-02 10:03:28 +10:00
/* tell ctdb what nodes are available */
2013-10-21 19:33:10 +11:00
if ( options . nlist ! = NULL ) {
ctdb - > nodes_file = options . nlist ;
} else {
ctdb - > nodes_file =
talloc_asprintf ( ctdb , " %s/nodes " , getenv ( " CTDB_BASE " ) ) ;
if ( ctdb - > nodes_file = = NULL ) {
DEBUG ( DEBUG_ALERT , ( __location__ " Out of memory \n " ) ) ;
exit ( 1 ) ;
}
}
2008-02-19 14:44:48 +11:00
ctdb_load_nodes_file ( ctdb ) ;
2007-06-02 10:03:28 +10:00
if ( options . db_dir ) {
ret = ctdb_set_tdb_dir ( ctdb , options . db_dir ) ;
if ( ret = = - 1 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " ctdb_set_tdb_dir failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
2007-06-02 10:03:28 +10:00
exit ( 1 ) ;
}
}
2007-09-21 12:24:02 +10:00
if ( options . db_dir_persistent ) {
ret = ctdb_set_tdb_dir_persistent ( ctdb , options . db_dir_persistent ) ;
if ( ret = = - 1 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " ctdb_set_tdb_dir_persistent failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
2007-09-21 12:24:02 +10:00
exit ( 1 ) ;
}
}
2009-11-23 14:38:03 +01:00
if ( options . db_dir_state ) {
ret = ctdb_set_tdb_dir_state ( ctdb , options . db_dir_state ) ;
if ( ret = = - 1 ) {
DEBUG ( DEBUG_ALERT , ( " ctdb_set_tdb_dir_state failed - %s \n " , ctdb_errstr ( ctdb ) ) ) ;
exit ( 1 ) ;
}
}
2007-06-02 10:03:28 +10:00
2007-09-10 14:26:35 +10:00
if ( options . public_interface ) {
ctdb - > default_public_interface = talloc_strdup ( ctdb , options . public_interface ) ;
CTDB_NO_MEMORY ( ctdb , ctdb - > default_public_interface ) ;
}
2007-10-10 09:42:32 +10:00
if ( options . single_public_ip ) {
if ( options . public_interface = = NULL ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " --single_public_ip used but --public_interface is not specified. You must specify the public interface when using single public ip. Exiting \n " ) ) ;
2007-10-10 09:42:32 +10:00
exit ( 10 ) ;
}
2009-12-14 19:33:35 +01:00
ret = ctdb_set_single_public_ip ( ctdb , options . public_interface ,
options . single_public_ip ) ;
if ( ret ! = 0 ) {
2008-02-04 20:07:15 +11:00
DEBUG ( DEBUG_ALERT , ( " Invalid --single-public-ip argument : %s . This is not a valid ip address. Exiting. \n " , options . single_public_ip ) ) ;
2007-10-10 09:42:32 +10:00
exit ( 10 ) ;
}
}
2013-10-15 14:10:58 +11:00
if ( options . event_script_dir ! = NULL ) {
ctdb - > event_script_dir = options . event_script_dir ;
} else {
ctdb - > event_script_dir = talloc_asprintf ( ctdb , " %s/events.d " ,
getenv ( " CTDB_BASE " ) ) ;
if ( ctdb - > event_script_dir = = NULL ) {
DEBUG ( DEBUG_ALERT , ( __location__ " Out of memory \n " ) ) ;
exit ( 1 ) ;
}
2007-08-15 14:44:03 +10:00
}
2009-03-31 14:23:31 +11:00
if ( options . notification_script ! = NULL ) {
ret = ctdb_set_notification_script ( ctdb , options . notification_script ) ;
if ( ret = = - 1 ) {
DEBUG ( DEBUG_ALERT , ( " Unable to setup notification script \n " ) ) ;
exit ( 1 ) ;
}
}
2009-12-16 20:59:15 +10:30
ctdb - > valgrinding = options . valgrinding ;
2011-01-24 11:42:50 +11:00
if ( options . valgrinding | | options . nosetsched ) {
ctdb - > do_setsched = 0 ;
} else {
ctdb - > do_setsched = 1 ;
}
2007-07-13 08:47:02 +10:00
2012-03-22 15:27:25 +11:00
ctdb - > do_checkpublicip = ! options . no_publicipcheck ;
2009-12-07 13:28:11 +01:00
if ( options . max_persistent_check_errors < 0 ) {
ctdb - > max_persistent_check_errors = 0xFFFFFFFFFFFFFFFFLL ;
} else {
ctdb - > max_persistent_check_errors = ( uint64_t ) options . max_persistent_check_errors ;
}
2007-04-29 16:19:40 +02:00
/* start the protocol running (as a child) */
2012-05-17 16:08:37 +10:00
return ctdb_start_daemon ( ctdb , interactive ? false : true , options . use_syslog , options . public_address_list ) ;
2007-04-11 18:54:22 +10:00
}