~drizzle-trunk/drizzle/development

1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
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.
9
 *
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.
14
 *
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
18
 */
19
20
#include "config.h"
21
22
#include <pthread.h>
23
#include <signal.h>
24
#include <sys/resource.h>
25
#include <unistd.h>
26
27
#if TIME_WITH_SYS_TIME
28
# include <sys/time.h>
29
# include <time.h>
30
#else
31
# if HAVE_SYS_TIME_H
32
#  include <sys/time.h>
33
# else
34
#  include <time.h>
35
# endif
36
#endif
37
1300.5.7 by Monty Taylor
Fixed Sun Studio issues.
38
#if defined(HAVE_LOCALE_H)
39
# include <locale.h>
40
#endif
41
42
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
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/drizzled.h"
50
#include "drizzled/errmsg_print.h"
51
#include "drizzled/data_home.h"
52
#include "drizzled/plugin/listen.h"
53
#include "drizzled/plugin/client.h"
54
#include "drizzled/pthread_globals.h"
55
#include "drizzled/tztime.h"
1300.5.22 by Monty Taylor
Moved and reworked a wrapper around sigset - which we shouldn't be using
56
#include "drizzled/signal_handler.h"
1471.3.2 by Monty Taylor
Merged in old drizzled-as-lib patch.
57
#include "drizzled/replication_services.h"
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
58
59
using namespace drizzled;
60
using namespace std;
61
62
static pthread_t select_thread;
63
static uint32_t thr_kill_signal;
64
65
/**
66
  All global error messages are sent here where the first one is stored
67
  for the client.
68
*/
69
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
70
{
71
  Session *session;
72
  /*
73
    Put here following assertion when situation with EE_* error codes
74
    will be fixed
75
  */
76
  if ((session= current_session))
77
  {
78
    if (MyFlags & ME_FATALERROR)
79
      session->is_fatal_error= 1;
80
81
    /*
82
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
83
      this could be improved by having a common stack of handlers.
84
    */
85
    if (session->handle_error(error, str,
86
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
87
      return;;
88
89
    /*
90
      session->lex->current_select == 0 if lex structure is not inited
91
      (not query command (COM_QUERY))
92
    */
93
    if (! (session->lex->current_select &&
94
        session->lex->current_select->no_error && !session->is_fatal_error))
95
    {
96
      if (! session->main_da.is_error())            // Return only first message
97
      {
98
        if (error == 0)
99
          error= ER_UNKNOWN_ERROR;
100
        if (str == NULL)
101
          str= ER(error);
102
        session->main_da.set_error_status(error, str);
103
      }
104
    }
105
106
    if (!session->no_warnings_for_error && !session->is_fatal_error)
107
    {
108
      /*
109
        Suppress infinite recursion if there a memory allocation error
110
        inside push_warning.
111
      */
112
      session->no_warnings_for_error= true;
113
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
114
      session->no_warnings_for_error= false;
115
      }
116
    }
117
    if (!session || MyFlags & ME_NOREFRESH)
118
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
119
}
120
121
static void init_signals(void)
122
{
123
  sigset_t set;
124
  struct sigaction sa;
125
126
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
127
        test_flags.test(TEST_CORE_ON_SIGNAL)))
128
  {
129
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
130
    sigemptyset(&sa.sa_mask);
131
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
132
133
    sa.sa_handler= drizzled_handle_segfault;
134
    sigaction(SIGSEGV, &sa, NULL);
135
    sigaction(SIGABRT, &sa, NULL);
136
#ifdef SIGBUS
137
    sigaction(SIGBUS, &sa, NULL);
138
#endif
139
    sigaction(SIGILL, &sa, NULL);
140
    sigaction(SIGFPE, &sa, NULL);
141
  }
142
143
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
144
  {
145
    /* Change limits so that we will get a core file */
146
    struct rlimit rl;
147
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
148
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
149
        errmsg_printf(ERRMSG_LVL_WARN,
150
                      _("setrlimit could not change the size of core files "
151
                        "to 'infinity';  We may not be able to generate a "
152
                        "core file on signals"));
153
  }
154
  (void) sigemptyset(&set);
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
155
  ignore_signal(SIGPIPE);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
156
  sigaddset(&set,SIGPIPE);
157
#ifndef IGNORE_SIGHUP_SIGQUIT
158
  sigaddset(&set,SIGQUIT);
159
  sigaddset(&set,SIGHUP);
160
#endif
161
  sigaddset(&set,SIGTERM);
162
163
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
164
  sigemptyset(&sa.sa_mask);
165
  sa.sa_flags = 0;
166
  sa.sa_handler = drizzled_print_signal_warning;
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
167
  sigaction(SIGTERM, &sa, NULL);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
168
  sa.sa_flags = 0;
169
  sa.sa_handler = drizzled_print_signal_warning;
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
170
  sigaction(SIGHUP, &sa, NULL);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
171
#ifdef SIGTSTP
172
  sigaddset(&set,SIGTSTP);
173
#endif
174
  if (test_flags.test(TEST_SIGINT))
175
  {
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
176
    sa.sa_flags= 0;
177
    sa.sa_handler= drizzled_end_thread_signal;
178
    sigaction(thr_kill_signal, &sa, NULL);
179
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
180
    // May be SIGINT
181
    sigdelset(&set, thr_kill_signal);
182
  }
183
  else
1608.1.2 by Brian Aker
Merge enum test
184
  {
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
185
    sigaddset(&set,SIGINT);
1608.1.2 by Brian Aker
Merge enum test
186
  }
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
187
  sigprocmask(SIG_SETMASK,&set,NULL);
188
  pthread_sigmask(SIG_SETMASK,&set,NULL);
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
189
  return;
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
190
}
191
1608.1.2 by Brian Aker
Merge enum test
192
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
193
                       int line, const string& message) throw(const char *)
194
{
195
  (void)filename;
196
  (void)line;
197
  (void)message;
198
  switch(level)
199
  {
200
  case google::protobuf::LOGLEVEL_INFO:
201
    break;
202
  case google::protobuf::LOGLEVEL_WARNING:
203
  case google::protobuf::LOGLEVEL_ERROR:
204
  case google::protobuf::LOGLEVEL_FATAL:
205
  default:
206
    throw("error in google protocol buffer parsing");
207
  }
208
}
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
209
210
int main(int argc, char **argv)
211
{
212
#if defined(ENABLE_NLS)
213
# if defined(HAVE_LOCALE_H)
214
  setlocale(LC_ALL, "");
215
# endif
216
  bindtextdomain("drizzle", LOCALEDIR);
217
  textdomain("drizzle");
218
#endif
219
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
220
  module::Registry &modules= module::Registry::singleton();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
221
  plugin::Client *client;
222
  Session *session;
223
224
  MY_INIT(argv[0]);		// init my_sys library & pthreads
225
  /* nothing should come before this line ^^^ */
226
227
  /* Set signal used to kill Drizzle */
228
  thr_kill_signal= SIGINT;
229
1608.1.2 by Brian Aker
Merge enum test
230
  google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
231
1655.1.1 by Andrew Hutchings
1. Move message handler hook earier so that errors during init_commit_variables do not segfault
232
  /*
233
    init signals & alarm
234
    After this we can't quit by a simple unireg_abort
235
  */
236
  error_handler_hook= my_message_sql;
237
1743.4.1 by LinuxJedi
Make sure unireg_abort shows the reason for the fail.
238
  /* Function generates error messages before abort */
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
239
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
240
			    argc, argv, load_default_groups))
241
    unireg_abort(1);				// Will do exit
242
243
  init_signals();
244
245
246
  select_thread=pthread_self();
247
  select_thread_in_use=1;
248
1300.5.3 by Monty Taylor
Removed drizzle_ prefix from some things that don't need it since they're
249
  if (chdir(data_home_real) && !opt_help)
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
250
  {
1300.5.3 by Monty Taylor
Removed drizzle_ prefix from some things that don't need it since they're
251
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), data_home_real);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
252
    unireg_abort(1);
253
  }
1300.5.3 by Monty Taylor
Removed drizzle_ prefix from some things that don't need it since they're
254
  data_home= data_home_buff;
255
  data_home[0]=FN_CURLIB;		// all paths are relative from here
256
  data_home[1]=0;
257
  data_home_len= 2;
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
258
259
  if (server_id == 0)
260
  {
261
    server_id= 1;
262
  }
263
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
264
  if (init_server_components(modules))
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
265
    unireg_abort(1);
266
1471.3.2 by Monty Taylor
Merged in old drizzled-as-lib patch.
267
  /**
268
   * This check must be done after init_server_components for now
269
   * because we don't yet have plugin dependency tracking...
270
   *
271
   * ReplicationServices::evaluateRegisteredPlugins() will print error messages to stderr
272
   * via errmsg_printf().
273
   *
274
   * @todo
275
   *
276
   * not checking return since unireg_abort() hangs
277
   */
278
  ReplicationServices &replication_services= ReplicationServices::singleton();
279
    (void) replication_services.evaluateRegisteredPlugins();
280
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
281
  if (plugin::Listen::setup())
282
    unireg_abort(1);
283
1300.5.17 by Monty Taylor
Merged trunk.
284
  assert(plugin::num_trx_monitored_objects > 0);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
285
  if (drizzle_rm_tmp_tables() ||
286
      my_tz_init((Session *)0, default_tz_name))
287
  {
288
    abort_loop= true;
289
    select_thread_in_use=0;
290
    (void) pthread_kill(signal_thread, SIGTERM);
291
292
    (void) unlink(pidfile_name);	// Not needed anymore
293
294
    exit(1);
295
  }
296
297
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
298
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
299
300
301
  /* Listen for new connections and start new session for each connection
302
     accepted. The listen.getClient() method will return NULL when the server
303
     should be shutdown. */
304
  while ((client= plugin::Listen::getClient()) != NULL)
305
  {
306
    if (!(session= new Session(client)))
307
    {
308
      delete client;
309
      continue;
310
    }
311
312
    /* If we error on creation we drop the connection and delete the session. */
313
    if (session->schedule())
314
      Session::unlink(session);
315
  }
316
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
317
  LOCK_thread_count.lock();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
318
  select_thread_in_use=0;			// For close_connections
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
319
  LOCK_thread_count.unlock();
1689.2.5 by Brian Aker
Convert COND_thread_count to boost.
320
  COND_thread_count.notify_all();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
321
322
  /* Wait until cleanup is done */
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
323
  LOCK_thread_count.lock();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
324
  while (!ready_to_exit)
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
325
    pthread_cond_wait(COND_server_end.native_handle(), LOCK_thread_count.native_handle());
326
  LOCK_thread_count.unlock();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
327
328
  clean_up(1);
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
329
  module::Registry::shutdown();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
330
  internal::my_end();
331
  return 0;
332
}
333