00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <pthread.h>
00023 #include <signal.h>
00024 #include <sys/resource.h>
00025 #include <unistd.h>
00026 #include <sys/stat.h>
00027 #include <sys/types.h>
00028
00029
00030 #if TIME_WITH_SYS_TIME
00031 # include <sys/time.h>
00032 # include <time.h>
00033 #else
00034 # if HAVE_SYS_TIME_H
00035 # include <sys/time.h>
00036 # else
00037 # include <time.h>
00038 # endif
00039 #endif
00040
00041 #if defined(HAVE_LOCALE_H)
00042 # include <locale.h>
00043 #endif
00044
00045 #include <boost/filesystem.hpp>
00046
00047 #include <drizzled/abort_exception.h>
00048 #include <drizzled/catalog/local.h>
00049 #include <drizzled/configmake.h>
00050 #include <drizzled/data_home.h>
00051 #include <drizzled/debug.h>
00052 #include <drizzled/drizzled.h>
00053 #include <drizzled/errmsg_print.h>
00054 #include <drizzled/gettext.h>
00055 #include <drizzled/internal/my_sys.h>
00056 #include <drizzled/plugin.h>
00057 #include <drizzled/plugin/client.h>
00058 #include <drizzled/plugin/listen.h>
00059 #include <drizzled/plugin/monitored_in_transaction.h>
00060 #include <drizzled/pthread_globals.h>
00061 #include <drizzled/replication_services.h>
00062 #include <drizzled/session.h>
00063 #include <drizzled/session/cache.h>
00064 #include <drizzled/signal_handler.h>
00065 #include <drizzled/transaction_services.h>
00066 #include <drizzled/tztime.h>
00067 #include <drizzled/unireg.h>
00068 #include <drizzled/util/backtrace.h>
00069 #include <drizzled/current_session.h>
00070 #include <drizzled/daemon.h>
00071 #include <drizzled/sql_base.h>
00072 #include <drizzled/sql_lex.h>
00073
00074 using namespace drizzled;
00075 using namespace std;
00076
00077 static pthread_t select_thread;
00078 static uint32_t thr_kill_signal;
00079
00080 extern bool opt_daemon;
00081
00082
00087 static void my_message_sql(drizzled::error_t error, const char *str, myf MyFlags)
00088 {
00089 Session *session;
00090
00091
00092
00093
00094 if ((session= current_session))
00095 {
00096 if (MyFlags & ME_FATALERROR)
00097 session->is_fatal_error= 1;
00098
00099
00100
00101
00102
00103 if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
00104 return;
00105
00106
00107
00108
00109
00110 if (! (session->lex().current_select &&
00111 session->lex().current_select->no_error && !session->is_fatal_error))
00112 {
00113 if (! session->main_da.is_error())
00114 {
00115 if (error == EE_OK)
00116 error= ER_UNKNOWN_ERROR;
00117
00118 if (str == NULL)
00119 str= ER(error);
00120
00121 session->main_da.set_error_status(error, str);
00122 }
00123 }
00124
00125 if (!session->no_warnings_for_error && !session->is_fatal_error)
00126 {
00127
00128
00129
00130
00131 session->no_warnings_for_error= true;
00132 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
00133 session->no_warnings_for_error= false;
00134 }
00135 }
00136
00137 if (not session || MyFlags & ME_NOREFRESH)
00138 {
00139 errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
00140 }
00141 }
00142
00143 static void init_signals(void)
00144 {
00145 sigset_t set;
00146 struct sigaction sa;
00147
00148 if (not (getDebug().test(debug::NO_STACKTRACE) ||
00149 getDebug().test(debug::CORE_ON_SIGNAL)))
00150 {
00151 sa.sa_flags = SA_RESETHAND | SA_NODEFER;
00152 sigemptyset(&sa.sa_mask);
00153 sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
00154
00155 sa.sa_handler= drizzled_handle_segfault;
00156 sigaction(SIGSEGV, &sa, NULL);
00157 sigaction(SIGABRT, &sa, NULL);
00158 #ifdef SIGBUS
00159 sigaction(SIGBUS, &sa, NULL);
00160 #endif
00161 sigaction(SIGILL, &sa, NULL);
00162 sigaction(SIGFPE, &sa, NULL);
00163 }
00164
00165 if (getDebug().test(debug::CORE_ON_SIGNAL))
00166 {
00167
00168 struct rlimit rl;
00169 rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
00170 if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
00171 errmsg_printf(error::WARN,
00172 _("setrlimit could not change the size of core files "
00173 "to 'infinity'; We may not be able to generate a "
00174 "core file on signals"));
00175 }
00176 (void) sigemptyset(&set);
00177 ignore_signal(SIGPIPE);
00178 sigaddset(&set,SIGPIPE);
00179 #ifndef IGNORE_SIGHUP_SIGQUIT
00180 sigaddset(&set,SIGQUIT);
00181 sigaddset(&set,SIGHUP);
00182 #endif
00183 sigaddset(&set,SIGTERM);
00184
00185
00186 sigemptyset(&sa.sa_mask);
00187 sa.sa_flags = 0;
00188 sa.sa_handler = drizzled_print_signal_warning;
00189 sigaction(SIGTERM, &sa, NULL);
00190 sa.sa_flags = 0;
00191 sa.sa_handler = drizzled_print_signal_warning;
00192 sigaction(SIGHUP, &sa, NULL);
00193 #ifdef SIGTSTP
00194 sigaddset(&set,SIGTSTP);
00195 #endif
00196 if (getDebug().test(debug::ALLOW_SIGINT))
00197 {
00198 sa.sa_flags= 0;
00199 sa.sa_handler= drizzled_end_thread_signal;
00200 sigaction(thr_kill_signal, &sa, NULL);
00201
00202
00203 sigdelset(&set, thr_kill_signal);
00204 }
00205 else
00206 {
00207 sigaddset(&set,SIGINT);
00208 }
00209 sigprocmask(SIG_SETMASK,&set,NULL);
00210 pthread_sigmask(SIG_SETMASK,&set,NULL);
00211 return;
00212 }
00213
00214 static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
00215 const char* ,
00216 int, const string& ) throw(const char *)
00217 {
00218 switch(level)
00219 {
00220 case google::protobuf::LOGLEVEL_INFO:
00221 break;
00222 case google::protobuf::LOGLEVEL_WARNING:
00223 case google::protobuf::LOGLEVEL_ERROR:
00224 case google::protobuf::LOGLEVEL_FATAL:
00225 default:
00226 throw("error in google protocol buffer parsing");
00227 }
00228 }
00229
00230 int main(int argc, char **argv)
00231 {
00232 #if defined(ENABLE_NLS)
00233 # if defined(HAVE_LOCALE_H)
00234 setlocale(LC_ALL, "");
00235 # endif
00236 bindtextdomain("drizzle7", LOCALEDIR);
00237 textdomain("drizzle7");
00238 #endif
00239
00240 module::Registry &modules= module::Registry::singleton();
00241
00242 MY_INIT(argv[0]);
00243
00244
00245
00246 thr_kill_signal= SIGINT;
00247
00248 google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
00249
00250
00251 error_handler_hook= my_message_sql;
00252
00253
00254
00255 if (init_basic_variables(argc, argv))
00256 unireg_abort(1);
00257
00258 if (opt_daemon)
00259 {
00260 if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
00261 {
00262 perror("Failed to ignore SIGHUP");
00263 }
00264 if (daemonize())
00265 {
00266 fprintf(stderr, "failed to daemon() in order to daemonize\n");
00267 exit(EXIT_FAILURE);
00268 }
00269 }
00270
00271 if (init_remaining_variables(modules))
00272 unireg_abort(1);
00273
00274
00275
00276
00277
00278 init_signals();
00279
00280
00281 select_thread=pthread_self();
00282 select_thread_in_use=1;
00283
00284 if (not opt_help)
00285 {
00286 if (chdir(getDataHome().file_string().c_str()))
00287 {
00288 errmsg_printf(error::ERROR,
00289 _("Data directory %s does not exist\n"),
00290 getDataHome().file_string().c_str());
00291 unireg_abort(1);
00292 }
00293 if (mkdir("local", 0700))
00294 {
00295
00296 }
00297 if (chdir("local"))
00298 {
00299 errmsg_printf(error::ERROR,
00300 _("Local catalog %s/local does not exist\n"),
00301 getDataHome().file_string().c_str());
00302 unireg_abort(1);
00303 }
00304
00305 boost::filesystem::path &full_data_home= getFullDataHome();
00306 full_data_home= boost::filesystem::system_complete(getDataHome());
00307 errmsg_printf(error::INFO, "Data Home directory is : %s", full_data_home.native_file_string().c_str());
00308 }
00309
00310
00311
00312 if (server_id == 0)
00313 {
00314 server_id= 1;
00315 }
00316
00317 try
00318 {
00319 if (init_server_components(modules))
00320 DRIZZLE_ABORT;
00321 }
00322 catch (abort_exception& ex)
00323 {
00324 #if defined(DEBUG)
00325 cout << _("Drizzle has receieved an abort event.") << endl;
00326 cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
00327 cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
00328 cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
00329 #endif
00330 unireg_abort(1);
00331 }
00332
00333
00345 ReplicationServices &replication_services= ReplicationServices::singleton();
00346 (void) replication_services.evaluateRegisteredPlugins();
00347
00348 if (plugin::Listen::setup())
00349 unireg_abort(1);
00350
00351 assert(plugin::num_trx_monitored_objects > 0);
00352 if (drizzle_rm_tmp_tables())
00353 {
00354 abort_loop= true;
00355 select_thread_in_use=0;
00356 (void) pthread_kill(signal_thread, SIGTERM);
00357
00358 (void) unlink(pid_file.file_string().c_str());
00359
00360 unireg_abort(1);
00361 }
00362
00363 errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
00364 PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
00365
00366
00367 TransactionServices &transaction_services= TransactionServices::singleton();
00368
00369
00370 {
00371 Session::shared_ptr session;
00372
00373 if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
00374 {
00375 currentSession().release();
00376 currentSession().reset(session.get());
00377
00378
00379 transaction_services.sendStartupEvent(*session);
00380
00381 plugin_startup_window(modules, *(session.get()));
00382 }
00383 }
00384
00385 if (opt_daemon)
00386 daemon_is_ready();
00387
00388
00389
00390
00391
00392
00393 plugin::Client *client;
00394 while ((client= plugin::Listen::getClient()) != NULL)
00395 {
00396 Session::shared_ptr session;
00397 session= Session::make_shared(client, client->catalog());
00398
00399 if (not session)
00400 {
00401 delete client;
00402 continue;
00403 }
00404
00405
00406 if (Session::schedule(session))
00407 Session::unlink(session);
00408 }
00409
00410
00411 {
00412 Session::shared_ptr session;
00413
00414 if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
00415 {
00416 currentSession().release();
00417 currentSession().reset(session.get());
00418 transaction_services.sendShutdownEvent(*session.get());
00419 }
00420 }
00421
00422 {
00423 boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
00424 select_thread_in_use= false;
00425 }
00426 COND_thread_count.notify_all();
00427
00428
00429 session::Cache::singleton().shutdownSecond();
00430
00431 clean_up(1);
00432 module::Registry::shutdown();
00433 internal::my_end();
00434
00435 return 0;
00436 }
00437