42
39
# include <locale.h>
45
#include <boost/filesystem.hpp>
47
#include <drizzled/abort_exception.h>
48
#include <drizzled/catalog/local.h>
49
#include <drizzled/configmake.h>
50
#include <drizzled/data_home.h>
51
#include <drizzled/debug.h>
52
#include <drizzled/drizzled.h>
53
#include <drizzled/errmsg_print.h>
54
#include <drizzled/gettext.h>
55
#include <drizzled/internal/my_sys.h>
56
#include <drizzled/plugin.h>
57
#include <drizzled/plugin/client.h>
58
#include <drizzled/plugin/listen.h>
59
#include <drizzled/plugin/monitored_in_transaction.h>
60
#include <drizzled/pthread_globals.h>
61
#include <drizzled/replication_services.h>
62
#include <drizzled/session.h>
63
#include <drizzled/session/cache.h>
64
#include <drizzled/signal_handler.h>
65
#include <drizzled/transaction_services.h>
66
#include <drizzled/tztime.h>
67
#include <drizzled/unireg.h>
68
#include <drizzled/util/backtrace.h>
69
#include <drizzled/current_session.h>
70
#include <drizzled/daemon.h>
43
#include "drizzled/plugin.h"
44
#include "drizzled/gettext.h"
45
#include "drizzled/configmake.h"
46
#include "drizzled/session.h"
47
#include "drizzled/internal/my_sys.h"
48
#include "drizzled/unireg.h"
49
#include "drizzled/stacktrace.h"
50
#include "drizzled/drizzled.h"
51
#include "drizzled/errmsg_print.h"
52
#include "drizzled/data_home.h"
53
#include "drizzled/plugin/listen.h"
54
#include "drizzled/plugin/client.h"
55
#include "drizzled/pthread_globals.h"
56
#include "drizzled/tztime.h"
57
#include "drizzled/signal_handler.h"
58
#include "drizzled/replication_services.h"
72
60
using namespace drizzled;
73
61
using namespace std;
95
80
session->is_fatal_error= 1;
98
@TODO There are two exceptions mechanism (Session and sp_rcontext),
83
TODO: There are two exceptions mechanism (Session and sp_rcontext),
99
84
this could be improved by having a common stack of handlers.
101
if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
86
if (session->handle_error(error, str,
87
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
105
session->getLex()->current_select == 0 if lex structure is not inited
91
session->lex->current_select == 0 if lex structure is not inited
106
92
(not query command (COM_QUERY))
108
if (! (session->getLex()->current_select &&
109
session->getLex()->current_select->no_error && !session->is_fatal_error))
94
if (! (session->lex->current_select &&
95
session->lex->current_select->no_error && !session->is_fatal_error))
111
97
if (! session->main_da.is_error()) // Return only first message
114
100
error= ER_UNKNOWN_ERROR;
119
103
session->main_da.set_error_status(error, str);
129
113
session->no_warnings_for_error= true;
130
114
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
131
115
session->no_warnings_for_error= false;
135
if (not session || MyFlags & ME_NOREFRESH)
137
errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
118
if (!session || MyFlags & ME_NOREFRESH)
119
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
141
122
static void init_signals(void)
144
125
struct sigaction sa;
146
if (not (getDebug().test(debug::NO_STACKTRACE) ||
147
getDebug().test(debug::CORE_ON_SIGNAL)))
127
if (!(test_flags.test(TEST_NO_STACKTRACE) ||
128
test_flags.test(TEST_CORE_ON_SIGNAL)))
149
130
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
150
131
sigemptyset(&sa.sa_mask);
151
132
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
153
135
sa.sa_handler= drizzled_handle_segfault;
154
136
sigaction(SIGSEGV, &sa, NULL);
155
137
sigaction(SIGABRT, &sa, NULL);
160
142
sigaction(SIGFPE, &sa, NULL);
163
if (getDebug().test(debug::CORE_ON_SIGNAL))
145
if (test_flags.test(TEST_CORE_ON_SIGNAL))
165
147
/* Change limits so that we will get a core file */
166
148
struct rlimit rl;
167
149
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
168
150
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
169
errmsg_printf(error::WARN,
151
errmsg_printf(ERRMSG_LVL_WARN,
170
152
_("setrlimit could not change the size of core files "
171
153
"to 'infinity'; We may not be able to generate a "
172
154
"core file on signals"));
231
215
# if defined(HAVE_LOCALE_H)
232
216
setlocale(LC_ALL, "");
234
bindtextdomain("drizzle7", LOCALEDIR);
235
textdomain("drizzle7");
218
bindtextdomain("drizzle", LOCALEDIR);
219
textdomain("drizzle");
238
222
module::Registry &modules= module::Registry::singleton();
223
plugin::Client *client;
240
226
MY_INIT(argv[0]); // init my_sys library & pthreads
241
227
/* nothing should come before this line ^^^ */
243
229
/* Set signal used to kill Drizzle */
231
thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
244
233
thr_kill_signal= SIGINT;
246
236
google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
248
/* Function generates error messages before abort */
249
error_handler_hook= my_message_sql;
251
/* init_common_variables must get basic settings such as data_home_dir
252
and plugin_load_list. */
253
if (init_basic_variables(argc, argv))
254
unireg_abort(1); // Will do exit
258
if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
260
perror("Failed to ignore SIGHUP");
264
fprintf(stderr, "failed to daemon() in order to daemonize\n");
269
if (init_remaining_variables(modules))
270
unireg_abort(1); // Will do exit
274
After this we can't quit by a simple unireg_abort
238
if (init_common_variables(DRIZZLE_CONFIG_NAME,
239
argc, argv, load_default_groups))
240
unireg_abort(1); // Will do exit
279
245
select_thread=pthread_self();
280
246
select_thread_in_use=1;
284
if (chdir(getDataHome().file_string().c_str()))
286
errmsg_printf(error::ERROR,
287
_("Data directory %s does not exist\n"),
288
getDataHome().file_string().c_str());
291
if (mkdir("local", 0700))
293
/* We don't actually care */
297
errmsg_printf(error::ERROR,
298
_("Local catalog %s/local does not exist\n"),
299
getDataHome().file_string().c_str());
303
boost::filesystem::path &full_data_home= getFullDataHome();
304
full_data_home= boost::filesystem::system_complete(getDataHome());
305
errmsg_printf(error::INFO, "Data Home directory is : %s", full_data_home.native_file_string().c_str());
248
if (chdir(data_home_real) && !opt_help)
250
errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), data_home_real);
253
data_home= data_home_buff;
254
data_home[0]=FN_CURLIB; // all paths are relative from here
258
if ((user_info= check_user(drizzled_user)))
260
set_user(drizzled_user, user_info);
310
263
if (server_id == 0)
317
if (init_server_components(modules))
320
catch (abort_exception& ex)
323
cout << _("Drizzle has receieved an abort event.") << endl;
324
cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
325
cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
326
cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
268
if (init_server_components(modules))
333
272
* This check must be done after init_server_components for now
346
285
if (plugin::Listen::setup())
290
After this we can't quit by a simple unireg_abort
292
error_handler_hook= my_message_sql;
349
294
assert(plugin::num_trx_monitored_objects > 0);
350
if (drizzle_rm_tmp_tables())
295
if (drizzle_rm_tmp_tables() ||
296
my_tz_init((Session *)0, default_tz_name))
352
298
abort_loop= true;
353
299
select_thread_in_use=0;
354
300
(void) pthread_kill(signal_thread, SIGTERM);
356
(void) unlink(pid_file.file_string().c_str()); // Not needed anymore
302
(void) unlink(pidfile_name); // Not needed anymore
361
errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
307
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
362
308
PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
365
TransactionServices &transaction_services= TransactionServices::singleton();
367
/* Send server startup event */
369
Session::shared_ptr session;
371
if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
373
currentSession().release();
374
currentSession().reset(session.get());
377
transaction_services.sendStartupEvent(*session);
379
plugin_startup_window(modules, *(session.get()));
387
Listen for new connections and start new session for each connection
311
/* Listen for new connections and start new session for each connection
388
312
accepted. The listen.getClient() method will return NULL when the server
391
plugin::Client *client;
313
should be shutdown. */
392
314
while ((client= plugin::Listen::getClient()) != NULL)
394
Session::shared_ptr session;
395
session= Session::make_shared(client, client->catalog());
316
if (!(session= new Session(client)))
403
322
/* If we error on creation we drop the connection and delete the session. */
404
if (Session::schedule(session))
323
if (session->schedule())
405
324
Session::unlink(session);
408
/* Send server shutdown event */
410
Session::shared_ptr session;
412
if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
414
currentSession().release();
415
currentSession().reset(session.get());
416
transaction_services.sendShutdownEvent(*session.get());
421
boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
422
select_thread_in_use= false; // For close_connections
327
LOCK_thread_count.lock();
328
select_thread_in_use=0; // For close_connections
329
LOCK_thread_count.unlock();
424
330
COND_thread_count.notify_all();
426
332
/* Wait until cleanup is done */
427
session::Cache::singleton().shutdownSecond();
333
LOCK_thread_count.lock();
334
while (!ready_to_exit)
335
pthread_cond_wait(COND_server_end.native_handle(), LOCK_thread_count.native_handle());
336
LOCK_thread_count.unlock();
430
339
module::Registry::shutdown();
431
340
internal::my_end();