19 #include <ndb_global.h>
30 #include <kernel/NodeBitmask.hpp>
35 static int _no_contact = 0;
36 static int _not_started = 0;
37 static int _single_user = 0;
38 static int _timeout = 120;
39 static const char* _wait_nodes = 0;
40 static const char* _nowait_nodes = 0;
43 const char *load_default_groups[]= {
"mysql_cluster",0 };
45 static struct my_option my_long_options[] =
47 NDB_STD_OPTS(
"ndb_waiter"),
48 {
"no-contact",
'n',
"Wait for cluster no contact",
49 (uchar**) &_no_contact, (uchar**) &_no_contact, 0,
50 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
51 {
"not-started", NDB_OPT_NOSHORT,
"Wait for cluster not started",
52 (uchar**) &_not_started, (uchar**) &_not_started, 0,
53 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
54 {
"single-user", NDB_OPT_NOSHORT,
55 "Wait for cluster to enter single user mode",
56 (uchar**) &_single_user, (uchar**) &_single_user, 0,
57 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
58 {
"timeout",
't',
"Timeout to wait in seconds",
59 (uchar**) &_timeout, (uchar**) &_timeout, 0,
60 GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
61 {
"wait-nodes",
'w',
"Node ids to wait on, e.g. '1,2-4'",
62 (uchar**) &_wait_nodes, (uchar**) &_wait_nodes, 0,
63 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
64 {
"nowait-nodes", NDB_OPT_NOSHORT,
65 "Nodes that will not be waited for, e.g. '2,3,4-7'",
66 (uchar**) &_nowait_nodes, (uchar**) &_nowait_nodes, 0,
67 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
68 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
71 static void short_usage_sub(
void)
73 ndb_short_usage_sub(NULL);
78 ndb_usage(short_usage_sub, load_default_groups, my_long_options);
82 void catch_signal(
int signum)
86 #include "../src/common/util/parse_mask.hpp"
88 int main(
int argc,
char** argv){
90 ndb_opt_set_usage_funcs(short_usage_sub, usage);
91 load_defaults(
"my",load_default_groups,&argc,&argv);
94 opt_debug=
"d:t:O,/tmp/ndb_waiter.trace";
100 signal(SIGUSR1, catch_signal);
103 if (handle_options(&argc, &argv, my_long_options,
104 ndb_std_get_one_option))
105 return NDBT_ProgramExit(NDBT_WRONGARGS);
107 const char* connect_string = argv[0];
108 if (connect_string == 0)
109 connect_string = opt_ndb_connectstring;
116 else if (_not_started)
120 else if (_single_user)
131 int res = parse_mask(_nowait_nodes, nowait_nodes_bitmask);
132 if(res == -2 || (res > 0 && nowait_nodes_bitmask.
get(0)))
134 ndbout_c(
"Invalid nodeid specified in nowait-nodes: %s",
140 ndbout_c(
"Unable to parse nowait-nodes argument: %s",
150 ndbout_c(
"Can not set both wait-nodes and nowait-nodes.");
154 int res = parse_mask(_wait_nodes, nowait_nodes_bitmask);
155 if (res == -2 || (res > 0 && nowait_nodes_bitmask.
get(0)))
157 ndbout_c(
"Invalid nodeid specified in wait-nodes: %s",
163 ndbout_c(
"Unable to parse wait-nodes argument: %s",
169 nowait_nodes_bitmask.
bitNOT();
172 if (waitClusterStatus(connect_string, wait_status) != 0)
173 return NDBT_ProgramExit(NDBT_FAILED);
174 return NDBT_ProgramExit(NDBT_OK);
178 ndbout << "latest_error="<<ndb_mgm_get_latest_error(h) \
179 << ", line="<<ndb_mgm_get_latest_error_line(h) \
197 ndbout <<
"status==NULL, retries="<<retries<<endl;
203 g_err <<
"Reconnect failed" << endl;
209 for (
int i = 0;
i < count;
i++){
214 ndbNodes.push_back(*node);
231 ndbout <<
"kalle"<< endl;
239 ndbout <<
"status == 0" << endl;
250 getTimeAsString(
char* pStr)
253 now= ::time((time_t*)NULL);
257 tm_now = localtime(&now);
259 tm_now = ::localtime(&now);
272 waitClusterStatus(
const char* _addr,
275 int _startphase = -1;
279 signal(SIGPIPE, SIG_IGN);
284 g_err <<
"Could not create ndb_mgm handle" << endl;
287 g_info <<
"Connecting to mgmsrv at " << _addr << endl;
291 g_err <<
"Connectstring " << _addr <<
" invalid" << endl;
296 g_err <<
"Connection to " << _addr <<
" failed" << endl;
301 int resetAttempts = 0;
302 const int MAX_RESET_ATTEMPTS = 10;
303 bool allInState =
false;
305 Uint64 time_now = NdbTick_CurrentMillisecond();
306 Uint64 timeout_time = time_now + 1000 * _timeout;
308 while (allInState ==
false){
309 if (_timeout > 0 && time_now > timeout_time){
314 bool waitMore =
false;
325 for (
size_t n = 0;
n < ndbNodes.size();
n++){
333 if (!waitMore || resetAttempts > MAX_RESET_ATTEMPTS){
334 g_err <<
"waitNodeState("
336 <<
", "<<_startphase<<
")"
337 <<
" timeout after " << attempts <<
" attempts" << endl;
341 g_err <<
"waitNodeState("
343 <<
", "<<_startphase<<
")"
344 <<
" resetting timeout "
345 << resetAttempts << endl;
347 timeout_time = time_now + 1000 * _timeout;
353 NdbSleep_MilliSleep(100);
354 if (getStatus() != 0){
359 allInState = (ndbNodes.size() > 0);
362 for (
size_t n = 0;
n < ndbNodes.size();
n++) {
365 assert(ndbNode != NULL);
367 g_info <<
"Node " << ndbNode->
node_id <<
": "
376 g_info <<
"[" << getTimeAsString(time) <<
"] "
377 <<
"Waiting for cluster enter state "
383 time_now = NdbTick_CurrentMillisecond();