~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/main.cc

  • Committer: Monty Taylor
  • Date: 2010-12-26 00:22:34 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101226002234-2sb62sm2gs0iftuy
Fixing some of the innodb c++ casting issues.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
 
20
#include "config.h"
21
21
 
22
22
#include <pthread.h>
23
23
#include <signal.h>
44
44
 
45
45
#include <boost/filesystem.hpp>
46
46
 
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/unireg.h>
67
 
#include <drizzled/util/backtrace.h>
68
 
#include <drizzled/current_session.h>
69
 
#include <drizzled/daemon.h>
70
 
#include <drizzled/diagnostics_area.h>
71
 
#include <drizzled/sql_base.h>
72
 
#include <drizzled/sql_lex.h>
73
 
#include <drizzled/system_variables.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/cache.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"
 
64
 
 
65
#include "drizzled/util/backtrace.h"
74
66
 
75
67
using namespace drizzled;
76
68
using namespace std;
 
69
namespace fs=boost::filesystem;
77
70
 
78
71
static pthread_t select_thread;
79
72
static uint32_t thr_kill_signal;
80
73
 
81
 
extern bool opt_daemon;
82
 
 
83
74
 
84
75
/**
85
76
  All global error messages are sent here where the first one is stored
86
77
  for the client.
87
78
*/
88
 
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)
89
80
{
90
 
  Session* session= current_session;
 
81
  Session *session;
91
82
  /*
92
83
    Put here following assertion when situation with EE_* error codes
93
84
    will be fixed
94
85
  */
95
 
  if (session)
 
86
  if ((session= current_session))
96
87
  {
97
88
    if (MyFlags & ME_FATALERROR)
98
89
      session->is_fatal_error= 1;
99
90
 
100
91
    /*
101
 
      @TODO There are two exceptions mechanism (Session and sp_rcontext),
 
92
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
102
93
      this could be improved by having a common stack of handlers.
103
 
 
104
 
    if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
105
 
      return;
106
94
    */
 
95
    if (session->handle_error(error, str,
 
96
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
 
97
      return;;
107
98
 
108
99
    /*
109
 
      session->lex().current_select == 0 if lex structure is not inited
 
100
      session->lex->current_select == 0 if lex structure is not inited
110
101
      (not query command (COM_QUERY))
111
102
    */
112
 
    if (! (session->lex().current_select &&
113
 
           session->lex().current_select->no_error && !session->is_fatal_error))
 
103
    if (! (session->lex->current_select &&
 
104
        session->lex->current_select->no_error && !session->is_fatal_error))
114
105
    {
115
 
      if (! session->main_da().is_error())            // Return only first message
 
106
      if (! session->main_da.is_error())            // Return only first message
116
107
      {
117
 
        if (error == EE_OK)
 
108
        if (error == 0)
118
109
          error= ER_UNKNOWN_ERROR;
119
 
 
120
110
        if (str == NULL)
121
111
          str= ER(error);
122
 
 
123
 
        session->main_da().set_error_status(error, str);
 
112
        session->main_da.set_error_status(error, str);
124
113
      }
125
114
    }
126
115
 
133
122
      session->no_warnings_for_error= true;
134
123
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
135
124
      session->no_warnings_for_error= false;
 
125
      }
136
126
    }
137
 
  }
138
 
 
139
 
  if (not session || MyFlags & ME_NOREFRESH)
140
 
  {
141
 
    errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
142
 
  }
 
127
    if (!session || MyFlags & ME_NOREFRESH)
 
128
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
143
129
}
144
130
 
145
131
static void init_signals(void)
147
133
  sigset_t set;
148
134
  struct sigaction sa;
149
135
 
150
 
  if (not (getDebug().test(debug::NO_STACKTRACE) ||
151
 
        getDebug().test(debug::CORE_ON_SIGNAL)))
 
136
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
 
137
        test_flags.test(TEST_CORE_ON_SIGNAL)))
152
138
  {
153
139
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
154
140
    sigemptyset(&sa.sa_mask);
164
150
    sigaction(SIGFPE, &sa, NULL);
165
151
  }
166
152
 
167
 
  if (getDebug().test(debug::CORE_ON_SIGNAL))
 
153
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
168
154
  {
169
155
    /* Change limits so that we will get a core file */
170
156
    struct rlimit rl;
171
157
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
172
158
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
173
 
        errmsg_printf(error::WARN,
 
159
        errmsg_printf(ERRMSG_LVL_WARN,
174
160
                      _("setrlimit could not change the size of core files "
175
161
                        "to 'infinity';  We may not be able to generate a "
176
162
                        "core file on signals"));
195
181
#ifdef SIGTSTP
196
182
  sigaddset(&set,SIGTSTP);
197
183
#endif
198
 
  if (getDebug().test(debug::ALLOW_SIGINT))
 
184
  if (test_flags.test(TEST_SIGINT))
199
185
  {
200
186
    sa.sa_flags= 0;
201
187
    sa.sa_handler= drizzled_end_thread_signal;
213
199
  return;
214
200
}
215
201
 
216
 
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
217
 
                                    const char* ,
218
 
                                    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 *)
219
204
{
 
205
  (void)level;
 
206
  (void)filename;
 
207
  (void)line;
 
208
  (void)message;
 
209
#if 0
 
210
  std::cerr << "\n";
 
211
  drizzled::util::custom_backtrace();
 
212
  std::cerr << "\n";
 
213
#endif
220
214
  switch(level)
221
215
  {
222
216
  case google::protobuf::LOGLEVEL_INFO:
225
219
  case google::protobuf::LOGLEVEL_ERROR:
226
220
  case google::protobuf::LOGLEVEL_FATAL:
227
221
  default:
 
222
#if 0
 
223
    std::cerr << "GoogleProtoErrorThrower(" << filename << ", " << line << ", " << message << ")";
 
224
#endif
228
225
    throw("error in google protocol buffer parsing");
229
226
  }
230
227
}
235
232
# if defined(HAVE_LOCALE_H)
236
233
  setlocale(LC_ALL, "");
237
234
# endif
238
 
  bindtextdomain("drizzle7", LOCALEDIR);
239
 
  textdomain("drizzle7");
 
235
  bindtextdomain("drizzle", LOCALEDIR);
 
236
  textdomain("drizzle");
240
237
#endif
241
238
 
242
239
  module::Registry &modules= module::Registry::singleton();
243
 
 
244
 
  drizzled::internal::my_progname= argv[0]; 
245
 
  drizzled::internal::my_init();
246
 
 
 
240
  plugin::Client *client;
 
241
 
 
242
  MY_INIT(argv[0]);             // init my_sys library & pthreads
247
243
  /* nothing should come before this line ^^^ */
248
244
 
249
245
  /* Set signal used to kill Drizzle */
253
249
 
254
250
  /* Function generates error messages before abort */
255
251
  error_handler_hook= my_message_sql;
256
 
 
257
 
  /* init_common_variables must get basic settings such as data_home_dir and plugin_load_list. */
258
 
  if (not init_variables_before_daemonizing(argc, argv))
259
 
  {
260
 
    unireg_abort << "init_variables_before_daemonizing() failed";                               // Will do exit
261
 
  }
262
 
 
263
 
  if (opt_daemon and was_help_requested() == false)
264
 
  {
265
 
    if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
266
 
    {
267
 
      perror("Failed to ignore SIGHUP");
268
 
    }
269
 
    if (daemonize())
270
 
    {
271
 
      unireg_abort << "--daemon failed";
272
 
    }
273
 
  }
274
 
 
275
 
  if (not init_variables_after_daemonizing(modules))
276
 
  {
277
 
    unireg_abort << "init_variables_after_daemonizing() failed";                                // Will do exit
278
 
  }
279
 
 
 
252
  /* init_common_variables must get basic settings such as data_home_dir
 
253
     and plugin_load_list. */
 
254
  if (init_common_variables(argc, argv, modules))
 
255
    unireg_abort(1);                            // Will do exit
280
256
 
281
257
  /*
282
258
    init signals & alarm
285
261
  init_signals();
286
262
 
287
263
 
288
 
  select_thread= pthread_self();
 
264
  select_thread=pthread_self();
289
265
  select_thread_in_use=1;
290
266
 
291
 
  if (was_help_requested() == false)
 
267
  if (not opt_help)
292
268
  {
293
269
    if (chdir(getDataHome().file_string().c_str()))
294
270
    {
295
 
      unireg_abort << "Data directory " << getDataHome().file_string() << " does not exist";
296
 
    }
297
 
 
298
 
    ifstream old_uuid_file ("server.uuid");
299
 
    if (old_uuid_file.is_open())
300
 
    {
301
 
      getline(old_uuid_file, server_uuid);
302
 
      old_uuid_file.close();
303
 
    } 
304
 
    else 
305
 
    {
306
 
      uuid_t uu;
307
 
      char uuid_string[37];
308
 
      uuid_generate_random(uu);
309
 
      uuid_unparse(uu, uuid_string);
310
 
      ofstream new_uuid_file ("server.uuid");
311
 
      new_uuid_file << uuid_string;
312
 
      new_uuid_file.close();
313
 
      server_uuid= string(uuid_string);
314
 
    }
315
 
 
316
 
    if (mkdir("local", 0700) == -1)
317
 
    {
318
 
      switch (errno)
319
 
      {
320
 
      case EEXIST:
321
 
        break;
322
 
 
323
 
      case EACCES:
324
 
        {
325
 
          char cwd[1024];
326
 
          unireg_abort << "Could not create local catalog, permission denied in directory:" << getcwd(cwd, sizeof(cwd));
327
 
        }
328
 
 
329
 
      default:
330
 
        {
331
 
          char cwd[1024];
332
 
          unireg_abort << "Could not create local catalog, in directory:" << getcwd(cwd, sizeof(cwd)) << " system error was:" << strerror(errno);
333
 
        }
334
 
      }
335
 
    }
336
 
 
337
 
    if (chdir("local") == -1)
338
 
    {
339
 
      unireg_abort << "Local catalog does not exist, was unable to chdir() to " << getDataHome().file_string();
340
 
    }
341
 
 
342
 
    setFullDataHome(boost::filesystem::system_complete(getDataHome()));
343
 
    errmsg_printf(error::INFO, "Data Home directory is : %s", getFullDataHome().native_file_string().c_str());
 
271
      errmsg_printf(ERRMSG_LVL_ERROR,
 
272
                    _("Data directory %s does not exist\n"),
 
273
                    getDataHome().file_string().c_str());
 
274
      unireg_abort(1);
 
275
    }
 
276
    if (mkdir("local", 0700))
 
277
    {
 
278
      /* We don't actually care */
 
279
    }
 
280
    if (chdir("local"))
 
281
    {
 
282
      errmsg_printf(ERRMSG_LVL_ERROR,
 
283
                    _("Local catalog %s/local does not exist\n"),
 
284
                    getDataHome().file_string().c_str());
 
285
      unireg_abort(1);
 
286
    }
 
287
 
 
288
    full_data_home= fs::system_complete(getDataHome());
 
289
    getDataHomeCatalog()= "./";
 
290
    getDataHome()= "../";
344
291
  }
345
292
 
 
293
 
 
294
 
346
295
  if (server_id == 0)
347
296
  {
348
297
    server_id= 1;
349
298
  }
350
299
 
351
 
  try
352
 
  {
353
 
    init_server_components(modules);
354
 
  }
355
 
  catch (abort_exception& ex)
356
 
  {
357
 
#if defined(DEBUG)
358
 
    cout << _("Drizzle has receieved an abort event.") << endl;
359
 
    cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
360
 
    cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
361
 
    cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
362
 
#endif
363
 
    unireg_abort << "init_server_components() failed";
364
 
  }
365
 
 
 
300
  if (init_server_components(modules))
 
301
    unireg_abort(1);
366
302
 
367
303
  /**
368
304
   * This check must be done after init_server_components for now
375
311
   *
376
312
   * not checking return since unireg_abort() hangs
377
313
   */
378
 
  (void) ReplicationServices::evaluateRegisteredPlugins();
 
314
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
315
    (void) replication_services.evaluateRegisteredPlugins();
379
316
 
380
317
  if (plugin::Listen::setup())
381
 
  {
382
 
    unireg_abort << "Failed plugin::Listen::setup()";
383
 
  }
 
318
    unireg_abort(1);
 
319
 
384
320
 
385
321
  assert(plugin::num_trx_monitored_objects > 0);
386
 
  drizzle_rm_tmp_tables();
387
 
  errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname, PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
 
322
  if (drizzle_rm_tmp_tables() ||
 
323
      my_tz_init((Session *)0, default_tz_name))
 
324
  {
 
325
    abort_loop= true;
 
326
    select_thread_in_use=0;
 
327
    (void) pthread_kill(signal_thread, SIGTERM);
 
328
 
 
329
    (void) unlink(pid_file.file_string().c_str());      // Not needed anymore
 
330
 
 
331
    exit(1);
 
332
  }
 
333
 
 
334
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
 
335
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
 
336
 
 
337
 
 
338
  TransactionServices &transaction_services= TransactionServices::singleton();
388
339
 
389
340
  /* Send server startup event */
390
341
  {
391
 
    Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
392
 
    setCurrentSession(session.get());
393
 
    TransactionServices::sendStartupEvent(*session);
394
 
    plugin_startup_window(modules, *session.get());
395
 
  }
396
 
 
397
 
  if (opt_daemon)
398
 
  {
399
 
    daemon_is_ready();
400
 
  }
401
 
 
402
 
  /*
403
 
    Listen for new connections and start new session for each connection
 
342
    Session *session;
 
343
 
 
344
    if ((session= new Session(plugin::Listen::getNullClient())))
 
345
    {
 
346
      currentSession().release();
 
347
      currentSession().reset(session);
 
348
      transaction_services.sendStartupEvent(session);
 
349
      delete session;
 
350
    }
 
351
  }
 
352
 
 
353
 
 
354
  /* Listen for new connections and start new session for each connection
404
355
     accepted. The listen.getClient() method will return NULL when the server
405
 
     should be shutdown.
406
 
   */
407
 
  while (plugin::Client* client= plugin::Listen::getClient())
 
356
     should be shutdown. */
 
357
  while ((client= plugin::Listen::getClient()) != NULL)
408
358
  {
409
 
    Session::shared_ptr session= Session::make_shared(client, client->catalog());
 
359
    Session::shared_ptr session(new Session(client));
 
360
 
 
361
    if (not session)
 
362
    {
 
363
      delete client;
 
364
      continue;
 
365
    }
410
366
 
411
367
    /* If we error on creation we drop the connection and delete the session. */
412
368
    if (Session::schedule(session))
415
371
 
416
372
  /* Send server shutdown event */
417
373
  {
418
 
    Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
419
 
    setCurrentSession(session.get());
420
 
    TransactionServices::sendShutdownEvent(*session.get());
 
374
    Session *session;
 
375
 
 
376
    if ((session= new Session(plugin::Listen::getNullClient())))
 
377
    {
 
378
      currentSession().release();
 
379
      currentSession().reset(session);
 
380
      transaction_services.sendShutdownEvent(session);
 
381
      delete session;
 
382
    }
421
383
  }
422
384
 
423
385
  {
424
 
    boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
 
386
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
425
387
    select_thread_in_use= false;                        // For close_connections
426
388
  }
427
389
  COND_thread_count.notify_all();
428
390
 
429
391
  /* Wait until cleanup is done */
430
 
  session::Cache::shutdownSecond();
 
392
  {
 
393
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
394
    while (not ready_to_exit)
 
395
      COND_server_end.wait(scopedLock);
 
396
  }
431
397
 
432
398
  clean_up(1);
433
399
  module::Registry::shutdown();