1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <ndb_global.h>
26 #include <ndb_opts.h>
27 #include <kernel/NodeBitmask.hpp>
28 #include <portlib/ndb_daemon.h>
29
30 #include "ndbd.hpp"
31 #include "angel.hpp"
32
33 #include <EventLogger.hpp>
34 extern EventLogger * g_eventLogger;
35
36 static int opt_daemon, opt_no_daemon, opt_foreground,
37 opt_initialstart, opt_verbose;
38 static const char* opt_nowait_nodes = 0;
39 static const char* opt_bind_address = 0;
40 static int opt_report_fd;
41 static int opt_initial;
42 static int opt_no_start;
43 static unsigned opt_allocated_nodeid;
44
45 extern NdbNodeBitmask g_nowait_nodes;
46
47 static struct my_option my_long_options[] =
48 {
49 NDB_STD_OPTS("ndbd"),
50 { "initial", NDB_OPT_NOSHORT,
51 "Perform initial start of ndbd, including cleaning the file system. "
52 "Consult documentation before using this",
53 (uchar**) &opt_initial, (uchar**) &opt_initial, 0,
54 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
55 { "nostart", 'n',
56 "Don't start ndbd immediately. Ndbd will await command from ndb_mgmd",
57 (uchar**) &opt_no_start, (uchar**) &opt_no_start, 0,
58 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
59 { "daemon", 'd', "Start ndbd as daemon (default)",
60 (uchar**) &opt_daemon, (uchar**) &opt_daemon, 0,
61 GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
62 { "nodaemon", NDB_OPT_NOSHORT,
63 "Do not start ndbd as daemon, provided for testing purposes",
64 (uchar**) &opt_no_daemon, (uchar**) &opt_no_daemon, 0,
65 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
66 { "foreground", NDB_OPT_NOSHORT,
67 "Run real ndbd in foreground, provided for debugging purposes"
68 " (implies --nodaemon)",
69 (uchar**) &opt_foreground, (uchar**) &opt_foreground, 0,
70 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
71 { "nowait-nodes", NDB_OPT_NOSHORT,
72 "Nodes that will not be waited for during start",
73 (uchar**) &opt_nowait_nodes, (uchar**) &opt_nowait_nodes, 0,
74 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
75 { "initial-start", NDB_OPT_NOSHORT,
76 "Perform a partial initial start of the cluster. "
77 "Each node should be started with this option, as well as --nowait-nodes",
78 (uchar**) &opt_initialstart, (uchar**) &opt_initialstart, 0,
79 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
80 { "bind-address", NDB_OPT_NOSHORT,
81 "Local bind address",
82 (uchar**) &opt_bind_address, (uchar**) &opt_bind_address, 0,
83 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
84 { "verbose", 'v',
85 "Write more log messages",
86 (uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,
87 GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
88 { "report-fd", 256,
89 "INTERNAL: fd where to write extra shutdown status",
90 (uchar**) &opt_report_fd, (uchar**) &opt_report_fd, 0,
91 GET_UINT, REQUIRED_ARG, 0, 0, ~0, 0, 0, 0 },
92 { "allocated-nodeid", 256,
93 "INTERNAL: nodeid allocated by angel process",
94 (uchar**) &opt_allocated_nodeid, (uchar**) &opt_allocated_nodeid, 0,
95 GET_UINT, REQUIRED_ARG, 0, 0, ~0, 0, 0, 0 },
96 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
97 };
98
99 const char *load_default_groups[]= { "mysql_cluster", "ndbd", 0 };
100
101
short_usage_sub(void)102 static void short_usage_sub(void)
103 {
104 ndb_short_usage_sub(NULL);
105 ndb_service_print_options("ndbd");
106 }
107
usage()108 static void usage()
109 {
110 ndb_usage(short_usage_sub, load_default_groups, my_long_options);
111 }
112
113 extern int g_ndb_init_need_monotonic;
114
115 #include "../common/util/parse_mask.hpp"
116
117 /**
118 * C++ Standard 3.6.1/3:
119 * The function main shall not be used (3.2) within a program.
120 *
121 * So call "main" "real_main" to avoid this rule...
122 */
123 int
real_main(int argc,char ** argv)124 real_main(int argc, char** argv)
125 {
126 g_ndb_init_need_monotonic = 1;
127 NDB_INIT(argv[0]);
128
129 // Print to stdout/console
130 g_eventLogger->createConsoleHandler();
131
132 #ifdef _WIN32
133 /* Output to Windows event log */
134 g_eventLogger->createEventLogHandler("MySQL Cluster Data Node Daemon");
135 #endif
136
137 g_eventLogger->setCategory("ndbd");
138
139 // Turn on max loglevel for startup messages
140 g_eventLogger->m_logLevel.setLogLevel(LogLevel::llStartUp, 15);
141
142 ndb_opt_set_usage_funcs(short_usage_sub, usage);
143 load_defaults("my",load_default_groups,&argc,&argv);
144
145 #ifndef DBUG_OFF
146 opt_debug= "d:t:O,/tmp/ndbd.trace";
147 #endif
148
149 // Save the original program name and arguments for angel
150 const char* progname = argv[0];
151 Vector<BaseString> original_args;
152 for (int i = 0; i < argc; i++)
153 {
154 if (ndb_is_load_default_arg_separator(argv[i]))
155 continue;
156 original_args.push_back(argv[i]);
157 }
158
159 int ho_error;
160 if ((ho_error=handle_options(&argc, &argv, my_long_options,
161 ndb_std_get_one_option)))
162 exit(ho_error);
163
164 if (opt_no_daemon || opt_foreground) {
165 // --nodaemon or --forground implies --daemon=0
166 opt_daemon= 0;
167 }
168
169 // Turn on debug printouts if --verbose
170 if (opt_verbose)
171 g_eventLogger->enable(Logger::LL_DEBUG);
172
173 if (opt_nowait_nodes)
174 {
175 int res = parse_mask(opt_nowait_nodes, g_nowait_nodes);
176 if(res == -2 || (res > 0 && g_nowait_nodes.get(0)))
177 {
178 g_eventLogger->error("Invalid nodeid specified in nowait-nodes: %s",
179 opt_nowait_nodes);
180 exit(-1);
181 }
182 else if (res < 0)
183 {
184 g_eventLogger->error("Unable to parse nowait-nodes argument: %s",
185 opt_nowait_nodes);
186 exit(-1);
187 }
188 }
189
190 if (opt_foreground ||
191 opt_allocated_nodeid ||
192 opt_report_fd)
193 {
194 ndbd_run(opt_foreground, opt_report_fd,
195 opt_ndb_connectstring, opt_ndb_nodeid, opt_bind_address,
196 opt_no_start, opt_initial, opt_initialstart,
197 opt_allocated_nodeid);
198 }
199
200 angel_run(progname,
201 original_args,
202 opt_ndb_connectstring,
203 opt_ndb_nodeid,
204 opt_bind_address,
205 opt_initial,
206 opt_no_start,
207 opt_daemon);
208
209 return 1; // Never reached
210 }
211
212 int
main(int argc,char ** argv)213 main(int argc, char** argv)
214 {
215 return ndb_daemon_init(argc, argv, real_main, angel_stop,
216 "ndbd", "MySQL Cluster Data Node Daemon");
217 }
218