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 <drizzled/configmake.h>
00023 #include <drizzled/atomics.h>
00024 #include <drizzled/data_home.h>
00025
00026 #include <netdb.h>
00027 #include <sys/types.h>
00028 #include <netinet/tcp.h>
00029 #include <netinet/in.h>
00030 #include <signal.h>
00031 #include <limits.h>
00032 #include <stdexcept>
00033
00034 #include <boost/program_options.hpp>
00035 #include <drizzled/program_options/config_file.h>
00036 #include <boost/thread/recursive_mutex.hpp>
00037 #include <boost/thread/mutex.hpp>
00038 #include <boost/thread/shared_mutex.hpp>
00039 #include <boost/thread/condition_variable.hpp>
00040 #include <boost/filesystem.hpp>
00041 #include <boost/detail/atomic_count.hpp>
00042
00043 #include <drizzled/cached_directory.h>
00044 #include <drizzled/charset.h>
00045 #include <drizzled/data_home.h>
00046 #include <drizzled/debug.h>
00047 #include <drizzled/definition/cache.h>
00048 #include <drizzled/drizzled.h>
00049 #include <drizzled/errmsg_print.h>
00050 #include <drizzled/error.h>
00051 #include <drizzled/global_buffer.h>
00052 #include <drizzled/internal/my_bit.h>
00053 #include <drizzled/internal/my_sys.h>
00054 #include <drizzled/item/cmpfunc.h>
00055 #include <drizzled/item/create.h>
00056 #include <drizzled/message/cache.h>
00057 #include <drizzled/module/load_list.h>
00058 #include <drizzled/module/registry.h>
00059 #include <drizzled/plugin/client.h>
00060 #include <drizzled/plugin/error_message.h>
00061 #include <drizzled/plugin/event_observer.h>
00062 #include <drizzled/plugin/listen.h>
00063 #include <drizzled/plugin/monitored_in_transaction.h>
00064 #include <drizzled/plugin/scheduler.h>
00065 #include <drizzled/plugin/storage_engine.h>
00066 #include <drizzled/plugin/xa_resource_manager.h>
00067 #include <drizzled/probes.h>
00068 #include <drizzled/replication_services.h>
00069 #include <drizzled/session.h>
00070 #include <drizzled/session/cache.h>
00071 #include <drizzled/show.h>
00072 #include <drizzled/sql_base.h>
00073 #include <drizzled/sql_parse.h>
00074 #include <drizzled/temporal_format.h>
00075 #include <drizzled/tztime.h>
00076 #include <drizzled/unireg.h>
00077 #include <plugin/myisam/myisam.h>
00078 #include <drizzled/typelib.h>
00079 #include <drizzled/visibility.h>
00080
00081 #include <google/protobuf/stubs/common.h>
00082
00083 #include <drizzled/refresh_version.h>
00084
00085 #if TIME_WITH_SYS_TIME
00086 # include <sys/time.h>
00087 # include <time.h>
00088 #else
00089 # if HAVE_SYS_TIME_H
00090 # include <sys/time.h>
00091 # else
00092 # include <time.h>
00093 # endif
00094 #endif
00095
00096 #ifdef HAVE_SYS_PRCTL_H
00097 #include <sys/prctl.h>
00098 #endif
00099 #include <sys/socket.h>
00100
00101
00102 #include <errno.h>
00103 #include <sys/stat.h>
00104 #include <drizzled/option.h>
00105 #ifdef HAVE_SYSENT_H
00106 #include <sysent.h>
00107 #endif
00108 #include <pwd.h>
00109 #include <grp.h>
00110
00111 #ifdef HAVE_SELECT_H
00112 # include <select.h>
00113 #endif
00114
00115 #ifdef HAVE_SYS_SELECT_H
00116 #include <sys/select.h>
00117 #endif
00118
00119 #include <sys/utsname.h>
00120
00121 #ifdef HAVE_SYS_MMAN_H
00122 #include <sys/mman.h>
00123 #endif
00124
00125 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00126 #include <ieeefp.h>
00127 #endif
00128
00129 #ifdef HAVE_FPU_CONTROL_H
00130 #include <fpu_control.h>
00131 #endif
00132
00133 #ifdef HAVE_SYS_FPU_H
00134
00135 #include <sys/fpu.h>
00136 #endif
00137
00138 #include <drizzled/internal/my_pthread.h>
00139 #include <drizzled/constrained_value.h>
00140
00141 #include <drizzled/gettext.h>
00142
00143
00144 #ifdef HAVE_VALGRIND
00145 #define IF_PURIFY(A,B) (A)
00146 #else
00147 #define IF_PURIFY(A,B) (B)
00148 #endif
00149
00150 #define MAX_MEM_TABLE_SIZE SIZE_MAX
00151 #include <iostream>
00152 #include <fstream>
00153
00154
00155 using namespace std;
00156 namespace fs=boost::filesystem;
00157 namespace po=boost::program_options;
00158 namespace dpo=drizzled::program_options;
00159
00160 bool opt_daemon= false;
00161
00162 namespace drizzled
00163 {
00164
00165 inline void setup_fpu()
00166 {
00167 #if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
00168
00169
00170
00171
00172
00173 #if defined(__i386__)
00174 fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00175 FP_X_IMP));
00176 #else
00177 fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
00178 FP_X_IMP));
00179 #endif
00180 #endif
00181
00182
00183
00184
00185
00186 #if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
00187 fpu_control_t cw;
00188 _FPU_GETCW(cw);
00189 cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
00190 _FPU_SETCW(cw);
00191 #endif
00192 }
00193
00194 #ifdef SOLARIS
00195 extern "C" int gethostname(char *name, int namelen);
00196 #endif
00197
00198 const char *first_keyword= "first";
00199 const char * const DRIZZLE_CONFIG_NAME= "drizzled";
00200
00201 #define GET_HA_ROWS GET_ULL
00202
00203 const char *tx_isolation_names[] =
00204 { "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
00205 NULL};
00206
00207 TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
00208 tx_isolation_names, NULL};
00209
00210
00211
00212
00213 bool opt_help= false;
00214
00215 arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
00216 {{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
00217 {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
00218 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
00219 {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
00220 {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
00221
00222
00223
00224 static bool opt_debugging= false;
00225 static uint32_t wake_thread;
00226 static char *drizzled_chroot;
00227 static const char *default_character_set_name;
00228 static const char *character_set_filesystem_name;
00229 static char *lc_time_names_name;
00230 static char *default_collation_name;
00231 static char *default_storage_engine_str;
00232 static const char *compiled_default_collation_name= "utf8_general_ci";
00233
00234
00235
00236 char *drizzled_user;
00237 bool volatile select_thread_in_use;
00238 bool volatile abort_loop;
00239 DRIZZLED_API bool volatile shutdown_in_progress;
00240 char *opt_scheduler_default;
00241 const char *opt_scheduler= NULL;
00242
00243 DRIZZLED_API size_t my_thread_stack_size= 0;
00244
00245
00246
00247
00248 plugin::StorageEngine *heap_engine;
00249 plugin::StorageEngine *myisam_engine;
00250
00251 bool calling_initgroups= false;
00253 uint32_t drizzled_bind_timeout;
00254 uint32_t dropping_tables, ha_open_options;
00255 uint32_t tc_heuristic_recover= 0;
00256 uint64_t session_startup_options;
00257 back_log_constraints back_log(50);
00258 DRIZZLED_API uint32_t server_id;
00259 uint64_t table_cache_size;
00260 size_t table_def_size;
00261 uint32_t global_thread_id= 1UL;
00262 pid_t current_pid;
00263
00264 extern const double log_10[309];
00265
00266 const double log_10[] = {
00267 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
00268 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
00269 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
00270 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
00271 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
00272 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
00273 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
00274 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
00275 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
00276 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
00277 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
00278 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
00279 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
00280 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
00281 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
00282 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
00283 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
00284 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
00285 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
00286 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
00287 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
00288 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
00289 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
00290 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
00291 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
00292 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
00293 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
00294 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
00295 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
00296 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
00297 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
00298 };
00299
00300 time_t server_start_time;
00301 time_t flush_status_time;
00302
00303 fs::path basedir(PREFIX);
00304 fs::path pid_file;
00305 fs::path secure_file_priv("");
00306 fs::path plugin_dir;
00307 fs::path system_config_dir(SYSCONFDIR);
00308
00309
00310 char *opt_tc_log_file;
00311 const key_map key_map_empty(0);
00312 key_map key_map_full(0);
00313
00314 std::string drizzle_tmpdir;
00315 char *opt_drizzle_tmpdir= NULL;
00316
00318 const char *in_left_expr_name= "<left expr>";
00320 const char *in_additional_cond= "<IN COND>";
00321 const char *in_having_cond= "<IN HAVING>";
00322
00323
00324
00325 FILE *stderror_file=0;
00326
00327 drizzle_system_variables global_system_variables;
00328 drizzle_system_variables max_system_variables;
00329 global_counters current_global_counters;
00330
00331 DRIZZLED_API const CHARSET_INFO *system_charset_info;
00332 const CHARSET_INFO *files_charset_info;
00333 const CHARSET_INFO *table_alias_charset;
00334 const CHARSET_INFO *character_set_filesystem;
00335
00336 MY_LOCALE *my_default_lc_time_names;
00337
00338 SHOW_COMP_OPTION have_symlink;
00339
00340 boost::condition_variable_any COND_refresh;
00341 boost::condition_variable COND_thread_count;
00342 pthread_t signal_thread;
00343
00344
00345
00346 int cleanup_done;
00347
00348 passwd *user_info;
00349
00350 boost::detail::atomic_count connection_count(0);
00351
00352 global_buffer_constraint<uint64_t> global_sort_buffer(0);
00353 global_buffer_constraint<uint64_t> global_join_buffer(0);
00354 global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
00355 global_buffer_constraint<uint64_t> global_read_buffer(0);
00356
00357 DRIZZLED_API size_t transaction_message_threshold;
00358
00359 static void drizzle_init_variables(void);
00360 static void get_options();
00361 static void fix_paths();
00362
00363 static void usage(void);
00364 void close_connections(void);
00365
00366 fs::path base_plugin_dir(PKGPLUGINDIR);
00367
00368 po::options_description config_options(_("Config File Options"));
00369 po::options_description long_options(_("Kernel Options"));
00370 po::options_description plugin_load_options(_("Plugin Loading Options"));
00371 po::options_description plugin_options(_("Plugin Options"));
00372 po::options_description initial_options(_("Config and Plugin Loading"));
00373 po::options_description full_options(_("Kernel and Plugin Loading and Plugin"));
00374 vector<string> unknown_options;
00375 vector<string> defaults_file_list;
00376 po::variables_map vm;
00377
00378 po::variables_map &getVariablesMap()
00379 {
00380 return vm;
00381 }
00382
00383 namespace
00384 {
00385
00386 std::string &getGlobHostname()
00387 {
00388 static std::string glob_hostname("localhost");
00389 return glob_hostname;
00390 }
00391
00392 void setServerHostname(const std::string &hostname)
00393 {
00394 getGlobHostname()= hostname;
00395 }
00396 }
00397
00398 const std::string &getServerHostname()
00399 {
00400 return getGlobHostname();
00401 }
00402
00403
00404
00405
00406
00407 void close_connections(void)
00408 {
00409
00410 plugin::Listen::shutdown();
00411
00412
00413 {
00414 boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
00415
00416 while (select_thread_in_use)
00417 {
00418 boost::xtime xt;
00419 xtime_get(&xt, boost::TIME_UTC);
00420 xt.sec += 2;
00421
00422 for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
00423 {
00424 bool success= COND_thread_count.timed_wait(scopedLock, xt);
00425 if (not success)
00426 break;
00427 }
00428 }
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 {
00439 boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
00440 session::Cache::list list= session::Cache::singleton().getCache();
00441
00442 for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
00443 {
00444 Session::shared_ptr tmp(*it);
00445
00446 tmp->setKilled(Session::KILL_CONNECTION);
00447 tmp->scheduler->killSession(tmp.get());
00448 DRIZZLE_CONNECTION_DONE(tmp->thread_id);
00449
00450 tmp->lockOnSys();
00451 }
00452 }
00453
00454 if (session::Cache::singleton().count())
00455 sleep(2);
00456
00457
00458
00459
00460
00461
00462 for (;;)
00463 {
00464 boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
00465 session::Cache::list list= session::Cache::singleton().getCache();
00466
00467 if (list.empty())
00468 {
00469 break;
00470 }
00471
00472 list.front()->getClient()->close();
00473 }
00474 }
00475
00476
00477 void unireg_abort(int exit_code)
00478 {
00479
00480 if (exit_code)
00481 {
00482 errmsg_printf(error::ERROR, _("Aborting"));
00483 }
00484 else if (opt_help)
00485 {
00486 usage();
00487 }
00488
00489 clean_up(!opt_help && (exit_code));
00490 internal::my_end();
00491 exit(exit_code);
00492 }
00493
00494
00495 void clean_up(bool print_message)
00496 {
00497 if (cleanup_done++)
00498 return;
00499
00500 table_cache_free();
00501 free_charsets();
00502 module::Registry &modules= module::Registry::singleton();
00503 modules.shutdownModules();
00504
00505 deinit_temporal_formats();
00506
00507 #if GOOGLE_PROTOBUF_VERSION >= 2001000
00508 google::protobuf::ShutdownProtobufLibrary();
00509 #endif
00510
00511 (void) unlink(pid_file.file_string().c_str());
00512
00513 if (print_message && server_start_time)
00514 errmsg_printf(drizzled::error::INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
00515
00516 session::Cache::singleton().shutdownFirst();
00517
00518
00519
00520
00521
00522 }
00523
00524
00525
00526
00527 passwd *check_user(const char *user)
00528 {
00529 passwd *tmp_user_info;
00530 uid_t user_id= geteuid();
00531
00532
00533 if (user_id)
00534 {
00535 if (user)
00536 {
00537
00538 tmp_user_info= getpwnam(user);
00539 if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
00540 global_system_variables.log_warnings)
00541 errmsg_printf(error::WARN, _("One can only use the --user switch "
00542 "if running as root\n"));
00543 }
00544 return NULL;
00545 }
00546 if (not user)
00547 {
00548 errmsg_printf(error::ERROR, _("Fatal error: Please read \"Security\" section of "
00549 "the manual to find out how to run drizzled as root"));
00550 unireg_abort(1);
00551 }
00552
00553 if (not strcmp(user, "root"))
00554 return NULL;
00555
00556 if (!(tmp_user_info= getpwnam(user)))
00557 {
00558
00559 const char *pos;
00560 for (pos= user; my_isdigit(&my_charset_utf8_general_ci,*pos); pos++) ;
00561 if (*pos)
00562 goto err;
00563 if (!(tmp_user_info= getpwuid(atoi(user))))
00564 goto err;
00565 }
00566 return tmp_user_info;
00567
00568 err:
00569 errmsg_printf(error::ERROR, _("Fatal error: Can't change to run as user '%s' ; "
00570 "Please check that the user exists!\n"),user);
00571 unireg_abort(1);
00572
00573 #ifdef PR_SET_DUMPABLE
00574 if (getDebug().test(debug::CORE_ON_SIGNAL))
00575 {
00576
00577 (void) prctl(PR_SET_DUMPABLE, 1);
00578 }
00579 #endif
00580
00581
00582 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
00583 return NULL;
00584 #endif
00585
00586 }
00587
00588 void set_user(const char *user, passwd *user_info_arg)
00589 {
00590 assert(user_info_arg != 0);
00591 initgroups((char*) user, user_info_arg->pw_gid);
00592 if (setgid(user_info_arg->pw_gid) == -1)
00593 {
00594 sql_perror(_("Set process group ID failed"));
00595 unireg_abort(1);
00596 }
00597 if (setuid(user_info_arg->pw_uid) == -1)
00598 {
00599 sql_perror(_("Set process user ID failed"));
00600 unireg_abort(1);
00601 }
00602 }
00603
00604
00605
00607 static void set_root(const char *path)
00608 {
00609 if ((chroot(path) == -1) || !chdir("/"))
00610 {
00611 sql_perror(_("Process chroot failed"));
00612 unireg_abort(1);
00613 }
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 void drizzled::Session::unlink(session_id_t &session_id)
00626 {
00627 Session::shared_ptr session= session::Cache::singleton().find(session_id);
00628
00629 if (session)
00630 unlink(session);
00631 }
00632
00633 void drizzled::Session::unlink(Session::shared_ptr &session)
00634 {
00635 --connection_count;
00636
00637 session->cleanup();
00638
00639 boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
00640
00641 if (unlikely(plugin::EventObserver::disconnectSession(*session)))
00642 {
00643
00644 }
00645 session::Cache::singleton().erase(session);
00646 }
00647
00648
00649 #ifndef SA_RESETHAND
00650 #define SA_RESETHAND 0
00651 #endif
00652 #ifndef SA_NODEFER
00653 #define SA_NODEFER 0
00654 #endif
00655
00656
00657
00658
00659 const char *load_default_groups[]=
00660 {
00661 DRIZZLE_CONFIG_NAME, "server", 0, 0
00662 };
00663
00664 static void find_plugin_dir(string progname)
00665 {
00666 fs::path full_progname(fs::system_complete(progname));
00667
00668 fs::path progdir(full_progname.parent_path());
00669 if (progdir.filename() == ".libs")
00670 {
00671 progdir= progdir.parent_path();
00672 }
00673
00674 if (fs::exists(progdir / "drizzled.lo") || fs::exists(progdir / "drizzled.o"))
00675 {
00676
00677 base_plugin_dir= progdir.parent_path();
00678 base_plugin_dir /= "plugin";
00679 base_plugin_dir /= ".libs";
00680 }
00681
00682 if (plugin_dir.root_directory() == "")
00683 {
00684 fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
00685 full_plugin_dir /= plugin_dir;
00686 plugin_dir= full_plugin_dir;
00687 }
00688 }
00689
00690 static void notify_plugin_dir(fs::path in_plugin_dir)
00691 {
00692 plugin_dir= in_plugin_dir;
00693 if (plugin_dir.root_directory() == "")
00694 {
00695 fs::path full_plugin_dir(fs::system_complete(basedir));
00696 full_plugin_dir /= plugin_dir;
00697 plugin_dir= full_plugin_dir;
00698 }
00699 }
00700
00701 static void expand_secure_file_priv(fs::path in_secure_file_priv)
00702 {
00703 secure_file_priv= fs::system_complete(in_secure_file_priv);
00704 }
00705
00706 static void check_limits_aii(uint64_t in_auto_increment_increment)
00707 {
00708 global_system_variables.auto_increment_increment= 1;
00709 if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
00710 {
00711 cout << _("Error: Invalid Value for auto_increment_increment");
00712 exit(-1);
00713 }
00714 global_system_variables.auto_increment_increment= in_auto_increment_increment;
00715 }
00716
00717 static void check_limits_aio(uint64_t in_auto_increment_offset)
00718 {
00719 global_system_variables.auto_increment_offset= 1;
00720 if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
00721 {
00722 cout << _("Error: Invalid Value for auto_increment_offset");
00723 exit(-1);
00724 }
00725 global_system_variables.auto_increment_offset= in_auto_increment_offset;
00726 }
00727
00728 static void check_limits_completion_type(uint32_t in_completion_type)
00729 {
00730 global_system_variables.completion_type= 0;
00731 if (in_completion_type > 2)
00732 {
00733 cout << _("Error: Invalid Value for completion_type");
00734 exit(-1);
00735 }
00736 global_system_variables.completion_type= in_completion_type;
00737 }
00738
00739
00740 static void check_limits_dpi(uint32_t in_div_precincrement)
00741 {
00742 global_system_variables.div_precincrement= 4;
00743 if (in_div_precincrement > DECIMAL_MAX_SCALE)
00744 {
00745 cout << _("Error: Invalid Value for div-precision-increment");
00746 exit(-1);
00747 }
00748 global_system_variables.div_precincrement= in_div_precincrement;
00749 }
00750
00751 static void check_limits_gcml(uint64_t in_group_concat_max_len)
00752 {
00753 global_system_variables.group_concat_max_len= 1024;
00754 if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
00755 {
00756 cout << _("Error: Invalid Value for group_concat_max_len");
00757 exit(-1);
00758 }
00759 global_system_variables.group_concat_max_len= in_group_concat_max_len;
00760 }
00761
00762 static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
00763 {
00764 global_system_variables.join_buff_size= (128*1024L);
00765 if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
00766 {
00767 cout << _("Error: Invalid Value for join_buffer_size");
00768 exit(-1);
00769 }
00770 in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
00771 global_system_variables.join_buff_size= in_join_buffer_size;
00772 }
00773
00774 static void check_limits_map(uint32_t in_max_allowed_packet)
00775 {
00776 global_system_variables.max_allowed_packet= (64*1024*1024L);
00777 if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
00778 {
00779 cout << _("Error: Invalid Value for max_allowed_packet");
00780 exit(-1);
00781 }
00782 in_max_allowed_packet-= in_max_allowed_packet % 1024;
00783 global_system_variables.max_allowed_packet= in_max_allowed_packet;
00784 }
00785
00786 static void check_limits_max_err_cnt(uint64_t in_max_error_count)
00787 {
00788 global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
00789 if (in_max_error_count > 65535)
00790 {
00791 cout << _("Error: Invalid Value for max_error_count");
00792 exit(-1);
00793 }
00794 global_system_variables.max_error_count= in_max_error_count;
00795 }
00796
00797 static void check_limits_mhts(uint64_t in_max_heap_table_size)
00798 {
00799 global_system_variables.max_heap_table_size= (16*1024*1024L);
00800 if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
00801 {
00802 cout << _("Error: Invalid Value for max_heap_table_size");
00803 exit(-1);
00804 }
00805 in_max_heap_table_size-= in_max_heap_table_size % 1024;
00806 global_system_variables.max_heap_table_size= in_max_heap_table_size;
00807 }
00808
00809 static void check_limits_merl(uint64_t in_min_examined_row_limit)
00810 {
00811 global_system_variables.min_examined_row_limit= 0;
00812 if (in_min_examined_row_limit > ULONG_MAX)
00813 {
00814 cout << _("Error: Invalid Value for min_examined_row_limit");
00815 exit(-1);
00816 }
00817 global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
00818 }
00819
00820 static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
00821 {
00822 global_system_variables.max_join_size= INT32_MAX;
00823 if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
00824 {
00825 cout << _("Error: Invalid Value for max_join_size");
00826 exit(-1);
00827 }
00828 global_system_variables.max_join_size= in_max_join_size;
00829 }
00830
00831 static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
00832 {
00833 global_system_variables.max_length_for_sort_data= 1024;
00834 if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
00835 {
00836 cout << _("Error: Invalid Value for max_length_for_sort_data");
00837 exit(-1);
00838 }
00839 global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
00840 }
00841
00842 static void check_limits_msfk(uint64_t in_max_seeks_for_key)
00843 {
00844 global_system_variables.max_seeks_for_key= ULONG_MAX;
00845 if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
00846 {
00847 cout << _("Error: Invalid Value for max_seeks_for_key");
00848 exit(-1);
00849 }
00850 global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
00851 }
00852
00853 static void check_limits_max_sort_length(size_t in_max_sort_length)
00854 {
00855 global_system_variables.max_sort_length= 1024;
00856 if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
00857 {
00858 cout << _("Error: Invalid Value for max_sort_length");
00859 exit(-1);
00860 }
00861 global_system_variables.max_sort_length= in_max_sort_length;
00862 }
00863
00864 static void check_limits_osd(uint32_t in_optimizer_search_depth)
00865 {
00866 global_system_variables.optimizer_search_depth= 0;
00867 if (in_optimizer_search_depth > MAX_TABLES + 2)
00868 {
00869 cout << _("Error: Invalid Value for optimizer_search_depth");
00870 exit(-1);
00871 }
00872 global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
00873 }
00874
00875 static void check_limits_pbs(uint64_t in_preload_buff_size)
00876 {
00877 global_system_variables.preload_buff_size= (32*1024L);
00878 if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
00879 {
00880 cout << _("Error: Invalid Value for preload_buff_size");
00881 exit(-1);
00882 }
00883 global_system_variables.preload_buff_size= in_preload_buff_size;
00884 }
00885
00886 static void check_limits_qabs(uint32_t in_query_alloc_block_size)
00887 {
00888 global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
00889 if (in_query_alloc_block_size < 1024)
00890 {
00891 cout << _("Error: Invalid Value for query_alloc_block_size");
00892 exit(-1);
00893 }
00894 in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
00895 global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
00896 }
00897
00898 static void check_limits_qps(uint32_t in_query_prealloc_size)
00899 {
00900 global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
00901 if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
00902 {
00903 cout << _("Error: Invalid Value for query_prealloc_size");
00904 exit(-1);
00905 }
00906 in_query_prealloc_size-= in_query_prealloc_size % 1024;
00907 global_system_variables.query_prealloc_size= in_query_prealloc_size;
00908 }
00909
00910 static void check_limits_rabs(size_t in_range_alloc_block_size)
00911 {
00912 global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
00913 if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
00914 {
00915 cout << _("Error: Invalid Value for range_alloc_block_size");
00916 exit(-1);
00917 }
00918 in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
00919 global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
00920 }
00921
00922 static void check_limits_read_buffer_size(int32_t in_read_buff_size)
00923 {
00924 global_system_variables.read_buff_size= (128*1024L);
00925 if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
00926 {
00927 cout << _("Error: Invalid Value for read_buff_size");
00928 exit(-1);
00929 }
00930 in_read_buff_size-= in_read_buff_size % IO_SIZE;
00931 global_system_variables.read_buff_size= in_read_buff_size;
00932 }
00933
00934 static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
00935 {
00936 global_system_variables.read_rnd_buff_size= (256*1024L);
00937 if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
00938 {
00939 cout << _("Error: Invalid Value for read_rnd_buff_size");
00940 exit(-1);
00941 }
00942 global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
00943 }
00944
00945 static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
00946 {
00947 global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
00948 if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
00949 {
00950 cout << _("Error: Invalid Value for sort_buff_size");
00951 exit(-1);
00952 }
00953 global_system_variables.sortbuff_size= in_sortbuff_size;
00954 }
00955
00956 static void check_limits_tdc(uint32_t in_table_def_size)
00957 {
00958 table_def_size= 128;
00959 if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
00960 {
00961 cout << _("Error: Invalid Value for table_def_size");
00962 exit(-1);
00963 }
00964 table_def_size= in_table_def_size;
00965 }
00966
00967 static void check_limits_toc(uint32_t in_table_cache_size)
00968 {
00969 table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
00970 if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
00971 {
00972 cout << _("Error: Invalid Value for table_cache_size");
00973 exit(-1);
00974 }
00975 table_cache_size= in_table_cache_size;
00976 }
00977
00978 static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
00979 {
00980 table_lock_wait_timeout= 50;
00981 if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
00982 {
00983 cout << _("Error: Invalid Value for table_lock_wait_timeout");
00984 exit(-1);
00985 }
00986 table_lock_wait_timeout= in_table_lock_wait_timeout;
00987 }
00988
00989 static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
00990 {
00991 my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
00992 }
00993
00994 static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
00995 {
00996 global_system_variables.tmp_table_size= 16*1024*1024L;
00997 if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
00998 {
00999 cout << _("Error: Invalid Value for table_lock_wait_timeout");
01000 exit(-1);
01001 }
01002 global_system_variables.tmp_table_size= in_tmp_table_size;
01003 }
01004
01005 static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
01006 {
01007 transaction_message_threshold= 1024*1024;
01008 if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
01009 {
01010 cout << _("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
01011 exit(-1);
01012 }
01013 transaction_message_threshold= in_transaction_message_threshold;
01014 }
01015
01016 static void process_defaults_files()
01017 {
01018 for (vector<string>::iterator iter= defaults_file_list.begin();
01019 iter != defaults_file_list.end();
01020 ++iter)
01021 {
01022 fs::path file_location= *iter;
01023
01024 ifstream input_defaults_file(file_location.file_string().c_str());
01025
01026 po::parsed_options file_parsed=
01027 dpo::parse_config_file(input_defaults_file, full_options, true);
01028 vector<string> file_unknown=
01029 po::collect_unrecognized(file_parsed.options, po::include_positional);
01030
01031 for (vector<string>::iterator it= file_unknown.begin();
01032 it != file_unknown.end();
01033 ++it)
01034 {
01035 string new_unknown_opt("--");
01036 new_unknown_opt.append(*it);
01037 ++it;
01038 if (it != file_unknown.end())
01039 {
01040 if ((*it) != "true")
01041 {
01042 new_unknown_opt.push_back('=');
01043 new_unknown_opt.append(*it);
01044 }
01045 }
01046 else
01047 {
01048 break;
01049 }
01050 unknown_options.push_back(new_unknown_opt);
01051 }
01052 store(file_parsed, vm);
01053 }
01054 }
01055
01056 static void compose_defaults_file_list(vector<string> in_options)
01057 {
01058 for (vector<string>::iterator it= in_options.begin();
01059 it != in_options.end();
01060 ++it)
01061 {
01062 fs::path p(*it);
01063 if (fs::is_regular_file(p))
01064 defaults_file_list.push_back(*it);
01065 else
01066 {
01067 errmsg_printf(error::ERROR,
01068 _("Defaults file '%s' not found\n"), (*it).c_str());
01069 unireg_abort(1);
01070 }
01071
01072 }
01073 }
01074
01075 int init_basic_variables(int argc, char **argv)
01076 {
01077 time_t curr_time;
01078 umask(((~internal::my_umask) & 0666));
01079 decimal_zero.set_zero();
01080 tzset();
01081
01082 curr_time= time(NULL);
01083 if (curr_time == (time_t)-1)
01084 return 1;
01085
01086 max_system_variables.pseudo_thread_id= UINT32_MAX;
01087 server_start_time= flush_status_time= curr_time;
01088
01089 drizzle_init_variables();
01090
01091 find_plugin_dir(argv[0]);
01092
01093
01094
01095
01096
01097
01098
01099 global_system_variables.time_zone= my_tz_SYSTEM;
01100
01101 char ret_hostname[FN_REFLEN];
01102 if (gethostname(ret_hostname,sizeof(ret_hostname)) < 0)
01103 {
01104 errmsg_printf(error::WARN,
01105 _("gethostname failed, using '%s' as hostname"),
01106 getServerHostname().c_str());
01107 pid_file= "drizzle";
01108 }
01109 else
01110 {
01111 setServerHostname(ret_hostname);
01112 pid_file= getServerHostname();
01113 }
01114 pid_file.replace_extension(".pid");
01115
01116 system_config_dir /= "drizzle";
01117
01118 config_options.add_options()
01119 ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
01120 _("Display this help and exit."))
01121 ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
01122 _("Run as a daemon."))
01123 ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
01124 _("Configuration file defaults are not used if no-defaults is set"))
01125 ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
01126 _("Configuration file to use"))
01127 ("config-dir", po::value<fs::path>(&system_config_dir),
01128 _("Base location for config files"))
01129 ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(¬ify_plugin_dir),
01130 _("Directory for plugins."))
01131 ;
01132
01133 plugin_load_options.add_options()
01134 ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
01135 _("Optional comma separated list of plugins to load at startup in addition "
01136 "to the default list of plugins. "
01137 "[for example: --plugin_add=crc32,logger_gearman]"))
01138 ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
01139 _("Optional comma separated list of plugins to not load at startup. Effectively "
01140 "removes a plugin from the list of plugins to be loaded. "
01141 "[for example: --plugin_remove=crc32,logger_gearman]"))
01142 ("plugin-load", po::value<string>()->notifier(¬ify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
01143 _("Optional comma separated list of plugins to load at starup instead of "
01144 "the default plugin load list. "
01145 "[for example: --plugin_load=crc32,logger_gearman]"))
01146 ;
01147
01148 long_options.add_options()
01149 ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
01150 _("Auto-increment columns are incremented by this"))
01151 ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
01152 _("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
01153 ("basedir,b", po::value<fs::path>(&basedir),
01154 _("Path to installation directory. All paths are usually resolved "
01155 "relative to this."))
01156 ("chroot,r", po::value<string>(),
01157 _("Chroot drizzled daemon during startup."))
01158 ("collation-server", po::value<string>(),
01159 _("Set the default collation."))
01160 ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
01161 _("Default completion type."))
01162 ("core-file", _("Write core on errors."))
01163 ("datadir", po::value<fs::path>(&getDataHome()),
01164 _("Path to the database root."))
01165 ("default-storage-engine", po::value<string>(),
01166 _("Set the default storage engine for tables."))
01167 ("default-time-zone", po::value<string>(),
01168 _("Set the default time zone."))
01169 ("exit-info,T", po::value<long>(),
01170 _("Used for debugging; Use at your own risk!"))
01171 ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
01172 _("Set up signals usable for debugging"))
01173 ("lc-time-name", po::value<string>(),
01174 _("Set the language used for the month names and the days of the week."))
01175 ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
01176 _("Log some not critical warnings to the log file."))
01177 ("pid-file", po::value<fs::path>(&pid_file),
01178 _("Pid file used by drizzled."))
01179 ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
01180 _("Maximum time in seconds to wait for the port to become free. "))
01181 ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
01182 _("Include the SQL query in replicated protobuf messages."))
01183 ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
01184 _("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
01185 "within specified directory"))
01186 ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
01187 _("Uniquely identifies the server instance in the community of "
01188 "replication partners."))
01189 ("skip-stack-trace",
01190 _("Don't print a stack trace on failure."))
01191 ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
01192 _("Enable symbolic link support."))
01193 ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
01194 _("Specify whether to time mutexes (only InnoDB mutexes are currently "
01195 "supported)"))
01196 ("tmpdir,t", po::value<string>(),
01197 _("Path for temporary files."))
01198 ("transaction-isolation", po::value<string>(),
01199 _("Default transaction isolation level."))
01200 ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
01201 _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
01202 ("user,u", po::value<string>(),
01203 _("Run drizzled daemon as user."))
01204 ("version,V",
01205 _("Output version information and exit."))
01206 ("back-log", po::value<back_log_constraints>(&back_log),
01207 _("The number of outstanding connection requests Drizzle can have. This "
01208 "comes into play when the main Drizzle thread gets very many connection "
01209 "requests in a very short time."))
01210 ("bulk-insert-buffer-size",
01211 po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
01212 _("Size of tree cache used in bulk insert optimization. Note that this is "
01213 "a limit per thread!"))
01214 ("div-precision-increment", po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
01215 _("Precision of the result of '/' operator will be increased on that "
01216 "value."))
01217 ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
01218 _("The maximum length of the result of function group_concat."))
01219 ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
01220 _("The size of the buffer that is used for full joins."))
01221 ("join-heap-threshold",
01222 po::value<uint64_t>()->default_value(0),
01223 _("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
01224 ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
01225 _("Max packetlength to send/receive from to server."))
01226 ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
01227 _("Max number of errors/warnings to store for a statement."))
01228 ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
01229 _("Don't allow creation of heap tables bigger than this."))
01230 ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
01231 _("Joins that are probably going to read more than max_join_size records "
01232 "return an error."))
01233 ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
01234 _("Max number of bytes in sorted records."))
01235 ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
01236 _("Limit assumed max number of seeks when looking up rows based on a key"))
01237 ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),
01238 _("The number of bytes to use when sorting BLOB or TEXT values "
01239 "(only the first max_sort_length bytes of each value are used; the "
01240 "rest are ignored)."))
01241 ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
01242 _("After this many write locks, allow some read locks to run in between."))
01243 ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
01244 _("Don't log queries which examine less than min_examined_row_limit "
01245 "rows to file."))
01246 ("disable-optimizer-prune",
01247 _("Do not apply any heuristic(s) during query optimization to prune, "
01248 "thus perform an exhaustive search from the optimizer search space."))
01249 ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
01250 _("Maximum depth of search performed by the query optimizer. Values "
01251 "larger than the number of relations in a query result in better query "
01252 "plans, but take longer to compile a query. Smaller values than the "
01253 "number of tables in a relation result in faster optimization, but may "
01254 "produce very bad query plans. If set to 0, the system will "
01255 "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
01256 "optimizer will switch to the original find_best (used for "
01257 "testing/comparison)."))
01258 ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
01259 _("The size of the buffer that is allocated when preloading indexes"))
01260 ("query-alloc-block-size",
01261 po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
01262 _("Allocation block size for query parsing and execution"))
01263 ("query-prealloc-size",
01264 po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
01265 _("Persistent buffer for query parsing and execution"))
01266 ("range-alloc-block-size",
01267 po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
01268 _("Allocation block size for storing ranges during optimization"))
01269 ("read-buffer-size",
01270 po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
01271 _("Each thread that does a sequential scan allocates a buffer of this "
01272 "size for each table it scans. If you do many sequential scans, you may "
01273 "want to increase this value."))
01274 ("read-buffer-threshold",
01275 po::value<uint64_t>()->default_value(0),
01276 _("A global cap on the size of read-buffer-size (0 means unlimited)"))
01277 ("read-rnd-buffer-size",
01278 po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
01279 _("When reading rows in sorted order after a sort, the rows are read "
01280 "through this buffer to avoid a disk seeks. If not set, then it's set "
01281 "to the value of record_buffer."))
01282 ("read-rnd-threshold",
01283 po::value<uint64_t>()->default_value(0),
01284 _("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
01285 ("scheduler", po::value<string>(),
01286 _("Select scheduler to be used (by default multi-thread)."))
01287 ("sort-buffer-size",
01288 po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
01289 _("Each thread that needs to do a sort allocates a buffer of this size."))
01290 ("sort-heap-threshold",
01291 po::value<uint64_t>()->default_value(0),
01292 _("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
01293 ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
01294 _("The number of cached table definitions."))
01295 ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
01296 _("The number of cached open tables."))
01297 ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
01298 _("Timeout in seconds to wait for a table level lock before returning an "
01299 "error. Used only if the connection has active cursors."))
01300 ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
01301 _("The stack size for each thread."))
01302 ("tmp-table-size",
01303 po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
01304 _("If an internal in-memory temporary table exceeds this size, Drizzle will"
01305 " automatically convert it to an on-disk MyISAM table."))
01306 ("verbose", po::value<std::string>()->default_value(error::verbose_string())->notifier(&error::check_verbosity),
01307 _("The verbosity of messages from drizzled. Possible values are INSPECT, INFO, WARN or ERROR"))
01308 ;
01309
01310 full_options.add(long_options);
01311 full_options.add(plugin_load_options);
01312
01313 initial_options.add(config_options);
01314 initial_options.add(plugin_load_options);
01315
01316 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
01317
01318 po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
01319 options(initial_options).allow_unregistered().run();
01320 unknown_options=
01321 po::collect_unrecognized(parsed.options, po::include_positional);
01322
01323 try
01324 {
01325 po::store(parsed, vm);
01326 }
01327 catch (std::exception&)
01328 {
01329 errmsg_printf(error::ERROR, _("Duplicate entry for command line option\n"));
01330 unireg_abort(1);
01331 }
01332
01333 if (not vm["no-defaults"].as<bool>())
01334 {
01335 fs::path system_config_file_drizzle(system_config_dir);
01336 system_config_file_drizzle /= "drizzled.cnf";
01337 defaults_file_list.insert(defaults_file_list.begin(),
01338 system_config_file_drizzle.file_string());
01339
01340 fs::path config_conf_d_location(system_config_dir);
01341 config_conf_d_location /= "conf.d";
01342
01343
01344 CachedDirectory config_conf_d(config_conf_d_location.file_string());
01345 if (not config_conf_d.fail())
01346 {
01347
01348 for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
01349 iter != config_conf_d.getEntries().end();
01350 ++iter)
01351 {
01352 string file_entry((*iter)->filename);
01353
01354 if (not file_entry.empty()
01355 && file_entry != "."
01356 && file_entry != "..")
01357 {
01358 fs::path the_entry(config_conf_d_location);
01359 the_entry /= file_entry;
01360 defaults_file_list.push_back(the_entry.file_string());
01361 }
01362 }
01363 }
01364 }
01365
01366
01367
01368
01369 try
01370 {
01371 po::notify(vm);
01372 }
01373 catch (po::validation_error &err)
01374 {
01375 errmsg_printf(error::ERROR,
01376 _("%s: %s.\n"
01377 "Use --help to get a list of available options\n"),
01378 internal::my_progname, err.what());
01379 unireg_abort(1);
01380 }
01381
01382 process_defaults_files();
01383
01384
01385
01386
01387 try
01388 {
01389 po::notify(vm);
01390 }
01391 catch (po::validation_error &err)
01392 {
01393 errmsg_printf(error::ERROR,
01394 _("%s: %s.\n"
01395 "Use --help to get a list of available options\n"),
01396 internal::my_progname, err.what());
01397 unireg_abort(1);
01398 }
01399
01400 return 0;
01401 }
01402
01403 int init_remaining_variables(module::Registry &plugins)
01404 {
01405 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
01406
01407 current_pid= getpid();
01408
01409
01410
01411
01412
01413 if (plugin_init(plugins, plugin_options))
01414 {
01415 errmsg_printf(error::ERROR, _("Failed to initialize plugins\n"));
01416 unireg_abort(1);
01417 }
01418
01419 full_options.add(plugin_options);
01420
01421 vector<string> final_unknown_options;
01422 try
01423 {
01424 po::parsed_options final_parsed=
01425 po::command_line_parser(unknown_options).style(style).
01426 options(full_options).extra_parser(dpo::parse_size_arg).run();
01427
01428 final_unknown_options=
01429 po::collect_unrecognized(final_parsed.options, po::include_positional);
01430
01431 po::store(final_parsed, vm);
01432
01433 }
01434 catch (po::validation_error &err)
01435 {
01436 errmsg_printf(error::ERROR,
01437 _("%s: %s.\n"
01438 "Use --help to get a list of available options\n"),
01439 internal::my_progname, err.what());
01440 unireg_abort(1);
01441 }
01442 catch (po::invalid_command_line_syntax &err)
01443 {
01444 errmsg_printf(error::ERROR,
01445 _("%s: %s.\n"
01446 "Use --help to get a list of available options\n"),
01447 internal::my_progname, err.what());
01448 unireg_abort(1);
01449 }
01450 catch (po::unknown_option &err)
01451 {
01452 errmsg_printf(error::ERROR,
01453 _("%s\nUse --help to get a list of available options\n"),
01454 err.what());
01455 unireg_abort(1);
01456 }
01457
01458 try
01459 {
01460 po::notify(vm);
01461 }
01462 catch (po::validation_error &err)
01463 {
01464 errmsg_printf(error::ERROR,
01465 _("%s: %s.\n"
01466 "Use --help to get a list of available options\n"),
01467 internal::my_progname, err.what());
01468 unireg_abort(1);
01469 }
01470
01471 get_options();
01472
01473
01474
01475 global_system_variables.optimizer_prune_level=
01476 vm.count("disable-optimizer-prune") ? false : true;
01477
01478 if (! vm["help"].as<bool>())
01479 {
01480 if ((user_info= check_user(drizzled_user)))
01481 {
01482 set_user(drizzled_user, user_info);
01483 }
01484 }
01485
01486 fix_paths();
01487
01488 init_time();
01489
01490 if (item_create_init())
01491 return 1;
01492 if (sys_var_init())
01493 return 1;
01494
01495 if (! init_temporal_formats())
01496 return 1;
01497
01498 if (!(default_charset_info=
01499 get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
01500 {
01501 errmsg_printf(error::ERROR, _("Error getting default charset"));
01502 return 1;
01503 }
01504
01505 if (vm.count("scheduler"))
01506 opt_scheduler= vm["scheduler"].as<string>().c_str();
01507
01508 if (default_collation_name)
01509 {
01510 const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
01511 if (not default_collation)
01512 {
01513 errmsg_printf(error::ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
01514 return 1;
01515 }
01516 if (not my_charset_same(default_charset_info, default_collation))
01517 {
01518 errmsg_printf(error::ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
01519 default_collation_name,
01520 default_charset_info->csname);
01521 return 1;
01522 }
01523 default_charset_info= default_collation;
01524 }
01525
01526 global_system_variables.collation_server= default_charset_info;
01527
01528 if (not (character_set_filesystem=
01529 get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
01530 {
01531 errmsg_printf(error::ERROR, _("Error setting collation"));
01532 return 1;
01533 }
01534 global_system_variables.character_set_filesystem= character_set_filesystem;
01535
01536 if (!(my_default_lc_time_names=
01537 my_locale_by_name(lc_time_names_name)))
01538 {
01539 errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
01540 return 1;
01541 }
01542 global_system_variables.lc_time_names= my_default_lc_time_names;
01543
01544
01545 table_alias_charset= files_charset_info;
01546
01547 return 0;
01548 }
01549
01550
01551 int init_server_components(module::Registry &plugins)
01552 {
01553
01554
01555
01556
01557 if (table_cache_init())
01558 {
01559 errmsg_printf(error::ERROR, _("Could not initialize table cache\n"));
01560 unireg_abort(1);
01561 }
01562
01563
01564 table::Cache::singleton().rehash(table_def_size);
01565 definition::Cache::singleton().rehash(table_def_size);
01566 message::Cache::singleton().rehash(table_def_size);
01567
01568 setup_fpu();
01569
01570
01571 ha_init_errors();
01572
01573
01574 if (opt_help)
01575 unireg_abort(0);
01576
01577 if (plugin_finalize(plugins))
01578 {
01579 unireg_abort(1);
01580 }
01581
01582 string scheduler_name;
01583 if (opt_scheduler)
01584 {
01585 scheduler_name= opt_scheduler;
01586 }
01587 else
01588 {
01589 scheduler_name= opt_scheduler_default;
01590 opt_scheduler= opt_scheduler_default;
01591 }
01592
01593 if (plugin::Scheduler::setPlugin(scheduler_name))
01594 {
01595 errmsg_printf(error::ERROR,
01596 _("No scheduler found, cannot continue!\n"));
01597 unireg_abort(1);
01598 }
01599
01600
01601
01602
01603
01604 const std::string myisam_engine_name("MyISAM");
01605 const std::string heap_engine_name("MEMORY");
01606 myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
01607 heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
01608
01609
01610
01611
01612 if (default_storage_engine_str)
01613 {
01614 const std::string name(default_storage_engine_str);
01615 plugin::StorageEngine *engine;
01616
01617 engine= plugin::StorageEngine::findByName(name);
01618 if (engine == NULL)
01619 {
01620 errmsg_printf(error::ERROR, _("Unknown/unsupported storage engine: %s\n"),
01621 default_storage_engine_str);
01622 unireg_abort(1);
01623 }
01624 global_system_variables.storage_engine= engine;
01625 }
01626
01627 if (plugin::XaResourceManager::recoverAllXids())
01628 {
01629
01630 unireg_abort(1);
01631 }
01632
01633 init_update_queries();
01634
01635 return(0);
01636 }
01637
01638
01639
01640
01641
01642
01643 enum options_drizzled
01644 {
01645 OPT_SOCKET=256,
01646 OPT_BIND_ADDRESS,
01647 OPT_PID_FILE,
01648 OPT_STORAGE_ENGINE,
01649 OPT_INIT_FILE,
01650 OPT_WANT_CORE,
01651 OPT_MEMLOCK,
01652 OPT_SERVER_ID,
01653 OPT_TC_HEURISTIC_RECOVER,
01654 OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
01655 OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
01656 OPT_DO_PSTACK,
01657 OPT_LOCAL_INFILE,
01658 OPT_BACK_LOG,
01659 OPT_JOIN_BUFF_SIZE,
01660 OPT_MAX_ALLOWED_PACKET,
01661 OPT_MAX_HEP_TABLE_SIZE,
01662 OPT_MAX_JOIN_SIZE,
01663 OPT_MAX_SORT_LENGTH,
01664 OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
01665 OPT_MAX_LENGTH_FOR_SORT_DATA,
01666 OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
01667 OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
01668 OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
01669 OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
01670 OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
01671 OPT_NET_BUFFER_LENGTH,
01672 OPT_PRELOAD_BUFFER_SIZE,
01673 OPT_RECORD_BUFFER,
01674 OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
01675 OPT_DEBUGGING,
01676 OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
01677 OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
01678 OPT_WAIT_TIMEOUT,
01679 OPT_RANGE_ALLOC_BLOCK_SIZE,
01680 OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
01681 OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
01682 OPT_OLD_ALTER_TABLE,
01683 OPT_GROUP_CONCAT_MAX_LEN,
01684 OPT_DEFAULT_COLLATION,
01685 OPT_CHARACTER_SET_FILESYSTEM,
01686 OPT_LC_TIME_NAMES,
01687 OPT_INIT_CONNECT,
01688 OPT_DEFAULT_TIME_ZONE,
01689 OPT_OPTIMIZER_SEARCH_DEPTH,
01690 OPT_SCHEDULER,
01691 OPT_PROTOCOL,
01692 OPT_OPTIMIZER_PRUNE_LEVEL,
01693 OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
01694 OPT_ENABLE_LARGE_PAGES,
01695 OPT_TIMED_MUTEXES,
01696 OPT_TABLE_LOCK_WAIT_TIMEOUT,
01697 OPT_PLUGIN_ADD,
01698 OPT_PLUGIN_REMOVE,
01699 OPT_PLUGIN_LOAD,
01700 OPT_PLUGIN_DIR,
01701 OPT_PORT_OPEN_TIMEOUT,
01702 OPT_SECURE_FILE_PRIV,
01703 OPT_MIN_EXAMINED_ROW_LIMIT,
01704 OPT_PRINT_DEFAULTS
01705 };
01706
01707
01708 struct option my_long_options[] =
01709 {
01710
01711 {"help", '?', N_("Display this help and exit."),
01712 (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
01713 0, 0},
01714 {"daemon", 'd', N_("Run as daemon."),
01715 (char**) &opt_daemon, (char**) &opt_daemon, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
01716 0, 0},
01717 {"auto-increment-increment", OPT_AUTO_INCREMENT,
01718 N_("Auto-increment columns are incremented by this"),
01719 (char**) &global_system_variables.auto_increment_increment,
01720 (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
01721 OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
01722 {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
01723 N_("Offset added to Auto-increment columns. Used when "
01724 "auto-increment-increment != 1"),
01725 (char**) &global_system_variables.auto_increment_offset,
01726 (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
01727 1, 1, INT64_MAX, 0, 1, 0 },
01728 {"basedir", 'b',
01729 N_("Path to installation directory. All paths are usually resolved "
01730 "relative to this."),
01731 NULL, NULL, 0, GET_STR, REQUIRED_ARG,
01732 0, 0, 0, 0, 0, 0},
01733 {"chroot", 'r',
01734 N_("Chroot drizzled daemon during startup."),
01735 (char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
01736 0, 0, 0, 0, 0, 0},
01737 {"collation-server", OPT_DEFAULT_COLLATION,
01738 N_("Set the default collation."),
01739 (char**) &default_collation_name, (char**) &default_collation_name,
01740 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
01741 {"completion-type", OPT_COMPLETION_TYPE,
01742 N_("Default completion type."),
01743 (char**) &global_system_variables.completion_type,
01744 (char**) &max_system_variables.completion_type, 0, GET_UINT,
01745 REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
01746 {"core-file", OPT_WANT_CORE,
01747 N_("Write core on errors."),
01748 0, 0, 0, GET_NO_ARG,
01749 NO_ARG, 0, 0, 0, 0, 0, 0},
01750 {"datadir", 'h',
01751 N_("Path to the database root."),
01752 NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01753
01754 {"exit-info", 'T',
01755 N_("Used for debugging; Use at your own risk!"),
01756 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
01757
01758
01759 {"gdb", OPT_DEBUGGING,
01760 N_("Set up signals usable for debugging"),
01761 (char**) &opt_debugging, (char**) &opt_debugging,
01762 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
01763 {"log-warnings", 'W',
01764 N_("Log some not critical warnings to the log file."),
01765 (char**) &global_system_variables.log_warnings,
01766 (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
01767 0, 0, 0},
01768 {"pid-file", OPT_PID_FILE,
01769 N_("Pid file used by drizzled."),
01770 NULL, NULL, 0, GET_STR,
01771 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01772 {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
01773 N_("Maximum time in seconds to wait for the port to become free. "
01774 "(Default: no wait)"),
01775 (char**) &drizzled_bind_timeout,
01776 (char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01777 {"secure-file-priv", OPT_SECURE_FILE_PRIV,
01778 N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
01779 "within specified directory"),
01780 NULL, NULL, 0,
01781 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01782 {"server-id", OPT_SERVER_ID,
01783 N_("Uniquely identifies the server instance in the community of "
01784 "replication partners."),
01785 (char**) &server_id, (char**) &server_id, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
01786 0, 0, 0},
01787 {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
01788 N_("Don't print a stack trace on failure."),
01789 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
01790 0, 0, 0, 0},
01791 {"symbolic-links", 's',
01792 N_("Enable symbolic link support."),
01793 (char**) &internal::my_use_symdir, (char**) &internal::my_use_symdir, 0, GET_BOOL, NO_ARG,
01794
01795
01796
01797
01798
01799 IF_PURIFY(0,1), 0, 0, 0, 0, 0},
01800 {"timed_mutexes", OPT_TIMED_MUTEXES,
01801 N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
01802 "supported)"),
01803 (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
01804 0, 0, 0, 0, 0},
01805 {"transaction-isolation", OPT_TX_ISOLATION,
01806 N_("Default transaction isolation level."),
01807 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
01808 0, 0, 0, 0, 0},
01809 {"user", 'u',
01810 N_("Run drizzled daemon as user."),
01811 0, 0, 0, GET_STR, REQUIRED_ARG,
01812 0, 0, 0, 0, 0, 0},
01813 {"back_log", OPT_BACK_LOG,
01814 N_("The number of outstanding connection requests Drizzle can have. This "
01815 "comes into play when the main Drizzle thread gets very many connection "
01816 "requests in a very short time."),
01817 (char**) &back_log, (char**) &back_log, 0, GET_UINT,
01818 REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
01819 { "bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
01820 N_("Size of tree cache used in bulk insert optimization. Note that this is "
01821 "a limit per thread!"),
01822 (char**) &global_system_variables.bulk_insert_buff_size,
01823 (char**) &max_system_variables.bulk_insert_buff_size,
01824 0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
01825 { "div_precision_increment", OPT_DIV_PRECINCREMENT,
01826 N_("Precision of the result of '/' operator will be increased on that "
01827 "value."),
01828 (char**) &global_system_variables.div_precincrement,
01829 (char**) &max_system_variables.div_precincrement, 0, GET_UINT,
01830 REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
01831 { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
01832 N_("The size of the buffer that is used for full joins."),
01833 (char**) &global_system_variables.join_buff_size,
01834 (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
01835 REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
01836 MALLOC_OVERHEAD, IO_SIZE, 0},
01837 {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
01838 N_("Max packetlength to send/receive from to server."),
01839 (char**) &global_system_variables.max_allowed_packet,
01840 (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
01841 REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
01842 {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
01843 N_("Don't allow creation of heap tables bigger than this."),
01844 (char**) &global_system_variables.max_heap_table_size,
01845 (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
01846 REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
01847 MALLOC_OVERHEAD, 1024, 0},
01848 {"max_join_size", OPT_MAX_JOIN_SIZE,
01849 N_("Joins that are probably going to read more than max_join_size records "
01850 "return an error."),
01851 (char**) &global_system_variables.max_join_size,
01852 (char**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
01853 INT32_MAX, 1, INT32_MAX, 0, 1, 0},
01854 {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
01855 N_("Max number of bytes in sorted records."),
01856 (char**) &global_system_variables.max_length_for_sort_data,
01857 (char**) &max_system_variables.max_length_for_sort_data, 0, GET_ULL,
01858 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01859 { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
01860 N_("Limit assumed max number of seeks when looking up rows based on a key"),
01861 (char**) &global_system_variables.max_seeks_for_key,
01862 (char**) &max_system_variables.max_seeks_for_key, 0, GET_UINT64,
01863 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
01864 {"max_sort_length", OPT_MAX_SORT_LENGTH,
01865 N_("The number of bytes to use when sorting BLOB or TEXT values "
01866 "(only the first max_sort_length bytes of each value are used; the "
01867 "rest are ignored)."),
01868 (char**) &global_system_variables.max_sort_length,
01869 (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
01870 REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
01871 {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
01872 N_("After this many write locks, allow some read locks to run in between."),
01873 (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
01874 REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
01875 {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
01876 N_("Don't log queries which examine less than min_examined_row_limit "
01877 "rows to file."),
01878 (char**) &global_system_variables.min_examined_row_limit,
01879 (char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
01880 REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
01881 {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
01882 N_("Controls the heuristic(s) applied during query optimization to prune "
01883 "less-promising partial plans from the optimizer search space. Meaning: "
01884 "false - do not apply any heuristic, thus perform exhaustive search; "
01885 "true - prune plans based on number of retrieved rows."),
01886 (char**) &global_system_variables.optimizer_prune_level,
01887 (char**) &max_system_variables.optimizer_prune_level,
01888 0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
01889 {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
01890 N_("Maximum depth of search performed by the query optimizer. Values "
01891 "larger than the number of relations in a query result in better query "
01892 "plans, but take longer to compile a query. Smaller values than the "
01893 "number of tables in a relation result in faster optimization, but may "
01894 "produce very bad query plans. If set to 0, the system will "
01895 "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
01896 "optimizer will switch to the original find_best (used for "
01897 "testing/comparison)."),
01898 (char**) &global_system_variables.optimizer_search_depth,
01899 (char**) &max_system_variables.optimizer_search_depth,
01900 0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
01901 {"plugin_dir", OPT_PLUGIN_DIR,
01902 N_("Directory for plugins."),
01903 NULL, NULL, 0,
01904 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01905 {"plugin_add", OPT_PLUGIN_ADD,
01906 N_("Optional comma separated list of plugins to load at startup in addition "
01907 "to the default list of plugins. "
01908 "[for example: --plugin_add=crc32,logger_gearman]"),
01909 NULL, NULL, 0,
01910 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01911 {"plugin_remove", OPT_PLUGIN_ADD,
01912 N_("Optional comma separated list of plugins to not load at startup. Effectively "
01913 "removes a plugin from the list of plugins to be loaded. "
01914 "[for example: --plugin_remove=crc32,logger_gearman]"),
01915 NULL, NULL, 0,
01916 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01917 {"plugin_load", OPT_PLUGIN_LOAD,
01918 N_("Optional comma separated list of plugins to load at starup instead of "
01919 "the default plugin load list. "
01920 "[for example: --plugin_load=crc32,logger_gearman]"),
01921 NULL, NULL, 0,
01922 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
01923 {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
01924 N_("The size of the buffer that is allocated when preloading indexes"),
01925 (char**) &global_system_variables.preload_buff_size,
01926 (char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
01927 REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
01928 {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
01929 N_("Allocation block size for query parsing and execution"),
01930 (char**) &global_system_variables.query_alloc_block_size,
01931 (char**) &max_system_variables.query_alloc_block_size, 0, GET_UINT,
01932 REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
01933 {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
01934 N_("Persistent buffer for query parsing and execution"),
01935 (char**) &global_system_variables.query_prealloc_size,
01936 (char**) &max_system_variables.query_prealloc_size, 0, GET_UINT,
01937 REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
01938 ULONG_MAX, 0, 1024, 0},
01939 {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
01940 N_("Allocation block size for storing ranges during optimization"),
01941 (char**) &global_system_variables.range_alloc_block_size,
01942 (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
01943 REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
01944 0, 1024, 0},
01945 {"read_buffer_size", OPT_RECORD_BUFFER,
01946 N_("Each thread that does a sequential scan allocates a buffer of this "
01947 "size for each table it scans. If you do many sequential scans, you may "
01948 "want to increase this value."),
01949 (char**) &global_system_variables.read_buff_size,
01950 (char**) &max_system_variables.read_buff_size,0, GET_UINT, REQUIRED_ARG,
01951 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT32_MAX, MALLOC_OVERHEAD, IO_SIZE,
01952 0},
01953 {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
01954 N_("When reading rows in sorted order after a sort, the rows are read "
01955 "through this buffer to avoid a disk seeks. If not set, then it's set "
01956 "to the value of record_buffer."),
01957 (char**) &global_system_variables.read_rnd_buff_size,
01958 (char**) &max_system_variables.read_rnd_buff_size, 0,
01959 GET_UINT, REQUIRED_ARG, 256*1024L, 64 ,
01960 UINT32_MAX, MALLOC_OVERHEAD, 1 , 0},
01961
01962 {"sort_buffer_size", OPT_SORT_BUFFER,
01963 N_("Each thread that needs to do a sort allocates a buffer of this size."),
01964 (char**) &global_system_variables.sortbuff_size,
01965 (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
01966 MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
01967 MALLOC_OVERHEAD, 1, 0},
01968 {"table_definition_cache", OPT_TABLE_DEF_CACHE,
01969 N_("The number of cached table definitions."),
01970 (char**) &table_def_size, (char**) &table_def_size,
01971 0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
01972 {"table_open_cache", OPT_TABLE_OPEN_CACHE,
01973 N_("The number of cached open tables."),
01974 (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
01975 REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, TABLE_OPEN_CACHE_MIN, 512*1024L, 0, 1, 0},
01976 {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
01977 N_("Timeout in seconds to wait for a table level lock before returning an "
01978 "error. Used only if the connection has active cursors."),
01979 (char**) &table_lock_wait_timeout, (char**) &table_lock_wait_timeout,
01980 0, GET_ULL, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
01981 {"thread_stack", OPT_THREAD_STACK,
01982 N_("The stack size for each thread."),
01983 (char**) &my_thread_stack_size,
01984 (char**) &my_thread_stack_size, 0, GET_SIZE,
01985 REQUIRED_ARG,DEFAULT_THREAD_STACK,
01986 UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
01987 {"tmp_table_size", OPT_TMP_TABLE_SIZE,
01988 N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
01989 " automatically convert it to an on-disk MyISAM table."),
01990 (char**) &global_system_variables.tmp_table_size,
01991 (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
01992 REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
01993 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
01994 };
01995
01996 static void print_version(void)
01997 {
01998
01999
02000
02001
02002 printf("%s Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
02003 PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
02004 COMPILATION_COMMENT);
02005 }
02006
02007 static void usage(void)
02008 {
02009 if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
02010 exit(1);
02011 if (!default_collation_name)
02012 default_collation_name= (char*) default_charset_info->name;
02013 print_version();
02014 puts(_("Copyright (C) 2008 Sun Microsystems\n"
02015 "This software comes with ABSOLUTELY NO WARRANTY. "
02016 "This is free software,\n"
02017 "and you are welcome to modify and redistribute it under the GPL "
02018 "license\n\n"));
02019
02020
02021 printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
02022
02023 po::options_description all_options("Drizzled Options");
02024 all_options.add(config_options);
02025 all_options.add(plugin_load_options);
02026 all_options.add(long_options);
02027 all_options.add(plugin_options);
02028 cout << all_options << endl;
02029
02030 }
02031
02048 static void drizzle_init_variables(void)
02049 {
02050
02051 opt_tc_log_file= (char *)"tc.log";
02052 cleanup_done= 0;
02053 dropping_tables= ha_open_options=0;
02054 getDebug().reset();
02055 wake_thread=0;
02056 abort_loop= select_thread_in_use= false;
02057 shutdown_in_progress= 0;
02058 drizzled_user= drizzled_chroot= 0;
02059 memset(¤t_global_counters, 0, sizeof(current_global_counters));
02060 key_map_full.set();
02061
02062
02063 system_charset_info= &my_charset_utf8_general_ci;
02064 files_charset_info= &my_charset_utf8_general_ci;
02065 table_alias_charset= &my_charset_bin;
02066 character_set_filesystem= &my_charset_bin;
02067
02068
02069 session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
02070 refresh_version= 1L;
02071 global_thread_id= 1UL;
02072 session::Cache::singleton().getCache().clear();
02073
02074
02075 default_character_set_name= "utf8";
02076 default_collation_name= (char *)compiled_default_collation_name;
02077 character_set_filesystem_name= "binary";
02078 lc_time_names_name= (char*) "en_US";
02079
02080 default_storage_engine_str= (char*) "innodb";
02081 global_system_variables.storage_engine= NULL;
02082 global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
02083 global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
02084 max_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
02085 global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
02086 max_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
02087 max_system_variables.auto_increment_increment= UINT64_MAX;
02088 max_system_variables.auto_increment_offset= UINT64_MAX;
02089 max_system_variables.completion_type= 2;
02090 max_system_variables.log_warnings= true;
02091 max_system_variables.bulk_insert_buff_size= ULONG_MAX;
02092 max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
02093 max_system_variables.group_concat_max_len= ULONG_MAX;
02094 max_system_variables.join_buff_size= ULONG_MAX;
02095 max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
02096 max_system_variables.max_error_count= 65535;
02097 max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
02098 max_system_variables.max_join_size= INT32_MAX;
02099 max_system_variables.max_length_for_sort_data= 8192*1024L;
02100 max_system_variables.max_seeks_for_key= ULONG_MAX;
02101 max_system_variables.max_sort_length= 8192*1024L;
02102 max_system_variables.min_examined_row_limit= ULONG_MAX;
02103 max_system_variables.optimizer_prune_level= 1;
02104 max_system_variables.optimizer_search_depth= MAX_TABLES+2;
02105 max_system_variables.preload_buff_size= 1024*1024*1024L;
02106 max_system_variables.query_alloc_block_size= UINT32_MAX;
02107 max_system_variables.query_prealloc_size= UINT32_MAX;
02108 max_system_variables.range_alloc_block_size= SIZE_MAX;
02109 max_system_variables.read_buff_size= INT32_MAX;
02110 max_system_variables.read_rnd_buff_size= UINT32_MAX;
02111 max_system_variables.sortbuff_size= SIZE_MAX;
02112 max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
02113
02114 opt_scheduler_default= (char*) "multi_thread";
02115
02116
02117 #ifdef HAVE_BROKEN_REALPATH
02118 have_symlink=SHOW_OPTION_NO;
02119 #else
02120 have_symlink=SHOW_OPTION_YES;
02121 #endif
02122 }
02123
02124
02129 static void get_options()
02130 {
02131
02132 fs::path &data_home_catalog= getDataHomeCatalog();
02133 data_home_catalog= getDataHome();
02134 data_home_catalog /= "local";
02135
02136 if (vm.count("user"))
02137 {
02138 if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
02139 drizzled_user= (char *)vm["user"].as<string>().c_str();
02140
02141 else
02142 errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was "
02143 "set to '%s' earlier on the command line\n"),
02144 vm["user"].as<string>().c_str(), drizzled_user);
02145 }
02146
02147 if (vm.count("version"))
02148 {
02149 print_version();
02150 exit(0);
02151 }
02152
02153 if (vm.count("sort-heap-threshold"))
02154 {
02155 if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
02156 (vm["sort-heap-threshold"].as<uint64_t>() <
02157 global_system_variables.sortbuff_size))
02158 {
02159 cout << _("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
02160 exit(-1);
02161 }
02162
02163 global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
02164 }
02165
02166 if (vm.count("join-heap-threshold"))
02167 {
02168 if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
02169 (vm["join-heap-threshold"].as<uint64_t>() <
02170 global_system_variables.join_buff_size))
02171 {
02172 cout << _("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
02173 exit(-1);
02174 }
02175
02176 global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
02177 }
02178
02179 if (vm.count("read-rnd-threshold"))
02180 {
02181 if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
02182 (vm["read-rnd-threshold"].as<uint64_t>() <
02183 global_system_variables.read_rnd_buff_size))
02184 {
02185 cout << _("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
02186 exit(-1);
02187 }
02188
02189 global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
02190 }
02191
02192 if (vm.count("read-buffer-threshold"))
02193 {
02194 if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
02195 (vm["read-buffer-threshold"].as<uint64_t>() <
02196 global_system_variables.read_buff_size))
02197 {
02198 cout << _("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
02199 exit(-1);
02200 }
02201
02202 global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
02203 }
02204
02205 if (vm.count("exit-info"))
02206 {
02207 if (vm["exit-info"].as<long>())
02208 {
02209 getDebug().set((uint32_t) vm["exit-info"].as<long>());
02210 }
02211 }
02212
02213 if (vm.count("want-core"))
02214 {
02215 getDebug().set(debug::CORE_ON_SIGNAL);
02216 }
02217
02218 if (vm.count("skip-stack-trace"))
02219 {
02220 getDebug().set(debug::NO_STACKTRACE);
02221 }
02222
02223 if (vm.count("skip-symlinks"))
02224 {
02225 internal::my_use_symdir=0;
02226 }
02227
02228 if (vm.count("transaction-isolation"))
02229 {
02230 int type= tx_isolation_typelib.find_type_or_exit(vm["transaction-isolation"].as<string>().c_str(), "transaction-isolation");
02231 global_system_variables.tx_isolation= type - 1;
02232 }
02233
02234
02235 if (vm.count("default-storage-engine"))
02236 {
02237 default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
02238 }
02239
02240
02241 my_getopt_skip_unknown= true;
02242
02243
02244 #if defined(HAVE_BROKEN_REALPATH)
02245 internal::my_use_symdir=0;
02246 internal::my_disable_symlinks=1;
02247 have_symlink=SHOW_OPTION_NO;
02248 #else
02249 if (!internal::my_use_symdir)
02250 {
02251 internal::my_disable_symlinks=1;
02252 have_symlink=SHOW_OPTION_DISABLED;
02253 }
02254 #endif
02255 if (opt_debugging)
02256 {
02257
02258 getDebug().set(debug::ALLOW_SIGINT);
02259 getDebug().set(debug::NO_STACKTRACE);
02260 getDebug().reset(debug::CORE_ON_SIGNAL);
02261 }
02262
02263 if (drizzled_chroot)
02264 set_root(drizzled_chroot);
02265
02266
02267
02268
02269
02270 internal::my_default_record_cache_size=global_system_variables.read_buff_size;
02271 }
02272
02273
02274 static void fix_paths()
02275 {
02276 fs::path pid_file_path(pid_file);
02277 if (pid_file_path.root_path().string() == "")
02278 {
02279 pid_file_path= getDataHome();
02280 pid_file_path /= pid_file;
02281 }
02282 pid_file= fs::system_complete(pid_file_path);
02283
02284 if (not opt_help)
02285 {
02286 const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
02287 struct stat buf;
02288 drizzle_tmpdir.clear();
02289
02290 if (vm.count("tmpdir"))
02291 {
02292 drizzle_tmpdir.append(vm["tmpdir"].as<string>());
02293 }
02294 else if (tmp_string == NULL)
02295 {
02296 drizzle_tmpdir.append(getDataHome().file_string());
02297 drizzle_tmpdir.push_back(FN_LIBCHAR);
02298 drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
02299 }
02300 else
02301 {
02302 drizzle_tmpdir.append(tmp_string);
02303 }
02304
02305 drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
02306 assert(drizzle_tmpdir.size());
02307
02308 if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
02309 {
02310 if (errno != EEXIST)
02311 {
02312 errmsg_printf(error::ERROR, _("There was an error creating the '%s' part of the path '%s'. Please check the path exists and is writable.\n"), fs::path(drizzle_tmpdir).leaf().c_str(), drizzle_tmpdir.c_str());
02313 exit(1);
02314 }
02315 }
02316
02317 if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
02318 {
02319 errmsg_printf(error::ERROR, _("There was an error opening the path '%s', please check the path exists and is writable.\n"), drizzle_tmpdir.c_str());
02320 exit(1);
02321 }
02322 }
02323
02324 }
02325
02326 }
02327