1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
45
45
#include <boost/filesystem.hpp>
47
#include "drizzled/plugin.h"
48
#include "drizzled/gettext.h"
49
#include "drizzled/configmake.h"
50
#include "drizzled/session.h"
51
#include "drizzled/session_list.h"
52
#include "drizzled/internal/my_sys.h"
53
#include "drizzled/unireg.h"
54
#include "drizzled/drizzled.h"
55
#include "drizzled/errmsg_print.h"
56
#include "drizzled/data_home.h"
57
#include "drizzled/plugin/listen.h"
58
#include "drizzled/plugin/client.h"
59
#include "drizzled/pthread_globals.h"
60
#include "drizzled/tztime.h"
61
#include "drizzled/signal_handler.h"
62
#include "drizzled/replication_services.h"
63
#include "drizzled/transaction_services.h"
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>
65
#include "drizzled/util/backtrace.h"
70
extern "C" int daemonize(int nochdir, int noclose, int wait_sigusr1);
71
extern "C" int daemon_is_ready(void);
67
73
using namespace drizzled;
68
74
using namespace std;
71
77
static pthread_t select_thread;
72
78
static uint32_t thr_kill_signal;
80
extern bool opt_daemon;
76
84
All global error messages are sent here where the first one is stored
79
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
87
static void my_message_sql(drizzled::error_t error, const char *str, myf MyFlags)
89
97
session->is_fatal_error= 1;
92
TODO: There are two exceptions mechanism (Session and sp_rcontext),
100
@TODO There are two exceptions mechanism (Session and sp_rcontext),
93
101
this could be improved by having a common stack of handlers.
95
if (session->handle_error(error, str,
96
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
103
if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
100
107
session->lex->current_select == 0 if lex structure is not inited
101
108
(not query command (COM_QUERY))
103
110
if (! (session->lex->current_select &&
104
session->lex->current_select->no_error && !session->is_fatal_error))
111
session->lex->current_select->no_error && !session->is_fatal_error))
106
113
if (! session->main_da.is_error()) // Return only first message
109
116
error= ER_UNKNOWN_ERROR;
112
121
session->main_da.set_error_status(error, str);
122
131
session->no_warnings_for_error= true;
123
132
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
124
133
session->no_warnings_for_error= false;
127
if (!session || MyFlags & ME_NOREFRESH)
128
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
137
if (not session || MyFlags & ME_NOREFRESH)
139
errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
131
143
static void init_signals(void)
134
146
struct sigaction sa;
136
if (!(test_flags.test(TEST_NO_STACKTRACE) ||
137
test_flags.test(TEST_CORE_ON_SIGNAL)))
148
if (not (getDebug().test(debug::NO_STACKTRACE) ||
149
getDebug().test(debug::CORE_ON_SIGNAL)))
139
151
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
140
152
sigemptyset(&sa.sa_mask);
150
162
sigaction(SIGFPE, &sa, NULL);
153
if (test_flags.test(TEST_CORE_ON_SIGNAL))
165
if (getDebug().test(debug::CORE_ON_SIGNAL))
155
167
/* Change limits so that we will get a core file */
156
168
struct rlimit rl;
157
169
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
158
170
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
159
errmsg_printf(ERRMSG_LVL_WARN,
171
errmsg_printf(error::WARN,
160
172
_("setrlimit could not change the size of core files "
161
173
"to 'infinity'; We may not be able to generate a "
162
174
"core file on signals"));
202
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
203
int line, const string& message) throw(const char *)
214
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
216
int, const string& ) throw(const char *)
209
drizzled::util::custom_backtrace();
213
220
case google::protobuf::LOGLEVEL_INFO:
227
233
# if defined(HAVE_LOCALE_H)
228
234
setlocale(LC_ALL, "");
230
bindtextdomain("drizzle", LOCALEDIR);
231
textdomain("drizzle");
236
bindtextdomain("drizzle7", LOCALEDIR);
237
textdomain("drizzle7");
234
240
module::Registry &modules= module::Registry::singleton();
235
plugin::Client *client;
237
242
MY_INIT(argv[0]); // init my_sys library & pthreads
238
243
/* nothing should come before this line ^^^ */
245
250
/* Function generates error messages before abort */
246
251
error_handler_hook= my_message_sql;
247
253
/* init_common_variables must get basic settings such as data_home_dir
248
254
and plugin_load_list. */
249
if (init_common_variables(argc, argv, modules))
255
if (init_basic_variables(argc, argv))
256
unireg_abort(1); // Will do exit
260
if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
262
perror("Failed to ignore SIGHUP");
264
if (daemonize(1, 1, 1) == -1)
266
fprintf(stderr, "failed to daemon() in order to daemonize\n");
271
if (init_remaining_variables(modules))
250
272
unireg_abort(1); // Will do exit
264
286
if (chdir(getDataHome().file_string().c_str()))
266
errmsg_printf(ERRMSG_LVL_ERROR,
288
errmsg_printf(error::ERROR,
267
289
_("Data directory %s does not exist\n"),
268
290
getDataHome().file_string().c_str());
275
297
if (chdir("local"))
277
errmsg_printf(ERRMSG_LVL_ERROR,
299
errmsg_printf(error::ERROR,
278
300
_("Local catalog %s/local does not exist\n"),
279
301
getDataHome().file_string().c_str());
305
fs::path &full_data_home= getFullDataHome();
283
306
full_data_home= fs::system_complete(getDataHome());
284
getDataHomeCatalog()= "./";
285
getDataHome()= "../";
307
std::cerr << "home " << full_data_home << std::endl;
295
if (init_server_components(modules))
319
if (init_server_components(modules))
322
catch (abort_exception& ex)
325
cout << _("Drizzle has receieved an abort event.") << endl;
326
cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
327
cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
328
cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
299
335
* This check must be done after init_server_components for now
312
348
if (plugin::Listen::setup())
316
351
assert(plugin::num_trx_monitored_objects > 0);
317
if (drizzle_rm_tmp_tables() ||
318
my_tz_init((Session *)0, default_tz_name))
352
if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
320
354
abort_loop= true;
321
355
select_thread_in_use=0;
324
358
(void) unlink(pid_file.file_string().c_str()); // Not needed anymore
329
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
363
errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
330
364
PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
335
369
/* Send server startup event */
371
Session::shared_ptr session;
339
if ((session= new Session(plugin::Listen::getNullClient())))
373
if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
341
375
currentSession().release();
342
currentSession().reset(session);
343
transaction_services.sendStartupEvent(session);
376
currentSession().reset(session.get());
379
transaction_services.sendStartupEvent(*session);
381
plugin_startup_window(modules, *(session.get()));
349
/* Listen for new connections and start new session for each connection
389
Listen for new connections and start new session for each connection
350
390
accepted. The listen.getClient() method will return NULL when the server
351
should be shutdown. */
393
plugin::Client *client;
352
394
while ((client= plugin::Listen::getClient()) != NULL)
354
Session::shared_ptr session(new Session(client));
396
Session::shared_ptr session;
397
session= Session::make_shared(client, client->catalog());
367
410
/* Send server shutdown event */
412
Session::shared_ptr session;
371
if ((session= new Session(plugin::Listen::getNullClient())))
414
if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
373
416
currentSession().release();
374
currentSession().reset(session);
375
transaction_services.sendShutdownEvent(session);
417
currentSession().reset(session.get());
418
transaction_services.sendShutdownEvent(*session.get());
384
426
COND_thread_count.notify_all();
386
428
/* Wait until cleanup is done */
388
boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
389
while (not ready_to_exit)
390
COND_server_end.wait(scopedLock);
429
session::Cache::singleton().shutdownSecond();
394
432
module::Registry::shutdown();