1 /* Copyright (c) 2003-2008 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 #include <ndb_global.h>
28 waitClusterStatus(const char* _addr
, ndb_mgm_node_status _status
);
30 enum ndb_waiter_options
{
31 OPT_WAIT_STATUS_NOT_STARTED
= NDB_STD_OPTIONS_LAST
,
32 OPT_WAIT_STATUS_SINGLE_USER
36 static int _no_contact
= 0;
37 static int _not_started
= 0;
38 static int _single_user
= 0;
39 static int _timeout
= 120;
41 const char *load_default_groups
[]= { "mysql_cluster",0 };
43 static struct my_option my_long_options
[] =
45 NDB_STD_OPTS("ndb_desc"),
46 { "no-contact", 'n', "Wait for cluster no contact",
47 (uchar
**) &_no_contact
, (uchar
**) &_no_contact
, 0,
48 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
49 { "not-started", OPT_WAIT_STATUS_NOT_STARTED
, "Wait for cluster not started",
50 (uchar
**) &_not_started
, (uchar
**) &_not_started
, 0,
51 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
52 { "single-user", OPT_WAIT_STATUS_SINGLE_USER
,
53 "Wait for cluster to enter single user mode",
54 (uchar
**) &_single_user
, (uchar
**) &_single_user
, 0,
55 GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
56 { "timeout", 't', "Timeout to wait in seconds",
57 (uchar
**) &_timeout
, (uchar
**) &_timeout
, 0,
58 GET_INT
, REQUIRED_ARG
, 120, 0, 0, 0, 0, 0 },
59 { 0, 0, 0, 0, 0, 0, GET_NO_ARG
, NO_ARG
, 0, 0, 0, 0, 0, 0}
65 ndb_std_print_version();
66 print_defaults(MYSQL_CONFIG_NAME
,load_default_groups
);
68 my_print_help(my_long_options
);
69 my_print_variables(my_long_options
);
73 int main(int argc
, char** argv
){
75 load_defaults("my",load_default_groups
,&argc
,&argv
);
76 const char* _hostName
= NULL
;
79 opt_debug
= "d:t:O,/tmp/ndb_waiter.trace";
82 if (handle_options(&argc
, &argv
, my_long_options
,
83 ndb_std_get_one_option
))
84 return NDBT_ProgramExit(NDBT_WRONGARGS
);
89 _hostName
= opt_connect_str
;
91 enum ndb_mgm_node_status wait_status
;
94 wait_status
= NDB_MGM_NODE_STATUS_NO_CONTACT
;
96 else if (_not_started
)
98 wait_status
= NDB_MGM_NODE_STATUS_NOT_STARTED
;
100 else if (_single_user
)
102 wait_status
= NDB_MGM_NODE_STATUS_SINGLEUSER
;
106 wait_status
= NDB_MGM_NODE_STATUS_STARTED
;
109 if (waitClusterStatus(_hostName
, wait_status
) != 0)
110 return NDBT_ProgramExit(NDBT_FAILED
);
111 return NDBT_ProgramExit(NDBT_OK
);
115 ndbout << "latest_error="<<ndb_mgm_get_latest_error(h) \
116 << ", line="<<ndb_mgm_get_latest_error_line(h) \
119 NdbMgmHandle handle
= NULL
;
121 Vector
<ndb_mgm_node_state
> ndbNodes
;
126 struct ndb_mgm_cluster_state
* status
;
127 struct ndb_mgm_node_state
* node
;
132 status
= ndb_mgm_get_status(handle
);
134 ndbout
<< "status==NULL, retries="<<retries
<<endl
;
137 ndb_mgm_disconnect(handle
);
138 if (ndb_mgm_connect(handle
,0,0,1)) {
140 g_err
<< "Reconnect failed" << endl
;
145 int count
= status
->no_of_nodes
;
146 for (int i
= 0; i
< count
; i
++){
147 node
= &status
->node_states
[i
];
148 switch(node
->node_type
){
149 case NDB_MGM_NODE_TYPE_NDB
:
150 ndbNodes
.push_back(*node
);
152 case NDB_MGM_NODE_TYPE_MGM
:
153 /* Don't care about MGM nodes */
155 case NDB_MGM_NODE_TYPE_API
:
156 /* Don't care about API nodes */
159 if(node
->node_status
== NDB_MGM_NODE_STATUS_UNKNOWN
||
160 node
->node_status
== NDB_MGM_NODE_STATUS_NO_CONTACT
){
167 ndbout
<< "kalle"<< endl
;
175 ndbout
<< "status == 0" << endl
;
186 waitClusterStatus(const char* _addr
,
187 ndb_mgm_node_status _status
)
189 int _startphase
= -1;
192 signal(SIGPIPE
, SIG_IGN
);
194 handle
= ndb_mgm_create_handle();
196 g_err
<< "Could not create ndb_mgm handle" << endl
;
199 g_info
<< "Connecting to mgmsrv at " << _addr
<< endl
;
200 if (ndb_mgm_set_connectstring(handle
, _addr
))
203 g_err
<< "Connectstring " << _addr
<< " invalid" << endl
;
206 if (ndb_mgm_connect(handle
,0,0,1)) {
208 g_err
<< "Connection to " << _addr
<< " failed" << endl
;
213 int resetAttempts
= 0;
214 const int MAX_RESET_ATTEMPTS
= 10;
215 bool allInState
= false;
216 int timeout_ms
= _timeout
* 10; /* In number of 100 milliseconds */
217 while (allInState
== false){
218 if (_timeout
> 0 && attempts
> _timeout
){
220 * Timeout has expired waiting for the nodes to enter
223 bool waitMore
= false;
225 * Make special check if we are waiting for
226 * cluster to become started
228 if(_status
== NDB_MGM_NODE_STATUS_STARTED
){
231 * First check if any node is not starting
232 * then it's no idea to wait anymore
234 for (size_t n
= 0; n
< ndbNodes
.size(); n
++){
235 if (ndbNodes
[n
].node_status
!= NDB_MGM_NODE_STATUS_STARTED
&&
236 ndbNodes
[n
].node_status
!= NDB_MGM_NODE_STATUS_STARTING
)
242 if (!waitMore
|| resetAttempts
> MAX_RESET_ATTEMPTS
){
243 g_err
<< "waitNodeState("
244 << ndb_mgm_get_node_status_string(_status
)
245 <<", "<<_startphase
<<")"
246 << " timeout after " << attempts
<<" attemps" << endl
;
250 g_err
<< "waitNodeState("
251 << ndb_mgm_get_node_status_string(_status
)
252 <<", "<<_startphase
<<")"
253 << " resetting number of attempts "
254 << resetAttempts
<< endl
;
259 if (getStatus() != 0){
263 /* Assume all nodes are in state(if there is any) */
264 allInState
= (ndbNodes
.size() > 0);
266 /* Loop through all nodes and check their state */
267 for (size_t n
= 0; n
< ndbNodes
.size(); n
++) {
268 ndb_mgm_node_state
* ndbNode
= &ndbNodes
[n
];
270 assert(ndbNode
!= NULL
);
272 g_info
<< "Node " << ndbNode
->node_id
<< ": "
273 << ndb_mgm_get_node_status_string(ndbNode
->node_status
)<< endl
;
275 if (ndbNode
->node_status
!= _status
)
280 g_info
<< "Waiting for cluster enter state "
281 << ndb_mgm_get_node_status_string(_status
)<< endl
;
282 NdbSleep_MilliSleep(100);
290 template class Vector
<ndb_mgm_node_state
>;