~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>
1786.3.1 by Monty Taylor
Initial working local catalog.
26
#include <sys/stat.h>
27
#include <sys/types.h>
28
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
29
30
#if TIME_WITH_SYS_TIME
31
# include <sys/time.h>
32
# include <time.h>
33
#else
34
# if HAVE_SYS_TIME_H
35
#  include <sys/time.h>
36
# else
37
#  include <time.h>
38
# endif
39
#endif
40
1300.5.7 by Monty Taylor
Fixed Sun Studio issues.
41
#if defined(HAVE_LOCALE_H)
42
# include <locale.h>
43
#endif
44
1791.3.5 by mordred
Now lets get the proper values into these bad boys.
45
#include <boost/filesystem.hpp>
1300.5.7 by Monty Taylor
Fixed Sun Studio issues.
46
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
47
#include "drizzled/plugin.h"
48
#include "drizzled/gettext.h"
49
#include "drizzled/configmake.h"
50
#include "drizzled/session.h"
51
#include "drizzled/internal/my_sys.h"
52
#include "drizzled/unireg.h"
53
#include "drizzled/drizzled.h"
54
#include "drizzled/errmsg_print.h"
55
#include "drizzled/data_home.h"
56
#include "drizzled/plugin/listen.h"
57
#include "drizzled/plugin/client.h"
58
#include "drizzled/pthread_globals.h"
59
#include "drizzled/tztime.h"
1300.5.22 by Monty Taylor
Moved and reworked a wrapper around sigset - which we shouldn't be using
60
#include "drizzled/signal_handler.h"
1471.3.2 by Monty Taylor
Merged in old drizzled-as-lib patch.
61
#include "drizzled/replication_services.h"
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
62
#include "drizzled/transaction_services.h"
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
63
1861.4.8 by Brian Aker
Adds in a portion of the ref constraints table.
64
#include "drizzled/util/backtrace.h"
65
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
66
using namespace drizzled;
67
using namespace std;
1791.3.5 by mordred
Now lets get the proper values into these bad boys.
68
namespace fs=boost::filesystem;
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
69
70
static pthread_t select_thread;
71
static uint32_t thr_kill_signal;
72
1791.3.4 by mordred
Well, so handing pointers returned by std::string::c_str() is a bad idea anyway - but you certainly shouldn't do it in static initializers before you do all of your changes to the string. Sigh.
73
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
74
/**
75
  All global error messages are sent here where the first one is stored
76
  for the client.
77
*/
78
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
79
{
80
  Session *session;
81
  /*
82
    Put here following assertion when situation with EE_* error codes
83
    will be fixed
84
  */
85
  if ((session= current_session))
86
  {
87
    if (MyFlags & ME_FATALERROR)
88
      session->is_fatal_error= 1;
89
90
    /*
91
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
92
      this could be improved by having a common stack of handlers.
93
    */
94
    if (session->handle_error(error, str,
95
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
96
      return;;
97
98
    /*
99
      session->lex->current_select == 0 if lex structure is not inited
100
      (not query command (COM_QUERY))
101
    */
102
    if (! (session->lex->current_select &&
103
        session->lex->current_select->no_error && !session->is_fatal_error))
104
    {
105
      if (! session->main_da.is_error())            // Return only first message
106
      {
107
        if (error == 0)
108
          error= ER_UNKNOWN_ERROR;
109
        if (str == NULL)
110
          str= ER(error);
111
        session->main_da.set_error_status(error, str);
112
      }
113
    }
114
115
    if (!session->no_warnings_for_error && !session->is_fatal_error)
116
    {
117
      /*
118
        Suppress infinite recursion if there a memory allocation error
119
        inside push_warning.
120
      */
121
      session->no_warnings_for_error= true;
122
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
123
      session->no_warnings_for_error= false;
124
      }
125
    }
126
    if (!session || MyFlags & ME_NOREFRESH)
127
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
128
}
129
130
static void init_signals(void)
131
{
132
  sigset_t set;
133
  struct sigaction sa;
134
135
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
136
        test_flags.test(TEST_CORE_ON_SIGNAL)))
137
  {
138
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
139
    sigemptyset(&sa.sa_mask);
140
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
141
142
    sa.sa_handler= drizzled_handle_segfault;
143
    sigaction(SIGSEGV, &sa, NULL);
144
    sigaction(SIGABRT, &sa, NULL);
145
#ifdef SIGBUS
146
    sigaction(SIGBUS, &sa, NULL);
147
#endif
148
    sigaction(SIGILL, &sa, NULL);
149
    sigaction(SIGFPE, &sa, NULL);
150
  }
151
152
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
153
  {
154
    /* Change limits so that we will get a core file */
155
    struct rlimit rl;
156
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
157
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
158
        errmsg_printf(ERRMSG_LVL_WARN,
159
                      _("setrlimit could not change the size of core files "
160
                        "to 'infinity';  We may not be able to generate a "
161
                        "core file on signals"));
162
  }
163
  (void) sigemptyset(&set);
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
164
  ignore_signal(SIGPIPE);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
165
  sigaddset(&set,SIGPIPE);
166
#ifndef IGNORE_SIGHUP_SIGQUIT
167
  sigaddset(&set,SIGQUIT);
168
  sigaddset(&set,SIGHUP);
169
#endif
170
  sigaddset(&set,SIGTERM);
171
172
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
173
  sigemptyset(&sa.sa_mask);
174
  sa.sa_flags = 0;
175
  sa.sa_handler = drizzled_print_signal_warning;
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
176
  sigaction(SIGTERM, &sa, NULL);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
177
  sa.sa_flags = 0;
178
  sa.sa_handler = drizzled_print_signal_warning;
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
179
  sigaction(SIGHUP, &sa, NULL);
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
180
#ifdef SIGTSTP
181
  sigaddset(&set,SIGTSTP);
182
#endif
183
  if (test_flags.test(TEST_SIGINT))
184
  {
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
185
    sa.sa_flags= 0;
186
    sa.sa_handler= drizzled_end_thread_signal;
187
    sigaction(thr_kill_signal, &sa, NULL);
188
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
189
    // May be SIGINT
190
    sigdelset(&set, thr_kill_signal);
191
  }
192
  else
1608.1.2 by Brian Aker
Merge enum test
193
  {
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
194
    sigaddset(&set,SIGINT);
1608.1.2 by Brian Aker
Merge enum test
195
  }
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
196
  sigprocmask(SIG_SETMASK,&set,NULL);
197
  pthread_sigmask(SIG_SETMASK,&set,NULL);
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
198
  return;
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
199
}
200
1608.1.2 by Brian Aker
Merge enum test
201
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
202
                       int line, const string& message) throw(const char *)
203
{
204
  (void)filename;
205
  (void)line;
206
  (void)message;
1861.4.8 by Brian Aker
Adds in a portion of the ref constraints table.
207
  std::cerr << "\n";
208
  drizzled::util::custom_backtrace();
209
  std::cerr << "\n";
1608.1.2 by Brian Aker
Merge enum test
210
  switch(level)
211
  {
212
  case google::protobuf::LOGLEVEL_INFO:
213
    break;
214
  case google::protobuf::LOGLEVEL_WARNING:
215
  case google::protobuf::LOGLEVEL_ERROR:
216
  case google::protobuf::LOGLEVEL_FATAL:
217
  default:
1802.12.1 by Brian Aker
This solves bug lp:654905
218
    std::cerr << "GoogleProtoErrorThrower(" << filename << ", " << line << ", " << message << ")";
1608.1.2 by Brian Aker
Merge enum test
219
    throw("error in google protocol buffer parsing");
220
  }
221
}
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
222
223
int main(int argc, char **argv)
224
{
225
#if defined(ENABLE_NLS)
226
# if defined(HAVE_LOCALE_H)
227
  setlocale(LC_ALL, "");
228
# endif
229
  bindtextdomain("drizzle", LOCALEDIR);
230
  textdomain("drizzle");
231
#endif
232
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
233
  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
234
  plugin::Client *client;
235
  Session *session;
236
237
  MY_INIT(argv[0]);		// init my_sys library & pthreads
238
  /* nothing should come before this line ^^^ */
239
240
  /* Set signal used to kill Drizzle */
241
  thr_kill_signal= SIGINT;
242
1608.1.2 by Brian Aker
Merge enum test
243
  google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
244
1743.4.1 by LinuxJedi
Make sure unireg_abort shows the reason for the fail.
245
  /* Function generates error messages before abort */
1794.3.5 by Monty Taylor
Fixed temporoary dir sequencing.
246
  error_handler_hook= my_message_sql;
1757.2.1 by Monty Taylor
Moved where we set errmsg_handler_hook.
247
  /* init_common_variables must get basic settings such as data_home_dir
248
     and plugin_load_list. */
1794.3.1 by Monty Taylor
Rearranged option processing.
249
  if (init_common_variables(argc, argv, modules))
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
250
    unireg_abort(1);				// Will do exit
251
1794.3.5 by Monty Taylor
Fixed temporoary dir sequencing.
252
  /*
253
    init signals & alarm
254
    After this we can't quit by a simple unireg_abort
255
  */
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
256
  init_signals();
257
258
259
  select_thread=pthread_self();
260
  select_thread_in_use=1;
261
1786.3.1 by Monty Taylor
Initial working local catalog.
262
  if (not opt_help)
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
263
  {
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
264
    if (chdir(getDataHome().file_string().c_str()))
1786.3.1 by Monty Taylor
Initial working local catalog.
265
    {
266
      errmsg_printf(ERRMSG_LVL_ERROR,
267
                    _("Data directory %s does not exist\n"),
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
268
                    getDataHome().file_string().c_str());
1786.3.1 by Monty Taylor
Initial working local catalog.
269
      unireg_abort(1);
270
    }
271
    if (mkdir("local", 0700))
272
    {
273
      /* We don't actually care */
274
    }
275
    if (chdir("local"))
276
    {
277
      errmsg_printf(ERRMSG_LVL_ERROR,
278
                    _("Local catalog %s/local does not exist\n"),
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
279
                    getDataHome().file_string().c_str());
1786.3.1 by Monty Taylor
Initial working local catalog.
280
      unireg_abort(1);
281
    }
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
282
283
    full_data_home= fs::system_complete(getDataHome());
1786.3.2 by Monty Taylor
Cleaned up the initial pass at this. It's not perfect, but it does work.
284
    getDataHomeCatalog()= "./";
285
    getDataHome()= "../";
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
286
  }
1786.3.1 by Monty Taylor
Initial working local catalog.
287
288
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
289
290
  if (server_id == 0)
291
  {
292
    server_id= 1;
293
  }
294
1757.2.6 by Monty Taylor
We've gotten further. Now things sometimes work, but some things aren't
295
  if (init_server_components(modules))
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
296
    unireg_abort(1);
297
1471.3.2 by Monty Taylor
Merged in old drizzled-as-lib patch.
298
  /**
299
   * This check must be done after init_server_components for now
300
   * because we don't yet have plugin dependency tracking...
301
   *
302
   * ReplicationServices::evaluateRegisteredPlugins() will print error messages to stderr
303
   * via errmsg_printf().
304
   *
305
   * @todo
306
   *
307
   * not checking return since unireg_abort() hangs
308
   */
309
  ReplicationServices &replication_services= ReplicationServices::singleton();
310
    (void) replication_services.evaluateRegisteredPlugins();
311
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
312
  if (plugin::Listen::setup())
313
    unireg_abort(1);
314
1757.2.1 by Monty Taylor
Moved where we set errmsg_handler_hook.
315
1300.5.17 by Monty Taylor
Merged trunk.
316
  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
317
  if (drizzle_rm_tmp_tables() ||
318
      my_tz_init((Session *)0, default_tz_name))
319
  {
320
    abort_loop= true;
321
    select_thread_in_use=0;
322
    (void) pthread_kill(signal_thread, SIGTERM);
323
1813.2.2 by Monty Taylor
Replaced pid-file with fs::path.
324
    (void) unlink(pid_file.file_string().c_str());	// Not needed anymore
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
325
326
    exit(1);
327
  }
328
329
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
330
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
331
332
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
333
  TransactionServices &transaction_services= TransactionServices::singleton();
334
335
  /* Send server startup event */
336
  if ((session= new Session(plugin::Listen::getNullClient())))
337
  {
338
    transaction_services.sendStartupEvent(session);
339
    session->lockForDelete();
340
    delete session;
341
  }
342
343
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
344
  /* Listen for new connections and start new session for each connection
345
     accepted. The listen.getClient() method will return NULL when the server
346
     should be shutdown. */
347
  while ((client= plugin::Listen::getClient()) != NULL)
348
  {
349
    if (!(session= new Session(client)))
350
    {
351
      delete client;
352
      continue;
353
    }
354
355
    /* If we error on creation we drop the connection and delete the session. */
356
    if (session->schedule())
357
      Session::unlink(session);
358
  }
359
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
360
  /* Send server shutdown event */
361
  if ((session= new Session(plugin::Listen::getNullClient())))
362
  {
363
    transaction_services.sendShutdownEvent(session);
364
    session->lockForDelete();
365
    delete session;
366
  }
367
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
368
  LOCK_thread_count.lock();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
369
  select_thread_in_use=0;			// For close_connections
1689.2.8 by Brian Aker
LOCK_thread_count -> boost.
370
  LOCK_thread_count.unlock();
1689.2.5 by Brian Aker
Convert COND_thread_count to boost.
371
  COND_thread_count.notify_all();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
372
373
  /* Wait until cleanup is done */
1798.3.1 by Brian Aker
Remove native_handle usage.
374
  {
375
    boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
376
    while (!ready_to_exit)
377
      COND_server_end.wait(scopedLock);
378
  }
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
379
380
  clean_up(1);
1530.2.5 by Monty Taylor
Renamed classes that were in drizzled::plugin but which were not meant
381
  module::Registry::shutdown();
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
382
  internal::my_end();
1798.3.1 by Brian Aker
Remove native_handle usage.
383
1300.5.2 by Monty Taylor
Changed build to build the almost all of drizzle into libdrizzled and then
384
  return 0;
385
}
386