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