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/unireg.h>
00067 #include <drizzled/util/backtrace.h>
00068 #include <drizzled/current_session.h>
00069 #include <drizzled/daemon.h>
00070 #include <drizzled/diagnostics_area.h>
00071 #include <drizzled/sql_base.h>
00072 #include <drizzled/sql_lex.h>
00073 #include <drizzled/system_variables.h>
00074
00075 using namespace drizzled;
00076 using namespace std;
00077
00078 static pthread_t select_thread;
00079 static uint32_t thr_kill_signal;
00080
00081 extern bool opt_daemon;
00082
00083
00088 static void my_message_sql(drizzled::error_t error, const char *str, myf MyFlags)
00089 {
00090 Session* session= current_session;
00091
00092
00093
00094
00095 if (session)
00096 {
00097 if (MyFlags & ME_FATALERROR)
00098 {
00099 session->is_fatal_error= 1;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 if (! (session->lex().current_select &&
00115 session->lex().current_select->no_error && !session->is_fatal_error))
00116 {
00117 if (! session->main_da().is_error())
00118 {
00119 if (error == EE_OK)
00120 error= ER_UNKNOWN_ERROR;
00121
00122 if (str == NULL)
00123 str= ER(error);
00124
00125 session->main_da().set_error_status(error, str);
00126 }
00127 }
00128
00129 if (!session->no_warnings_for_error && !session->is_fatal_error)
00130 {
00131
00132
00133
00134
00135 session->no_warnings_for_error= true;
00136 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
00137 session->no_warnings_for_error= false;
00138 }
00139 }
00140
00141 if (not session || MyFlags & ME_NOREFRESH)
00142 {
00143 errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
00144 }
00145 }
00146
00147 static void init_signals(void)
00148 {
00149 sigset_t set;
00150 struct sigaction sa;
00151
00152 if (not (getDebug().test(debug::NO_STACKTRACE) ||
00153 getDebug().test(debug::CORE_ON_SIGNAL)))
00154 {
00155 sa.sa_flags = SA_RESETHAND | SA_NODEFER;
00156 sigemptyset(&sa.sa_mask);
00157 sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
00158
00159 sa.sa_handler= drizzled_handle_segfault;
00160 sigaction(SIGSEGV, &sa, NULL);
00161 sigaction(SIGABRT, &sa, NULL);
00162 #ifdef SIGBUS
00163 sigaction(SIGBUS, &sa, NULL);
00164 #endif
00165 sigaction(SIGILL, &sa, NULL);
00166 sigaction(SIGFPE, &sa, NULL);
00167 }
00168
00169 if (getDebug().test(debug::CORE_ON_SIGNAL))
00170 {
00171
00172 struct rlimit rl;
00173 rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
00174 if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
00175 errmsg_printf(error::WARN,
00176 _("setrlimit could not change the size of core files "
00177 "to 'infinity'; We may not be able to generate a "
00178 "core file on signals"));
00179 }
00180 (void) sigemptyset(&set);
00181 ignore_signal(SIGPIPE);
00182 sigaddset(&set,SIGPIPE);
00183 #ifndef IGNORE_SIGHUP_SIGQUIT
00184 sigaddset(&set,SIGQUIT);
00185 sigaddset(&set,SIGHUP);
00186 #endif
00187 sigaddset(&set,SIGTERM);
00188
00189
00190 sigemptyset(&sa.sa_mask);
00191 sa.sa_flags = 0;
00192 sa.sa_handler = drizzled_print_signal_warning;
00193 sigaction(SIGTERM, &sa, NULL);
00194 sa.sa_flags = 0;
00195 sa.sa_handler = drizzled_print_signal_warning;
00196 sigaction(SIGHUP, &sa, NULL);
00197 #ifdef SIGTSTP
00198 sigaddset(&set,SIGTSTP);
00199 #endif
00200 if (getDebug().test(debug::ALLOW_SIGINT))
00201 {
00202 sa.sa_flags= 0;
00203 sa.sa_handler= drizzled_end_thread_signal;
00204 sigaction(thr_kill_signal, &sa, NULL);
00205
00206
00207 sigdelset(&set, thr_kill_signal);
00208 }
00209 else
00210 {
00211 sigaddset(&set,SIGINT);
00212 }
00213 sigprocmask(SIG_SETMASK,&set,NULL);
00214 pthread_sigmask(SIG_SETMASK,&set,NULL);
00215 return;
00216 }
00217
00218 static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
00219 const char* ,
00220 int, const string& ) throw(const char *)
00221 {
00222 switch(level)
00223 {
00224 case google::protobuf::LOGLEVEL_INFO:
00225 break;
00226 case google::protobuf::LOGLEVEL_WARNING:
00227 case google::protobuf::LOGLEVEL_ERROR:
00228 case google::protobuf::LOGLEVEL_FATAL:
00229 default:
00230 throw("error in google protocol buffer parsing");
00231 }
00232 }
00233
00234 int main(int argc, char **argv)
00235 {
00236 #if defined(ENABLE_NLS)
00237 # if defined(HAVE_LOCALE_H)
00238 setlocale(LC_ALL, "");
00239 # endif
00240 bindtextdomain("drizzle7", LOCALEDIR);
00241 textdomain("drizzle7");
00242 #endif
00243
00244 module::Registry &modules= module::Registry::singleton();
00245
00246 drizzled::internal::my_progname= argv[0];
00247 drizzled::internal::my_init();
00248
00249
00250
00251
00252 thr_kill_signal= SIGINT;
00253
00254 google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
00255
00256
00257 error_handler_hook= my_message_sql;
00258
00259
00260 if (not init_variables_before_daemonizing(argc, argv))
00261 {
00262 unireg_abort << "init_variables_before_daemonizing() failed";
00263 }
00264
00265 if (opt_daemon and was_help_requested() == false)
00266 {
00267 if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
00268 {
00269 perror("Failed to ignore SIGHUP");
00270 }
00271 if (daemonize())
00272 {
00273 unireg_abort << "--daemon failed";
00274 }
00275 }
00276
00277 if (not init_variables_after_daemonizing(modules))
00278 {
00279 unireg_abort << "init_variables_after_daemonizing() failed";
00280 }
00281
00282
00283
00284
00285
00286
00287 init_signals();
00288
00289
00290 select_thread= pthread_self();
00291 select_thread_in_use=1;
00292
00293 if (was_help_requested() == false)
00294 {
00295 if (chdir(getDataHome().file_string().c_str()))
00296 {
00297 unireg_abort << "Data directory " << getDataHome().file_string() << " does not exist";
00298 }
00299
00300 ifstream old_uuid_file ("server.uuid");
00301 if (old_uuid_file.is_open())
00302 {
00303 getline(old_uuid_file, server_uuid);
00304 old_uuid_file.close();
00305 }
00306 else
00307 {
00308 uuid_t uu;
00309 char uuid_string[37];
00310 uuid_generate_random(uu);
00311 uuid_unparse(uu, uuid_string);
00312 ofstream new_uuid_file ("server.uuid");
00313 new_uuid_file << uuid_string;
00314 new_uuid_file.close();
00315 server_uuid= string(uuid_string);
00316 }
00317
00318 if (mkdir("local", 0700) == -1)
00319 {
00320 switch (errno)
00321 {
00322 case EEXIST:
00323 break;
00324
00325 case EACCES:
00326 {
00327 char cwd[1024];
00328 unireg_abort << "Could not create local catalog, permission denied in directory:" << getcwd(cwd, sizeof(cwd));
00329 }
00330
00331 default:
00332 {
00333 char cwd[1024];
00334 unireg_abort << "Could not create local catalog, in directory:" << getcwd(cwd, sizeof(cwd)) << " system error was:" << strerror(errno);
00335 }
00336 }
00337 }
00338
00339 if (chdir("local") == -1)
00340 {
00341 unireg_abort << "Local catalog does not exist, was unable to chdir() to " << getDataHome().file_string();
00342 }
00343
00344 setFullDataHome(boost::filesystem::system_complete(getDataHome()));
00345 errmsg_printf(error::INFO, "Data Home directory is : %s", getFullDataHome().native_file_string().c_str());
00346 }
00347
00348 if (server_id == 0)
00349 {
00350 server_id= 1;
00351 }
00352
00353 try
00354 {
00355 init_server_components(modules);
00356 }
00357 catch (abort_exception& ex)
00358 {
00359 #if defined(DEBUG)
00360 cout << _("Drizzle has receieved an abort event.") << endl;
00361 cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
00362 cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
00363 cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
00364 #endif
00365 unireg_abort << "init_server_components() failed";
00366 }
00367
00368
00380 (void) ReplicationServices::evaluateRegisteredPlugins();
00381
00382 if (plugin::Listen::setup())
00383 {
00384 unireg_abort << "Failed plugin::Listen::setup()";
00385 }
00386
00387 assert(plugin::num_trx_monitored_objects > 0);
00388 drizzle_rm_tmp_tables();
00389 errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname, PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
00390
00391
00392 {
00393 Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
00394 setCurrentSession(session.get());
00395 TransactionServices::sendStartupEvent(*session);
00396 plugin_startup_window(modules, *session.get());
00397 }
00398
00399 if (opt_daemon)
00400 {
00401 daemon_is_ready();
00402 }
00403
00404
00405 errmsg_printf(error::INFO, "Drizzle startup complete, listening for connections will now begin.");
00406
00407
00408
00409
00410
00411
00412 while (plugin::Client* client= plugin::Listen::getClient())
00413 {
00414 Session::shared_ptr session= Session::make_shared(client, client->catalog());
00415
00416
00417 if (Session::schedule(session))
00418 Session::unlink(session);
00419 }
00420
00421
00422 {
00423 Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
00424 setCurrentSession(session.get());
00425 TransactionServices::sendShutdownEvent(*session.get());
00426 }
00427
00428 {
00429 boost::mutex::scoped_lock scopedLock(session::Cache::mutex());
00430 select_thread_in_use= false;
00431 }
00432 COND_thread_count.notify_all();
00433
00434
00435 session::Cache::shutdownSecond();
00436
00437 clean_up(1);
00438 module::Registry::shutdown();
00439 internal::my_end();
00440
00441 errmsg_printf(error::INFO, "Drizzle is now shutting down");
00442
00443 return 0;
00444 }
00445