1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
#include <sys/resource.h>
27
#if TIME_WITH_SYS_TIME
28
# include <sys/time.h>
32
# include <sys/time.h>
38
#if defined(HAVE_LOCALE_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"
60
using namespace drizzled;
63
static pthread_t select_thread;
64
static uint32_t thr_kill_signal;
67
All global error messages are sent here where the first one is stored
70
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
74
Put here following assertion when situation with EE_* error codes
77
if ((session= current_session))
79
if (MyFlags & ME_FATALERROR)
80
session->is_fatal_error= 1;
83
TODO: There are two exceptions mechanism (Session and sp_rcontext),
84
this could be improved by having a common stack of handlers.
86
if (session->handle_error(error, str,
87
DRIZZLE_ERROR::WARN_LEVEL_ERROR))
91
session->lex->current_select == 0 if lex structure is not inited
92
(not query command (COM_QUERY))
94
if (! (session->lex->current_select &&
95
session->lex->current_select->no_error && !session->is_fatal_error))
97
if (! session->main_da.is_error()) // Return only first message
100
error= ER_UNKNOWN_ERROR;
103
session->main_da.set_error_status(error, str);
107
if (!session->no_warnings_for_error && !session->is_fatal_error)
110
Suppress infinite recursion if there a memory allocation error
113
session->no_warnings_for_error= true;
114
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
115
session->no_warnings_for_error= false;
118
if (!session || MyFlags & ME_NOREFRESH)
119
errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
122
static void init_signals(void)
127
if (!(test_flags.test(TEST_NO_STACKTRACE) ||
128
test_flags.test(TEST_CORE_ON_SIGNAL)))
130
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
131
sigemptyset(&sa.sa_mask);
132
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
135
sa.sa_handler= drizzled_handle_segfault;
136
sigaction(SIGSEGV, &sa, NULL);
137
sigaction(SIGABRT, &sa, NULL);
139
sigaction(SIGBUS, &sa, NULL);
141
sigaction(SIGILL, &sa, NULL);
142
sigaction(SIGFPE, &sa, NULL);
145
if (test_flags.test(TEST_CORE_ON_SIGNAL))
147
/* Change limits so that we will get a core file */
149
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
150
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
151
errmsg_printf(ERRMSG_LVL_WARN,
152
_("setrlimit could not change the size of core files "
153
"to 'infinity'; We may not be able to generate a "
154
"core file on signals"));
156
(void) sigemptyset(&set);
157
ignore_signal(SIGPIPE);
158
sigaddset(&set,SIGPIPE);
159
#ifndef IGNORE_SIGHUP_SIGQUIT
160
sigaddset(&set,SIGQUIT);
161
sigaddset(&set,SIGHUP);
163
sigaddset(&set,SIGTERM);
165
/* Fix signals if blocked by parents (can happen on Mac OS X) */
166
sigemptyset(&sa.sa_mask);
168
sa.sa_handler = drizzled_print_signal_warning;
169
sigaction(SIGTERM, &sa, NULL);
171
sa.sa_handler = drizzled_print_signal_warning;
172
sigaction(SIGHUP, &sa, NULL);
174
sigaddset(&set,SIGTSTP);
176
if (test_flags.test(TEST_SIGINT))
179
sa.sa_handler= drizzled_end_thread_signal;
180
sigaction(thr_kill_signal, &sa, NULL);
183
sigdelset(&set, thr_kill_signal);
186
sigaddset(&set,SIGINT);
187
sigprocmask(SIG_SETMASK,&set,NULL);
188
pthread_sigmask(SIG_SETMASK,&set,NULL);
193
int main(int argc, char **argv)
195
#if defined(ENABLE_NLS)
196
# if defined(HAVE_LOCALE_H)
197
setlocale(LC_ALL, "");
199
bindtextdomain("drizzle", LOCALEDIR);
200
textdomain("drizzle");
203
plugin::Registry &plugins= plugin::Registry::singleton();
204
plugin::Client *client;
207
MY_INIT(argv[0]); // init my_sys library & pthreads
208
/* nothing should come before this line ^^^ */
210
/* Set signal used to kill Drizzle */
212
thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
214
thr_kill_signal= SIGINT;
217
if (init_common_variables(DRIZZLE_CONFIG_NAME,
218
argc, argv, load_default_groups))
219
unireg_abort(1); // Will do exit
224
select_thread=pthread_self();
225
select_thread_in_use=1;
227
if (chdir(data_home_real) && !opt_help)
229
errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), data_home_real);
232
data_home= data_home_buff;
233
data_home[0]=FN_CURLIB; // all paths are relative from here
237
if ((user_info= check_user(drizzled_user)))
239
set_user(drizzled_user, user_info);
247
if (init_server_components(plugins))
251
* This check must be done after init_server_components for now
252
* because we don't yet have plugin dependency tracking...
254
* ReplicationServices::evaluateRegisteredPlugins() will print error messages to stderr
255
* via errmsg_printf().
259
* not checking return since unireg_abort() hangs
261
ReplicationServices &replication_services= ReplicationServices::singleton();
262
(void) replication_services.evaluateRegisteredPlugins();
264
if (plugin::Listen::setup())
269
After this we can't quit by a simple unireg_abort
271
error_handler_hook= my_message_sql;
273
assert(plugin::num_trx_monitored_objects > 0);
274
if (drizzle_rm_tmp_tables() ||
275
my_tz_init((Session *)0, default_tz_name))
278
select_thread_in_use=0;
279
(void) pthread_kill(signal_thread, SIGTERM);
281
(void) unlink(pidfile_name); // Not needed anymore
288
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
289
PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
292
/* Listen for new connections and start new session for each connection
293
accepted. The listen.getClient() method will return NULL when the server
294
should be shutdown. */
295
while ((client= plugin::Listen::getClient()) != NULL)
297
if (!(session= new Session(client)))
303
/* If we error on creation we drop the connection and delete the session. */
304
if (session->schedule())
305
Session::unlink(session);
308
/* (void) pthread_attr_destroy(&connection_attrib); */
311
(void) pthread_mutex_lock(&LOCK_thread_count);
312
select_thread_in_use=0; // For close_connections
313
(void) pthread_mutex_unlock(&LOCK_thread_count);
314
(void) pthread_cond_broadcast(&COND_thread_count);
316
/* Wait until cleanup is done */
317
(void) pthread_mutex_lock(&LOCK_thread_count);
318
while (!ready_to_exit)
319
pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
320
(void) pthread_mutex_unlock(&LOCK_thread_count);
323
plugin::Registry::shutdown();