~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Patrick Crews
  • Date: 2010-08-17 16:41:12 UTC
  • mfrom: (1711.6.2 staging)
  • mto: This revision was merged to the branch mainline in revision 1714.
  • Revision ID: gleebix@gmail.com-20100817164112-vaa55iprokbg6m1k
Merge Brian's recursive mutex removal tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
#include "config.h"
21
 
#include "drizzled/configmake.h"
22
 
#include "drizzled/atomics.h"
23
 
#include "drizzled/data_home.h"
 
21
#include <drizzled/configmake.h>
 
22
#include <drizzled/atomics.h>
24
23
 
25
24
#include <netdb.h>
26
25
#include <sys/types.h>
31
30
#include <stdexcept>
32
31
 
33
32
#include <boost/program_options.hpp>
34
 
#include "drizzled/program_options/config_file.h"
35
33
#include <boost/thread/recursive_mutex.hpp>
36
34
#include <boost/thread/mutex.hpp>
37
 
#include <boost/thread/shared_mutex.hpp>
38
35
#include <boost/thread/condition_variable.hpp>
39
 
#include <boost/filesystem.hpp>
40
36
 
41
37
#include "drizzled/internal/my_sys.h"
42
38
#include "drizzled/internal/my_bit.h"
60
56
#include "drizzled/plugin/monitored_in_transaction.h"
61
57
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
62
58
#include "drizzled/probes.h"
63
 
#include "drizzled/session/cache.h"
 
59
#include "drizzled/session_list.h"
64
60
#include "drizzled/charset.h"
65
61
#include "plugin/myisam/myisam.h"
66
62
#include "drizzled/drizzled.h"
67
63
#include "drizzled/module/registry.h"
68
 
#include "drizzled/module/load_list.h"
69
 
#include "drizzled/global_buffer.h"
70
 
 
71
 
#include "drizzled/definition/cache.h"
72
 
 
73
 
#include "drizzled/plugin/event_observer.h"
74
 
 
75
 
#include "drizzled/message/cache.h"
76
64
 
77
65
#include <google/protobuf/stubs/common.h>
78
66
 
130
118
#endif
131
119
 
132
120
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
133
 
#include "drizzled/constrained_value.h"
134
121
 
135
122
#include <drizzled/gettext.h>
136
123
 
137
124
 
138
 
#ifdef HAVE_VALGRIND
 
125
#ifdef HAVE_purify
139
126
#define IF_PURIFY(A,B) (A)
140
127
#else
141
128
#define IF_PURIFY(A,B) (B)
142
129
#endif
143
130
 
144
131
#define MAX_MEM_TABLE_SIZE SIZE_MAX
145
 
#include <iostream>
146
 
#include <fstream>
147
 
 
148
132
 
149
133
using namespace std;
150
 
namespace fs=boost::filesystem;
151
134
namespace po=boost::program_options;
152
 
namespace dpo=drizzled::program_options;
153
135
 
154
136
 
155
137
namespace drizzled
189
171
extern "C" int gethostname(char *name, int namelen);
190
172
#endif
191
173
 
 
174
/* Constants */
 
175
static const char *tc_heuristic_recover_names[]=
 
176
{
 
177
  "COMMIT", "ROLLBACK", NULL
 
178
};
 
179
static TYPELIB tc_heuristic_recover_typelib=
 
180
{
 
181
  array_elements(tc_heuristic_recover_names)-1,"",
 
182
  tc_heuristic_recover_names, NULL
 
183
};
 
184
 
192
185
const char *first_keyword= "first";
193
186
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
194
 
 
195
187
#define GET_HA_ROWS GET_ULL
196
188
 
197
189
const char *tx_isolation_names[] =
205
197
  Used with --help for detailed option
206
198
*/
207
199
bool opt_help= false;
 
200
bool opt_help_extended= false;
208
201
 
209
202
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
210
203
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
215
208
 
216
209
/* static variables */
217
210
 
218
 
static bool opt_debugging= false;
 
211
static bool opt_debugging= 0;
219
212
static uint32_t wake_thread;
220
213
static char *drizzled_chroot;
 
214
static char *language_ptr;
221
215
static const char *default_character_set_name;
222
216
static const char *character_set_filesystem_name;
223
217
static char *lc_time_names_name;
233
227
bool volatile abort_loop;
234
228
bool volatile shutdown_in_progress;
235
229
char *opt_scheduler_default;
236
 
const char *opt_scheduler= NULL;
 
230
char *opt_scheduler= NULL;
237
231
 
238
 
size_t my_thread_stack_size= 0;
 
232
size_t my_thread_stack_size= 65536;
239
233
 
240
234
/*
241
235
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
243
237
plugin::StorageEngine *heap_engine;
244
238
plugin::StorageEngine *myisam_engine;
245
239
 
 
240
char* opt_secure_file_priv= 0;
 
241
 
246
242
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
247
243
 
248
244
uint32_t drizzled_bind_timeout;
250
246
uint32_t dropping_tables, ha_open_options;
251
247
uint32_t tc_heuristic_recover= 0;
252
248
uint64_t session_startup_options;
253
 
back_log_constraints back_log(50);
 
249
uint32_t back_log;
254
250
uint32_t server_id;
255
251
uint64_t table_cache_size;
256
252
size_t table_def_size;
297
293
time_t server_start_time;
298
294
time_t flush_status_time;
299
295
 
300
 
fs::path basedir(PREFIX);
301
 
fs::path pid_file;
302
 
fs::path secure_file_priv("");
303
 
fs::path plugin_dir;
304
 
fs::path system_config_dir(SYSCONFDIR);
305
 
 
306
 
 
307
 
char system_time_zone[30];
 
296
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
308
297
char *default_tz_name;
309
298
char glob_hostname[FN_REFLEN];
310
 
 
311
 
char *opt_tc_log_file;
 
299
char data_home_real[FN_REFLEN],
 
300
     language[FN_REFLEN], 
 
301
     *opt_tc_log_file;
 
302
char data_home_real_unpacked[FN_REFLEN];
312
303
const key_map key_map_empty(0);
313
304
key_map key_map_full(0);                        // Will be initialized later
314
305
 
 
306
uint32_t data_home_len;
 
307
char data_home_buff[2], *data_home=data_home_real;
315
308
std::string drizzle_tmpdir;
316
309
char *opt_drizzle_tmpdir= NULL;
317
310
 
326
319
 
327
320
FILE *stderror_file=0;
328
321
 
329
 
struct drizzle_system_variables global_system_variables;
330
 
struct drizzle_system_variables max_system_variables;
 
322
struct system_variables global_system_variables;
 
323
struct system_variables max_system_variables;
331
324
struct global_counters current_global_counters;
332
325
 
333
326
const CHARSET_INFO *system_charset_info, *files_charset_info ;
339
332
SHOW_COMP_OPTION have_symlink;
340
333
 
341
334
/* Thread specific variables */
342
 
boost::mutex LOCK_global_system_variables;
343
 
 
344
 
boost::condition_variable_any COND_refresh;
 
335
 
 
336
pthread_key_t THR_Mem_root;
 
337
pthread_key_t THR_Session;
 
338
boost::mutex LOCK_open;
 
339
boost::recursive_mutex LOCK_global_system_variables;
 
340
boost::mutex LOCK_thread_count;
 
341
 
 
342
boost::condition_variable COND_refresh;
345
343
boost::condition_variable COND_thread_count;
346
344
pthread_t signal_thread;
347
345
boost::condition_variable COND_server_end;
349
347
/* Static variables */
350
348
 
351
349
int cleanup_done;
 
350
static char *drizzle_home_ptr, *pidfile_name_ptr;
 
351
static int defaults_argc;
 
352
static char **defaults_argv;
352
353
 
353
354
passwd *user_info;
354
355
 
355
356
atomic<uint32_t> connection_count;
356
357
 
357
 
global_buffer_constraint<uint64_t> global_sort_buffer(0);
358
 
global_buffer_constraint<uint64_t> global_join_buffer(0);
359
 
global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
360
 
global_buffer_constraint<uint64_t> global_read_buffer(0);
361
 
 
362
358
/** 
363
359
  Refresh value. We use to test this to find out if a refresh even has happened recently.
364
360
*/
368
364
bool drizzle_rm_tmp_tables();
369
365
 
370
366
static void drizzle_init_variables(void);
371
 
static void get_options();
372
 
static void fix_paths();
 
367
static void get_options(int *argc,char **argv);
 
368
int drizzled_get_one_option(int, const struct option *, char *);
 
369
static const char *get_relative_path(const char *path);
 
370
static void fix_paths(string &progname);
373
371
 
374
372
static void usage(void);
375
373
void close_connections(void);
376
374
 
377
 
fs::path base_plugin_dir(PKGPLUGINDIR);
378
 
 
379
 
po::options_description config_options("Config File Options");
380
 
po::options_description long_options("Kernel Options");
381
 
po::options_description plugin_load_options("Plugin Loading Options");
382
 
po::options_description plugin_options("Plugin Options");
383
 
po::options_description initial_options("Config and Plugin Loading");
384
 
po::options_description full_options("Kernel and Plugin Loading and Plugin");
385
 
vector<string> unknown_options;
386
 
vector<string> defaults_file_list;
 
375
po::options_description long_options("Allowed Options");
387
376
po::variables_map vm;
388
377
 
389
 
fs::path data_home(LOCALSTATEDIR);
390
 
fs::path full_data_home(LOCALSTATEDIR);
391
 
 
392
378
po::variables_map &getVariablesMap()
393
379
{
394
380
  return vm;
395
381
}
396
 
 
397
 
fs::path& getDataHome()
398
 
{
399
 
  return data_home;
400
 
}
401
 
 
402
 
fs::path& getDataHomeCatalog()
403
 
{
404
 
  static fs::path data_home_catalog(getDataHome());
405
 
  return data_home_catalog;
406
 
}
407
 
 
408
382
 
409
383
/****************************************************************************
410
384
** Code to end drizzled
416
390
  plugin::Listen::shutdown();
417
391
 
418
392
  /* kill connection thread */
 
393
  LOCK_thread_count.lock();
 
394
 
 
395
  while (select_thread_in_use)
419
396
  {
420
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
397
    struct timespec abstime;
 
398
    int error;
421
399
 
422
 
    while (select_thread_in_use)
 
400
    set_timespec(abstime, 2);
 
401
    for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
423
402
    {
424
 
      boost::xtime xt; 
425
 
      xtime_get(&xt, boost::TIME_UTC); 
426
 
      xt.sec += 2; 
427
 
 
428
 
      for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
429
 
      {
430
 
        bool success= COND_thread_count.timed_wait(scopedLock, xt);
431
 
        if (not success)
432
 
          break;
433
 
      }
 
403
      error= pthread_cond_timedwait(COND_thread_count.native_handle(),LOCK_thread_count.native_handle(), &abstime);
 
404
      if (error != EINTR)
 
405
        break;
434
406
    }
435
407
  }
 
408
  LOCK_thread_count.unlock();
436
409
 
437
410
 
438
411
  /*
441
414
    statements and inform their clients that the server is about to die.
442
415
  */
443
416
 
 
417
  Session *tmp;
 
418
 
 
419
  LOCK_thread_count.lock(); // For unlink from list
 
420
 
 
421
  for( SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
444
422
  {
445
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
446
 
    session::Cache::list list= session::Cache::singleton().getCache();
447
 
 
448
 
    for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
449
 
    {
450
 
      Session::shared_ptr tmp(*it);
451
 
 
452
 
      tmp->setKilled(Session::KILL_CONNECTION);
453
 
      tmp->scheduler->killSession(tmp.get());
454
 
      DRIZZLE_CONNECTION_DONE(tmp->thread_id);
455
 
 
456
 
      tmp->lockOnSys();
457
 
    }
 
423
    tmp= *it;
 
424
    tmp->killed= Session::KILL_CONNECTION;
 
425
    tmp->scheduler->killSession(tmp);
 
426
    DRIZZLE_CONNECTION_DONE(tmp->thread_id);
 
427
    tmp->lockOnSys();
458
428
  }
 
429
  LOCK_thread_count.unlock(); // For unlink from list
459
430
 
460
 
  if (session::Cache::singleton().count())
 
431
  if (connection_count)
461
432
    sleep(2);                                   // Give threads time to die
462
433
 
463
434
  /*
467
438
  */
468
439
  for (;;)
469
440
  {
470
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
471
 
    session::Cache::list list= session::Cache::singleton().getCache();
472
 
 
473
 
    if (list.empty())
 
441
    LOCK_thread_count.lock(); // For unlink from list
 
442
    if (getSessionList().empty())
474
443
    {
 
444
      LOCK_thread_count.unlock();
475
445
      break;
476
446
    }
 
447
    tmp= getSessionList().front();
477
448
    /* Close before unlock, avoiding crash. See LP bug#436685 */
478
 
    list.front()->client->close();
 
449
    tmp->client->close();
 
450
    LOCK_thread_count.unlock();
479
451
  }
480
452
}
481
453
 
 
454
/**
 
455
  cleanup all memory and end program nicely.
 
456
 
 
457
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
458
    by the main thread. To get Drizzle to shut down nicely in this case
 
459
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
460
 
 
461
  @note
 
462
    This function never returns.
 
463
*/
 
464
void unireg_end(void)
 
465
{
 
466
  clean_up(1);
 
467
  internal::my_thread_end();
 
468
#if defined(SIGNALS_DONT_BREAK_READ)
 
469
  exit(0);
 
470
#else
 
471
  pthread_exit(0);                              // Exit is in main thread
 
472
#endif
 
473
}
 
474
 
482
475
 
483
476
void unireg_abort(int exit_code)
484
477
{
485
478
 
486
479
  if (exit_code)
487
480
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
488
 
  else if (opt_help)
 
481
  else if (opt_help || opt_help_extended)
489
482
    usage();
490
483
  clean_up(!opt_help && (exit_code));
491
484
  internal::my_end();
499
492
    return;
500
493
 
501
494
  table_cache_free();
 
495
  set_var_free();
502
496
  free_charsets();
503
497
  module::Registry &modules= module::Registry::singleton();
504
498
  modules.shutdownModules();
505
499
  xid_cache_free();
 
500
  if (defaults_argv)
 
501
    internal::free_defaults(defaults_argv);
 
502
  if (opt_secure_file_priv)
 
503
    free(opt_secure_file_priv);
506
504
 
507
505
  deinit_temporal_formats();
508
506
 
510
508
  google::protobuf::ShutdownProtobufLibrary();
511
509
#endif
512
510
 
513
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
 
511
  (void) unlink(pidfile_name);  // This may not always exist
514
512
 
515
513
  if (print_message && server_start_time)
516
514
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
517
 
  {
518
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
519
 
    ready_to_exit= true;
520
 
 
521
 
    /* do the broadcast inside the lock to ensure that my_end() is not called */
522
 
    COND_server_end.notify_all();
523
 
  }
 
515
  LOCK_thread_count.lock();
 
516
  ready_to_exit=1;
 
517
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
518
  COND_server_end.notify_all();
 
519
  LOCK_thread_count.unlock();
524
520
 
525
521
  /*
526
522
    The following lines may never be executed as the main thread may have
550
546
    }
551
547
    return NULL;
552
548
  }
553
 
  if (not user)
 
549
  if (!user)
554
550
  {
555
551
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
556
552
                      "the manual to find out how to run drizzled as root!\n"));
594
590
void set_user(const char *user, passwd *user_info_arg)
595
591
{
596
592
  assert(user_info_arg != 0);
 
593
  /*
 
594
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
 
595
    is configured to use LDAP and the server is statically linked.  We set
 
596
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
 
597
    output a specific message to help the user resolve this problem.
 
598
  */
 
599
  calling_initgroups= true;
597
600
  initgroups((char*) user, user_info_arg->pw_gid);
 
601
  calling_initgroups= false;
598
602
  if (setgid(user_info_arg->pw_gid) == -1)
599
603
  {
600
 
    sql_perror(N_("Set process group ID failed"));
 
604
    sql_perror("setgid");
601
605
    unireg_abort(1);
602
606
  }
603
607
  if (setuid(user_info_arg->pw_uid) == -1)
604
608
  {
605
 
    sql_perror(N_("Set process user ID failed"));
 
609
    sql_perror("setuid");
606
610
    unireg_abort(1);
607
611
  }
608
612
}
614
618
{
615
619
  if ((chroot(path) == -1) || !chdir("/"))
616
620
  {
617
 
    sql_perror(N_("Process chroot failed"));
 
621
    sql_perror("chroot");
618
622
    unireg_abort(1);
619
623
  }
620
624
}
626
630
  SYNOPSIS
627
631
    Session::unlink()
628
632
    session              Thread handler
 
633
 
 
634
  NOTES
 
635
    LOCK_thread_count is locked and left locked
629
636
*/
630
637
 
631
 
void drizzled::Session::unlink(Session::shared_ptr &session)
 
638
void Session::unlink(Session *session)
632
639
{
633
640
  connection_count.decrement();
634
641
 
635
642
  session->cleanup();
636
643
 
637
 
  boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
638
 
 
639
 
  if (unlikely(plugin::EventObserver::disconnectSession(*session)))
640
 
  {
641
 
    // We should do something about an error...
642
 
  }
643
 
  session::Cache::singleton().erase(session);
 
644
  LOCK_thread_count.lock();
 
645
  session->lockForDelete();
 
646
 
 
647
  getSessionList().erase(remove(getSessionList().begin(),
 
648
                         getSessionList().end(),
 
649
                         session));
 
650
 
 
651
  delete session;
 
652
  LOCK_thread_count.unlock();
 
653
 
 
654
  return;
644
655
}
645
656
 
646
657
 
659
670
  DRIZZLE_CONFIG_NAME, "server", 0, 0
660
671
};
661
672
 
662
 
static void find_plugin_dir(string progname)
663
 
{
664
 
  if (progname[0] != FN_LIBCHAR)
665
 
  {
666
 
    /* We have a relative path and need to find the absolute */
667
 
    char working_dir[FN_REFLEN];
668
 
    char *working_dir_ptr= working_dir;
669
 
    working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
670
 
    string new_path(working_dir);
671
 
    if (*(new_path.end()-1) != '/')
672
 
      new_path.push_back('/');
673
 
    if (progname[0] == '.' && progname[1] == '/')
674
 
      new_path.append(progname.substr(2));
675
 
    else
676
 
      new_path.append(progname);
677
 
    progname.swap(new_path);
678
 
  }
679
 
 
680
 
  /* Now, trim off the exe name */
681
 
  string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
682
 
  if (progdir.rfind(".libs/") != string::npos)
683
 
  {
684
 
    progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
685
 
  }
686
 
  string testlofile(progdir);
687
 
  testlofile.append("drizzled.lo");
688
 
  string testofile(progdir);
689
 
  testofile.append("drizzled.o");
690
 
  struct stat testfile_stat;
691
 
  if (not (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat)))
692
 
  {
693
 
    /* We are in a source dir! Plugin dir is ../plugin/.libs */
694
 
    size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
695
 
    base_plugin_dir= progdir.substr(0,last_libchar_pos);
696
 
    base_plugin_dir /= "plugin";
697
 
    base_plugin_dir /= ".libs";
698
 
  }
699
 
 
700
 
  if (plugin_dir.root_directory() == "")
701
 
  {
702
 
    fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
703
 
    full_plugin_dir /= plugin_dir;
704
 
    plugin_dir= full_plugin_dir;
705
 
  }
706
 
}
707
 
 
708
 
static void notify_plugin_dir(fs::path in_plugin_dir)
709
 
{
710
 
  plugin_dir= in_plugin_dir;
711
 
  if (plugin_dir.root_directory() == "")
712
 
  {
713
 
    fs::path full_plugin_dir(fs::system_complete(basedir));
714
 
    full_plugin_dir /= plugin_dir;
715
 
    plugin_dir= full_plugin_dir;
716
 
  }
717
 
}
718
 
 
719
 
static void expand_secure_file_priv(fs::path in_secure_file_priv)
720
 
{
721
 
  secure_file_priv= fs::system_complete(in_secure_file_priv);
722
 
}
723
 
 
724
 
static void check_limits_aii(uint64_t in_auto_increment_increment)
725
 
{
726
 
  global_system_variables.auto_increment_increment= 1;
727
 
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
728
 
  {
729
 
    cout << N_("Error: Invalid Value for auto_increment_increment");
730
 
    exit(-1);
731
 
  }
732
 
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
733
 
}
734
 
 
735
 
static void check_limits_aio(uint64_t in_auto_increment_offset)
736
 
{
737
 
  global_system_variables.auto_increment_offset= 1;
738
 
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
739
 
  {
740
 
    cout << N_("Error: Invalid Value for auto_increment_offset");
741
 
    exit(-1);
742
 
  }
743
 
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
744
 
}
745
 
 
746
 
static void check_limits_completion_type(uint32_t in_completion_type)
747
 
{
748
 
  global_system_variables.completion_type= 0;
749
 
  if (in_completion_type > 2)
750
 
  {
751
 
    cout << N_("Error: Invalid Value for completion_type");
752
 
    exit(-1);
753
 
  }
754
 
  global_system_variables.completion_type= in_completion_type;
755
 
}
756
 
 
757
 
 
758
 
static void check_limits_dpi(uint32_t in_div_precincrement)
759
 
{
760
 
  global_system_variables.div_precincrement= 4;
761
 
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
762
 
  {
763
 
    cout << N_("Error: Invalid Value for div-precision-increment");
764
 
    exit(-1);
765
 
  }
766
 
  global_system_variables.div_precincrement= in_div_precincrement;
767
 
}
768
 
 
769
 
static void check_limits_gcml(uint64_t in_group_concat_max_len)
770
 
{
771
 
  global_system_variables.group_concat_max_len= 1024;
772
 
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
773
 
  {
774
 
    cout << N_("Error: Invalid Value for group_concat_max_len");
775
 
    exit(-1);
776
 
  }
777
 
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
778
 
}
779
 
 
780
 
static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
781
 
{
782
 
  global_system_variables.join_buff_size= (128*1024L);
783
 
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
784
 
  {
785
 
    cout << N_("Error: Invalid Value for join_buffer_size");
786
 
    exit(-1);
787
 
  }
788
 
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
789
 
  global_system_variables.join_buff_size= in_join_buffer_size;
790
 
}
791
 
 
792
 
static void check_limits_map(uint32_t in_max_allowed_packet)
793
 
{
794
 
  global_system_variables.max_allowed_packet= (64*1024*1024L);
795
 
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
796
 
  {
797
 
    cout << N_("Error: Invalid Value for max_allowed_packet");
798
 
    exit(-1);
799
 
  }
800
 
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
801
 
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
802
 
}
803
 
 
804
 
static void check_limits_mce(uint64_t in_max_connect_errors)
805
 
{
806
 
  max_connect_errors= MAX_CONNECT_ERRORS;
807
 
  if (in_max_connect_errors < 1 || in_max_connect_errors > ULONG_MAX)
808
 
  {
809
 
    cout << N_("Error: Invalid Value for max_connect_errors");
810
 
    exit(-1);
811
 
  }
812
 
  max_connect_errors= in_max_connect_errors;
813
 
}
814
 
 
815
 
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
816
 
{
817
 
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
818
 
  if (in_max_error_count > 65535)
819
 
  {
820
 
    cout << N_("Error: Invalid Value for max_error_count");
821
 
    exit(-1);
822
 
  }
823
 
  global_system_variables.max_error_count= in_max_error_count;
824
 
}
825
 
 
826
 
static void check_limits_mhts(uint64_t in_max_heap_table_size)
827
 
{
828
 
  global_system_variables.max_heap_table_size= (16*1024*1024L);
829
 
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
830
 
  {
831
 
    cout << N_("Error: Invalid Value for max_heap_table_size");
832
 
    exit(-1);
833
 
  }
834
 
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
835
 
  global_system_variables.max_heap_table_size= in_max_heap_table_size;
836
 
}
837
 
 
838
 
static void check_limits_merl(uint64_t in_min_examined_row_limit)
839
 
{
840
 
  global_system_variables.min_examined_row_limit= 0;
841
 
  if (in_min_examined_row_limit > ULONG_MAX)
842
 
  {
843
 
    cout << N_("Error: Invalid Value for min_examined_row_limit");
844
 
    exit(-1);
845
 
  }
846
 
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
847
 
}
848
 
 
849
 
static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
850
 
{
851
 
  global_system_variables.max_join_size= INT32_MAX;
852
 
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
853
 
  {
854
 
    cout << N_("Error: Invalid Value for max_join_size");
855
 
    exit(-1);
856
 
  }
857
 
  global_system_variables.max_join_size= in_max_join_size;
858
 
}
859
 
 
860
 
static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
861
 
{
862
 
  global_system_variables.max_length_for_sort_data= 1024;
863
 
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
864
 
  {
865
 
    cout << N_("Error: Invalid Value for max_length_for_sort_data");
866
 
    exit(-1);
867
 
  }
868
 
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
869
 
}
870
 
 
871
 
static void check_limits_msfk(uint64_t in_max_seeks_for_key)
872
 
{
873
 
  global_system_variables.max_seeks_for_key= ULONG_MAX;
874
 
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
875
 
  {
876
 
    cout << N_("Error: Invalid Value for max_seeks_for_key");
877
 
    exit(-1);
878
 
  }
879
 
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
880
 
}
881
 
 
882
 
static void check_limits_max_sort_length(size_t in_max_sort_length)
883
 
{
884
 
  global_system_variables.max_sort_length= 1024;
885
 
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
886
 
  {
887
 
    cout << N_("Error: Invalid Value for max_sort_length");
888
 
    exit(-1);
889
 
  }
890
 
  global_system_variables.max_sort_length= in_max_sort_length;
891
 
}
892
 
 
893
 
static void check_limits_osd(uint32_t in_optimizer_search_depth)
894
 
{
895
 
  global_system_variables.optimizer_search_depth= 0;
896
 
  if (in_optimizer_search_depth > MAX_TABLES + 2)
897
 
  {
898
 
    cout << N_("Error: Invalid Value for optimizer_search_depth");
899
 
    exit(-1);
900
 
  }
901
 
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
902
 
}
903
 
 
904
 
static void check_limits_pbs(uint64_t in_preload_buff_size)
905
 
{
906
 
  global_system_variables.preload_buff_size= (32*1024L);
907
 
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
908
 
  {
909
 
    cout << N_("Error: Invalid Value for preload_buff_size");
910
 
    exit(-1);
911
 
  }
912
 
  global_system_variables.preload_buff_size= in_preload_buff_size;
913
 
}
914
 
 
915
 
static void check_limits_qabs(uint32_t in_query_alloc_block_size)
916
 
{
917
 
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
918
 
  if (in_query_alloc_block_size < 1024)
919
 
  {
920
 
    cout << N_("Error: Invalid Value for query_alloc_block_size");
921
 
    exit(-1);
922
 
  }
923
 
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
924
 
  global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
925
 
}
926
 
 
927
 
static void check_limits_qps(uint32_t in_query_prealloc_size)
928
 
{
929
 
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
930
 
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
931
 
  {
932
 
    cout << N_("Error: Invalid Value for query_prealloc_size");
933
 
    exit(-1);
934
 
  }
935
 
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
936
 
  global_system_variables.query_prealloc_size= in_query_prealloc_size;
937
 
}
938
 
 
939
 
static void check_limits_rabs(size_t in_range_alloc_block_size)
940
 
{
941
 
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
942
 
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
943
 
  {
944
 
    cout << N_("Error: Invalid Value for range_alloc_block_size");
945
 
    exit(-1);
946
 
  }
947
 
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
948
 
  global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
949
 
}
950
 
 
951
 
static void check_limits_read_buffer_size(int32_t in_read_buff_size)
952
 
{
953
 
  global_system_variables.read_buff_size= (128*1024L);
954
 
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
955
 
  {
956
 
    cout << N_("Error: Invalid Value for read_buff_size");
957
 
    exit(-1);
958
 
  }
959
 
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
960
 
  global_system_variables.read_buff_size= in_read_buff_size;
961
 
}
962
 
 
963
 
static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
964
 
{
965
 
  global_system_variables.read_rnd_buff_size= (256*1024L);
966
 
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
967
 
  {
968
 
    cout << N_("Error: Invalid Value for read_rnd_buff_size");
969
 
    exit(-1);
970
 
  }
971
 
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
972
 
}
973
 
 
974
 
static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
975
 
{
976
 
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
977
 
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
978
 
  {
979
 
    cout << N_("Error: Invalid Value for sort_buff_size");
980
 
    exit(-1);
981
 
  }
982
 
  global_system_variables.sortbuff_size= in_sortbuff_size;
983
 
}
984
 
 
985
 
static void check_limits_tdc(uint32_t in_table_def_size)
986
 
{
987
 
  table_def_size= 128;
988
 
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
989
 
  {
990
 
    cout << N_("Error: Invalid Value for table_def_size");
991
 
    exit(-1);
992
 
  }
993
 
  table_def_size= in_table_def_size;
994
 
}
995
 
 
996
 
static void check_limits_toc(uint32_t in_table_cache_size)
997
 
{
998
 
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
999
 
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
1000
 
  {
1001
 
    cout << N_("Error: Invalid Value for table_cache_size");
1002
 
    exit(-1);
1003
 
  }
1004
 
  table_cache_size= in_table_cache_size;
1005
 
}
1006
 
 
1007
 
static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
1008
 
{
1009
 
  table_lock_wait_timeout= 50;
1010
 
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
1011
 
  {
1012
 
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1013
 
    exit(-1);
1014
 
  }
1015
 
  table_lock_wait_timeout= in_table_lock_wait_timeout;
1016
 
}
1017
 
 
1018
 
static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
1019
 
{
1020
 
  my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
1021
 
}
1022
 
 
1023
 
static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
1024
 
{
1025
 
  global_system_variables.tmp_table_size= 16*1024*1024L;
1026
 
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
1027
 
  {
1028
 
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1029
 
    exit(-1);
1030
 
  }
1031
 
  global_system_variables.tmp_table_size= in_tmp_table_size;
1032
 
}
1033
 
 
1034
 
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1035
 
{
1036
 
  global_system_variables.transaction_message_threshold= 1024*1024;
1037
 
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1038
 
  {
1039
 
    cout << N_("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1040
 
    exit(-1);
1041
 
  }
1042
 
  global_system_variables.transaction_message_threshold= in_transaction_message_threshold;
1043
 
}
1044
 
 
1045
 
static void process_defaults_files()
1046
 
{
1047
 
  for (vector<string>::iterator iter= defaults_file_list.begin();
1048
 
       iter != defaults_file_list.end();
1049
 
       ++iter)
1050
 
  {
1051
 
    fs::path file_location= *iter;
1052
 
 
1053
 
    ifstream input_defaults_file(file_location.file_string().c_str());
1054
 
    
1055
 
    po::parsed_options file_parsed=
1056
 
      dpo::parse_config_file(input_defaults_file, full_options, true);
1057
 
    vector<string> file_unknown= 
1058
 
      po::collect_unrecognized(file_parsed.options, po::include_positional);
1059
 
 
1060
 
    for (vector<string>::iterator it= file_unknown.begin();
1061
 
         it != file_unknown.end();
1062
 
         ++it)
1063
 
    {
1064
 
      string new_unknown_opt("--");
1065
 
      new_unknown_opt.append(*it);
1066
 
      ++it;
1067
 
      if (it != file_unknown.end())
1068
 
      {
1069
 
        if ((*it) != "true")
1070
 
        {
1071
 
          new_unknown_opt.push_back('=');
1072
 
          new_unknown_opt.append(*it);
1073
 
        }
1074
 
      }
1075
 
      else
1076
 
      {
1077
 
        break;
1078
 
      }
1079
 
      unknown_options.push_back(new_unknown_opt);
1080
 
    }
1081
 
    store(file_parsed, vm);
1082
 
  }
1083
 
}
1084
 
 
1085
 
static void compose_defaults_file_list(vector<string> in_options)
1086
 
{
1087
 
  for (vector<string>::iterator it= in_options.begin();
1088
 
       it != in_options.end();
1089
 
       ++it)
1090
 
  {
1091
 
    fs::path p(*it);
1092
 
    if (fs::is_regular_file(p))
1093
 
      defaults_file_list.push_back(*it);
1094
 
    else
1095
 
    {
1096
 
      errmsg_printf(ERRMSG_LVL_ERROR,
1097
 
                  _("Defaults file '%s' not found\n"), (*it).c_str());
1098
 
      unireg_abort(1);
1099
 
    }
1100
 
 
1101
 
  }
1102
 
}
1103
 
 
1104
 
int init_common_variables(int argc, char **argv, module::Registry &plugins)
 
673
int init_common_variables(const char *conf_file_name, int argc,
 
674
                          char **argv, const char **groups)
1105
675
{
1106
676
  time_t curr_time;
1107
677
  umask(((~internal::my_umask) & 0666));
1115
685
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1116
686
  server_start_time= flush_status_time= curr_time;
1117
687
 
 
688
  if (init_thread_environment())
 
689
    return 1;
1118
690
  drizzle_init_variables();
1119
691
 
1120
 
  find_plugin_dir(argv[0]);
1121
692
  {
1122
693
    struct tm tm_tmp;
1123
694
    localtime_r(&server_start_time,&tm_tmp);
1138
709
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1139
710
    errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1140
711
                  glob_hostname);
1141
 
    pid_file= "drizzle";
 
712
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1142
713
  }
1143
714
  else
1144
 
  {
1145
 
    pid_file= glob_hostname;
1146
 
  }
1147
 
  pid_file.replace_extension(".pid");
1148
 
 
1149
 
  system_config_dir /= "drizzle";
1150
 
 
1151
 
  config_options.add_options()
1152
 
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1153
 
  N_("Display this help and exit."))
1154
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1155
 
  N_("Configuration file defaults are not used if no-defaults is set"))
1156
 
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1157
 
   N_("Configuration file to use"))
1158
 
  ("config-dir", po::value<fs::path>(&system_config_dir),
1159
 
   N_("Base location for config files"))
1160
 
  ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(&notify_plugin_dir),
1161
 
  N_("Directory for plugins."))
1162
 
  ;
1163
 
 
1164
 
  plugin_load_options.add_options()
1165
 
  ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1166
 
  N_("Optional comma separated list of plugins to load at startup in addition "
1167
 
     "to the default list of plugins. "
1168
 
     "[for example: --plugin_add=crc32,logger_gearman]"))    
1169
 
  ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1170
 
  N_("Optional comma separated list of plugins to not load at startup. Effectively "
1171
 
     "removes a plugin from the list of plugins to be loaded. "
1172
 
     "[for example: --plugin_remove=crc32,logger_gearman]"))
1173
 
  ("plugin-load", po::value<string>()->notifier(&notify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1174
 
  N_("Optional comma separated list of plugins to load at starup instead of "
1175
 
     "the default plugin load list. "
1176
 
     "[for example: --plugin_load=crc32,logger_gearman]"))
1177
 
  ;
1178
 
 
1179
 
  long_options.add_options()
1180
 
  ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1181
 
  N_("Auto-increment columns are incremented by this"))
1182
 
  ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1183
 
  N_("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1184
 
  ("basedir,b", po::value<fs::path>(&basedir),
1185
 
  N_("Path to installation directory. All paths are usually resolved "
1186
 
     "relative to this."))
1187
 
  ("chroot,r", po::value<string>(),
1188
 
  N_("Chroot drizzled daemon during startup."))
1189
 
  ("collation-server", po::value<string>(),
1190
 
  N_("Set the default collation."))      
1191
 
  ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1192
 
  N_("Default completion type."))
1193
 
  ("core-file",  N_("Write core on errors."))
1194
 
  ("datadir", po::value<fs::path>(&data_home),
1195
 
  N_("Path to the database root."))
1196
 
  ("default-storage-engine", po::value<string>(),
1197
 
  N_("Set the default storage engine for tables."))
1198
 
  ("default-time-zone", po::value<string>(),
1199
 
  N_("Set the default time zone."))
1200
 
  ("exit-info,T", po::value<long>(),
1201
 
  N_("Used for debugging;  Use at your own risk!"))
1202
 
  ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1203
 
  N_("Set up signals usable for debugging"))
1204
 
  ("lc-time-name", po::value<string>(),
1205
 
  N_("Set the language used for the month names and the days of the week."))
1206
 
  ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1207
 
  N_("Log some not critical warnings to the log file."))  
1208
 
  ("pid-file", po::value<fs::path>(&pid_file),
1209
 
  N_("Pid file used by drizzled."))
1210
 
  ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1211
 
  N_("Maximum time in seconds to wait for the port to become free. "))
1212
 
  ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1213
 
  N_("Include the SQL query in replicated protobuf messages."))
1214
 
  ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1215
 
  N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1216
 
     "within specified directory"))
1217
 
  ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1218
 
  N_("Uniquely identifies the server instance in the community of "
1219
 
     "replication partners."))
1220
 
  ("skip-stack-trace",  
1221
 
  N_("Don't print a stack trace on failure."))
1222
 
  ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1223
 
  N_("Enable symbolic link support."))
1224
 
  ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1225
 
  N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1226
 
     "supported)")) 
1227
 
  ("tmpdir,t", po::value<string>(),
1228
 
  N_("Path for temporary files."))
1229
 
  ("transaction-isolation", po::value<string>(),
1230
 
  N_("Default transaction isolation level."))
1231
 
  ("transaction-message-threshold", po::value<size_t>(&global_system_variables.transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1232
 
  N_("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1233
 
  ("user,u", po::value<string>(),
1234
 
  N_("Run drizzled daemon as user."))  
1235
 
  ("version,V", 
1236
 
  N_("Output version information and exit."))
1237
 
  ("back-log", po::value<back_log_constraints>(&back_log),
1238
 
  N_("The number of outstanding connection requests Drizzle can have. This "
1239
 
     "comes into play when the main Drizzle thread gets very many connection "
1240
 
     "requests in a very short time."))
1241
 
  ("bulk-insert-buffer-size", 
1242
 
  po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1243
 
  N_("Size of tree cache used in bulk insert optimization. Note that this is "
1244
 
     "a limit per thread!"))
1245
 
  ("div-precision-increment",  po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1246
 
  N_("Precision of the result of '/' operator will be increased on that "
1247
 
     "value."))
1248
 
  ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1249
 
  N_("The maximum length of the result of function  group_concat."))
1250
 
  ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1251
 
  N_("The size of the buffer that is used for full joins."))
1252
 
  ("join-heap-threshold",
1253
 
  po::value<uint64_t>()->default_value(0),
1254
 
  N_("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1255
 
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1256
 
  N_("Max packetlength to send/receive from to server."))
1257
 
  ("max-connect-errors", po::value<uint64_t>(&max_connect_errors)->default_value(MAX_CONNECT_ERRORS)->notifier(&check_limits_mce),
1258
 
  N_("If there is more than this number of interrupted connections from a "
1259
 
     "host this host will be blocked from further connections."))
1260
 
  ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1261
 
  N_("Max number of errors/warnings to store for a statement."))
1262
 
  ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1263
 
  N_("Don't allow creation of heap tables bigger than this."))
1264
 
  ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1265
 
  N_("Joins that are probably going to read more than max_join_size records "
1266
 
     "return an error."))
1267
 
  ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1268
 
  N_("Max number of bytes in sorted records."))
1269
 
  ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1270
 
  N_("Limit assumed max number of seeks when looking up rows based on a key"))
1271
 
  ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),  
1272
 
  N_("The number of bytes to use when sorting BLOB or TEXT values "
1273
 
     "(only the first max_sort_length bytes of each value are used; the "
1274
 
     "rest are ignored)."))
1275
 
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1276
 
  N_("After this many write locks, allow some read locks to run in between."))
1277
 
  ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1278
 
  N_("Don't log queries which examine less than min_examined_row_limit "
1279
 
     "rows to file."))
1280
 
  ("disable-optimizer-prune",
1281
 
  N_("Do not apply any heuristic(s) during query optimization to prune, "
1282
 
     "thus perform an exhaustive search from the optimizer search space."))
1283
 
  ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1284
 
  N_("Maximum depth of search performed by the query optimizer. Values "
1285
 
     "larger than the number of relations in a query result in better query "
1286
 
     "plans, but take longer to compile a query. Smaller values than the "
1287
 
     "number of tables in a relation result in faster optimization, but may "
1288
 
     "produce very bad query plans. If set to 0, the system will "
1289
 
     "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1290
 
     "optimizer will switch to the original find_best (used for "
1291
 
     "testing/comparison)."))
1292
 
  ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1293
 
  N_("The size of the buffer that is allocated when preloading indexes"))
1294
 
  ("query-alloc-block-size", 
1295
 
  po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1296
 
  N_("Allocation block size for query parsing and execution"))
1297
 
  ("query-prealloc-size",
1298
 
  po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1299
 
  N_("Persistent buffer for query parsing and execution"))
1300
 
  ("range-alloc-block-size",
1301
 
  po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1302
 
  N_("Allocation block size for storing ranges during optimization"))
1303
 
  ("read-buffer-size",
1304
 
  po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1305
 
  N_("Each thread that does a sequential scan allocates a buffer of this "
1306
 
      "size for each table it scans. If you do many sequential scans, you may "
1307
 
      "want to increase this value."))
1308
 
  ("read-buffer-threshold",
1309
 
  po::value<uint64_t>()->default_value(0),
1310
 
  N_("A global cap on the size of read-buffer-size (0 means unlimited)"))
1311
 
  ("read-rnd-buffer-size",
1312
 
  po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1313
 
  N_("When reading rows in sorted order after a sort, the rows are read "
1314
 
     "through this buffer to avoid a disk seeks. If not set, then it's set "
1315
 
     "to the value of record_buffer."))
1316
 
  ("read-rnd-threshold",
1317
 
  po::value<uint64_t>()->default_value(0),
1318
 
  N_("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1319
 
  ("scheduler", po::value<string>(),
1320
 
  N_("Select scheduler to be used (by default multi-thread)."))
1321
 
  ("sort-buffer-size",
1322
 
  po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1323
 
  N_("Each thread that needs to do a sort allocates a buffer of this size."))
1324
 
  ("sort-heap-threshold",
1325
 
  po::value<uint64_t>()->default_value(0),
1326
 
  N_("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
1327
 
  ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1328
 
  N_("The number of cached table definitions."))
1329
 
  ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1330
 
  N_("The number of cached open tables."))
1331
 
  ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1332
 
  N_("Timeout in seconds to wait for a table level lock before returning an "
1333
 
     "error. Used only if the connection has active cursors."))
1334
 
  ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1335
 
  N_("The stack size for each thread."))
1336
 
  ("tmp-table-size", 
1337
 
  po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1338
 
  N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1339
 
     " automatically convert it to an on-disk MyISAM table."))
1340
 
  ;
1341
 
 
1342
 
  full_options.add(long_options);
1343
 
  full_options.add(plugin_load_options);
1344
 
 
1345
 
  initial_options.add(config_options);
1346
 
  initial_options.add(plugin_load_options);
1347
 
 
1348
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1349
 
  /* Get options about where config files and the like are */
1350
 
  po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1351
 
    options(initial_options).allow_unregistered().run();
1352
 
  unknown_options=
1353
 
    po::collect_unrecognized(parsed.options, po::include_positional);
1354
 
 
1355
 
  try
1356
 
  {
1357
 
    po::store(parsed, vm);
1358
 
  }
1359
 
  catch (std::exception&)
1360
 
  {
1361
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Duplicate entry for command line option\n"));
1362
 
    unireg_abort(1);
1363
 
  }
1364
 
 
1365
 
  if (not vm["no-defaults"].as<bool>())
1366
 
  {
1367
 
    fs::path system_config_file_drizzle(system_config_dir);
1368
 
    system_config_file_drizzle /= "drizzled.cnf";
1369
 
    defaults_file_list.insert(defaults_file_list.begin(),
1370
 
                              system_config_file_drizzle.file_string());
1371
 
 
1372
 
    fs::path config_conf_d_location(system_config_dir);
1373
 
    config_conf_d_location /= "conf.d";
1374
 
 
1375
 
 
1376
 
    CachedDirectory config_conf_d(config_conf_d_location.file_string());
1377
 
    if (not config_conf_d.fail())
1378
 
    {
1379
 
 
1380
 
      for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1381
 
           iter != config_conf_d.getEntries().end();
1382
 
           ++iter)
1383
 
      {
1384
 
        string file_entry((*iter)->filename);
1385
 
 
1386
 
        if (not file_entry.empty()
1387
 
            && file_entry != "."
1388
 
            && file_entry != "..")
1389
 
        {
1390
 
          fs::path the_entry(config_conf_d_location);
1391
 
          the_entry /= file_entry;
1392
 
          defaults_file_list.push_back(the_entry.file_string());
1393
 
        }
1394
 
      }
1395
 
    }
1396
 
  }
1397
 
 
1398
 
  /* TODO: here is where we should add a process_env_vars */
1399
 
 
1400
 
  /* We need a notify here so that plugin_init will work properly */
1401
 
  try
1402
 
  {
1403
 
    po::notify(vm);
1404
 
  }
1405
 
  catch (po::validation_error &err)
1406
 
  {
1407
 
    errmsg_printf(ERRMSG_LVL_ERROR,  
1408
 
                  _("%s: %s.\n"
1409
 
                    "Use --help to get a list of available options\n"),
1410
 
                  internal::my_progname, err.what());
1411
 
    unireg_abort(1);
1412
 
  }
1413
 
 
1414
 
  process_defaults_files();
1415
 
 
1416
 
  /* Process with notify a second time because a config file may contain
1417
 
     plugin loader options */
1418
 
 
1419
 
  try
1420
 
  {
1421
 
    po::notify(vm);
1422
 
  }
1423
 
  catch (po::validation_error &err)
1424
 
  {
1425
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1426
 
                  _("%s: %s.\n"
1427
 
                    "Use --help to get a list of available options\n"),
1428
 
                  internal::my_progname, err.what());
1429
 
    unireg_abort(1);
1430
 
  }
1431
 
 
1432
 
  /* At this point, we've read all the options we need to read from files and
1433
 
     collected most of them into unknown options - now let's load everything
1434
 
  */
1435
 
 
1436
 
  if (plugin_init(plugins, plugin_options))
1437
 
  {
1438
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins\n"));
1439
 
    unireg_abort(1);
1440
 
  }
1441
 
 
1442
 
  full_options.add(plugin_options);
1443
 
 
1444
 
  vector<string> final_unknown_options;
1445
 
  try
1446
 
  {
1447
 
    po::parsed_options final_parsed=
1448
 
      po::command_line_parser(unknown_options).style(style).
1449
 
      options(full_options).extra_parser(dpo::parse_size_arg).run();
1450
 
 
1451
 
    final_unknown_options=
1452
 
      po::collect_unrecognized(final_parsed.options, po::include_positional);
1453
 
 
1454
 
    po::store(final_parsed, vm);
1455
 
 
1456
 
  }
1457
 
  catch (po::validation_error &err)
1458
 
  {
1459
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1460
 
                  _("%s: %s.\n"
1461
 
                    "Use --help to get a list of available options\n"),
1462
 
                  internal::my_progname, err.what());
1463
 
    unireg_abort(1);
1464
 
  }
1465
 
  catch (po::invalid_command_line_syntax &err)
1466
 
  {
1467
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1468
 
                  _("%s: %s.\n"
1469
 
                    "Use --help to get a list of available options\n"),
1470
 
                  internal::my_progname, err.what());
1471
 
    unireg_abort(1);
1472
 
  }
1473
 
  catch (po::unknown_option &err)
1474
 
  {
1475
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1476
 
                  _("%s\nUse --help to get a list of available options\n"),
1477
 
                  err.what());
1478
 
    unireg_abort(1);
1479
 
  }
1480
 
 
1481
 
  try
1482
 
  {
1483
 
    po::notify(vm);
1484
 
  }
1485
 
  catch (po::validation_error &err)
1486
 
  {
1487
 
    errmsg_printf(ERRMSG_LVL_ERROR,  
1488
 
                  _("%s: %s.\n"
1489
 
                    "Use --help to get a list of available options\n"),
1490
 
                  internal::my_progname, err.what());
1491
 
    unireg_abort(1);
1492
 
  }
1493
 
 
1494
 
  get_options();
1495
 
 
1496
 
  /* Inverted Booleans */
1497
 
 
1498
 
  global_system_variables.optimizer_prune_level=
1499
 
    vm.count("disable-optimizer-prune") ? false : true;
1500
 
 
1501
 
  if (vm.count("help") == 0 && vm.count("help-extended") == 0)
1502
 
  {
1503
 
    if ((user_info= check_user(drizzled_user)))
1504
 
    {
1505
 
      set_user(drizzled_user, user_info);
1506
 
    }
1507
 
  }
1508
 
 
1509
 
  fix_paths();
 
715
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
716
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
 
717
 
 
718
  internal::load_defaults(conf_file_name, groups, &argc, &argv);
 
719
  defaults_argv=argv;
 
720
  defaults_argc=argc;
 
721
  get_options(&defaults_argc, defaults_argv);
1510
722
 
1511
723
  current_pid= getpid();                /* Save for later ref */
1512
724
  init_time();                          /* Init time-functions (read zone) */
1513
725
 
1514
726
  if (item_create_init())
1515
727
    return 1;
1516
 
  if (sys_var_init())
 
728
  if (set_var_init())
1517
729
    return 1;
1518
730
  /* Creates static regex matching for temporal values */
1519
731
  if (! init_temporal_formats())
1522
734
  if (!(default_charset_info=
1523
735
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1524
736
  {
1525
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error getting default charset"));
1526
737
    return 1;                           // Eof of the list
1527
738
  }
1528
739
 
1529
 
  if (vm.count("scheduler"))
1530
 
    opt_scheduler= vm["scheduler"].as<string>().c_str();
1531
 
 
1532
740
  if (default_collation_name)
1533
741
  {
1534
742
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1551
759
 
1552
760
  if (not (character_set_filesystem=
1553
761
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1554
 
  {
1555
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error setting collation"));
1556
762
    return 1;
1557
 
  }
1558
763
  global_system_variables.character_set_filesystem= character_set_filesystem;
1559
764
 
1560
765
  if (!(my_default_lc_time_names=
1572
777
}
1573
778
 
1574
779
 
 
780
int init_thread_environment()
 
781
{
 
782
  if (pthread_key_create(&THR_Session,NULL) ||
 
783
      pthread_key_create(&THR_Mem_root,NULL))
 
784
  {
 
785
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
 
786
    return 1;
 
787
  }
 
788
  return 0;
 
789
}
 
790
 
 
791
static pair<string, string> parse_size_suffixes(string s)
 
792
{
 
793
  size_t equal_pos= s.find("=");
 
794
  if (equal_pos != string::npos)
 
795
  {
 
796
    string arg_key(s.substr(0, equal_pos));
 
797
    string arg_val(s.substr(equal_pos+1));
 
798
 
 
799
    try
 
800
    {
 
801
      size_t size_suffix_pos= arg_val.find_last_of("kmgKMG");
 
802
      if (size_suffix_pos == arg_val.size()-1)
 
803
      {
 
804
        char suffix= arg_val[size_suffix_pos];
 
805
        string size_val(arg_val.substr(0, size_suffix_pos));
 
806
 
 
807
        uint64_t base_size= boost::lexical_cast<uint64_t>(size_val);
 
808
        uint64_t new_size= 0;
 
809
 
 
810
        switch (suffix)
 
811
        {
 
812
        case 'K':
 
813
        case 'k':
 
814
          new_size= base_size * 1024;
 
815
          break;
 
816
        case 'M':
 
817
        case 'm':
 
818
          new_size= base_size * 1024 * 1024;
 
819
          break;
 
820
        case 'G':
 
821
        case 'g':
 
822
          new_size= base_size * 1024 * 1024 * 1024;
 
823
          break;
 
824
        }
 
825
        return make_pair(arg_key,
 
826
                         boost::lexical_cast<string>(new_size));
 
827
      }
 
828
    }
 
829
    catch (...)
 
830
    {
 
831
      /* Screw it, let the normal parser take over */
 
832
    }
 
833
  }
 
834
 
 
835
  return make_pair(string(""), string(""));
 
836
}
 
837
 
 
838
static pair<string, string> parse_size_arg(string s)
 
839
{
 
840
  if (s.find("--") == 0)
 
841
  {
 
842
    return parse_size_suffixes(s.substr(2));
 
843
  }
 
844
  return make_pair(string(""), string(""));
 
845
}
 
846
 
1575
847
int init_server_components(module::Registry &plugins)
1576
848
{
1577
849
  /*
1579
851
    all things are initialized so that unireg_abort() doesn't fail
1580
852
  */
1581
853
  if (table_cache_init())
1582
 
  {
1583
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not initialize table cache\n"));
1584
854
    unireg_abort(1);
1585
 
  }
1586
 
 
1587
 
  // Resize the definition Cache at startup
1588
 
  table::Cache::singleton().rehash(table_def_size);
1589
 
  definition::Cache::singleton().rehash(table_def_size);
1590
 
  message::Cache::singleton().rehash(table_def_size);
 
855
  TableShare::cacheStart();
1591
856
 
1592
857
  setup_fpu();
1593
858
 
1595
860
 
1596
861
  if (xid_cache_init())
1597
862
  {
1598
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("XA cache initialization failed: Out of memory\n"));
 
863
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1599
864
    unireg_abort(1);
1600
865
  }
1601
866
 
1602
867
  /* Allow storage engine to give real error messages */
1603
868
  ha_init_errors();
1604
869
 
1605
 
 
1606
 
  if (opt_help)
 
870
  if (plugin_init(plugins, &defaults_argc, defaults_argv, long_options))
 
871
  {
 
872
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
 
873
    unireg_abort(1);
 
874
  }
 
875
 
 
876
 
 
877
  if (opt_help || opt_help_extended)
1607
878
    unireg_abort(0);
1608
879
 
1609
 
  if (plugin_finalize(plugins))
 
880
  po::parsed_options parsed= po::command_line_parser(defaults_argc,
 
881
                                                     defaults_argv).
 
882
    options(long_options).extra_parser(parse_size_arg).
 
883
    allow_unregistered().run();
 
884
 
 
885
  vector<string> unknown_options=
 
886
    po::collect_unrecognized(parsed.options, po::include_positional);
 
887
 
 
888
  /* we do want to exit if there are any other unknown options */
 
889
  /** @TODO: We should perhaps remove allowed_unregistered() and catch the
 
890
    exception here */
 
891
  if (unknown_options.size() > 0)
1610
892
  {
1611
 
    unireg_abort(1);
 
893
     fprintf(stderr,
 
894
            _("%s: Too many arguments (first extra is '%s').\n"
 
895
              "Use --verbose --help to get a list of available options\n"),
 
896
            internal::my_progname, unknown_options[0].c_str());
 
897
      unireg_abort(1);
1612
898
  }
1613
899
 
 
900
  po::store(parsed, vm);
 
901
  po::notify(vm);
 
902
 
 
903
  plugin_finalize(plugins);
 
904
 
1614
905
  string scheduler_name;
1615
906
  if (opt_scheduler)
1616
907
  {
1649
940
    engine= plugin::StorageEngine::findByName(name);
1650
941
    if (engine == NULL)
1651
942
    {
1652
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s\n"),
 
943
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s"),
1653
944
                    default_storage_engine_str);
1654
945
      unireg_abort(1);
1655
946
    }
1656
947
    global_system_variables.storage_engine= engine;
1657
948
  }
1658
949
 
1659
 
  if (plugin::XaResourceManager::recoverAllXids())
 
950
  if (plugin::XaResourceManager::recoverAllXids(0))
1660
951
  {
1661
 
    /* This function alredy generates error messages */
1662
952
    unireg_abort(1);
1663
953
  }
1664
954
 
1733
1023
  OPT_PLUGIN_DIR,
1734
1024
  OPT_PORT_OPEN_TIMEOUT,
1735
1025
  OPT_SECURE_FILE_PRIV,
1736
 
  OPT_MIN_EXAMINED_ROW_LIMIT,
1737
 
  OPT_PRINT_DEFAULTS
 
1026
  OPT_MIN_EXAMINED_ROW_LIMIT
1738
1027
};
1739
1028
 
1740
1029
 
1741
1030
struct option my_long_options[] =
1742
1031
{
1743
 
 
1744
1032
  {"help", '?', N_("Display this help and exit."),
1745
1033
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1746
1034
   0, 0},
 
1035
  {"help-extended", '?',
 
1036
   N_("Display this help and exit after initializing plugins."),
 
1037
   (char**) &opt_help_extended, (char**) &opt_help_extended,
 
1038
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1747
1039
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1748
1040
   N_("Auto-increment columns are incremented by this"),
1749
1041
   (char**) &global_system_variables.auto_increment_increment,
1750
1042
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1751
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
 
1043
   OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1752
1044
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1753
1045
   N_("Offset added to Auto-increment columns. Used when "
1754
1046
      "auto-increment-increment != 1"),
1755
1047
   (char**) &global_system_variables.auto_increment_offset,
1756
1048
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1757
 
   1, 1, INT64_MAX, 0, 1, 0 },
 
1049
   1, 1, UINT64_MAX, 0, 1, 0 },
1758
1050
  {"basedir", 'b',
1759
1051
   N_("Path to installation directory. All paths are usually resolved "
1760
1052
      "relative to this."),
1761
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
 
1053
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1762
1054
   0, 0, 0, 0, 0, 0},
1763
1055
  {"chroot", 'r',
1764
1056
   N_("Chroot drizzled daemon during startup."),
1779
1071
   NO_ARG, 0, 0, 0, 0, 0, 0},
1780
1072
  {"datadir", 'h',
1781
1073
   N_("Path to the database root."),
1782
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1074
   (char**) &data_home,
 
1075
   (char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1783
1076
  {"default-storage-engine", OPT_STORAGE_ENGINE,
1784
1077
   N_("Set the default storage engine (table type) for tables."),
1785
1078
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1798
1091
   N_("Set up signals usable for debugging"),
1799
1092
   (char**) &opt_debugging, (char**) &opt_debugging,
1800
1093
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1094
  {"language", 'L',
 
1095
   N_("(IGNORED)"),
 
1096
   (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
 
1097
   0, 0, 0, 0, 0, 0},
1801
1098
  {"lc-time-names", OPT_LC_TIME_NAMES,
1802
1099
   N_("Set the language used for the month names and the days of the week."),
1803
1100
   (char**) &lc_time_names_name,
1809
1106
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1810
1107
   0, 0, 0},
1811
1108
  {"pid-file", OPT_PID_FILE,
1812
 
   N_("Pid file used by drizzled."),
1813
 
   NULL, NULL, 0, GET_STR,
 
1109
   N_("Pid file used by safe_mysqld."),
 
1110
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1814
1111
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1815
1112
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1816
1113
   N_("Maximum time in seconds to wait for the port to become free. "
1820
1117
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1821
1118
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1822
1119
      "within specified directory"),
1823
 
   NULL, NULL, 0,
 
1120
   (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1824
1121
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
1122
  {"server-id", OPT_SERVER_ID,
1826
1123
   N_("Uniquely identifies the server instance in the community of "
1894
1191
   N_("Max packetlength to send/receive from to server."),
1895
1192
   (char**) &global_system_variables.max_allowed_packet,
1896
1193
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1897
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1194
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1898
1195
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
1899
1196
   N_("If there is more than this number of interrupted connections from a "
1900
1197
      "host this host will be blocked from further connections."),
1909
1206
   N_("Don't allow creation of heap tables bigger than this."),
1910
1207
   (char**) &global_system_variables.max_heap_table_size,
1911
1208
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1912
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
 
1209
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1913
1210
   MALLOC_OVERHEAD, 1024, 0},
1914
1211
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1915
1212
   N_("Joins that are probably going to read more than max_join_size records "
1966
1263
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
1967
1264
  {"plugin_dir", OPT_PLUGIN_DIR,
1968
1265
   N_("Directory for plugins."),
1969
 
   NULL, NULL, 0,
 
1266
   (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
1970
1267
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1971
1268
  {"plugin_add", OPT_PLUGIN_ADD,
1972
1269
   N_("Optional comma separated list of plugins to load at startup in addition "
1973
1270
      "to the default list of plugins. "
1974
1271
      "[for example: --plugin_add=crc32,logger_gearman]"),
1975
 
   NULL, NULL, 0,
 
1272
   (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
1976
1273
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1977
1274
  {"plugin_remove", OPT_PLUGIN_ADD,
1978
1275
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
1979
1276
      "removes a plugin from the list of plugins to be loaded. "
1980
1277
      "[for example: --plugin_remove=crc32,logger_gearman]"),
1981
 
   NULL, NULL, 0,
 
1278
   (char**) &opt_plugin_remove, (char**) &opt_plugin_remove, 0,
1982
1279
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1983
1280
  {"plugin_load", OPT_PLUGIN_LOAD,
1984
1281
   N_("Optional comma separated list of plugins to load at starup instead of "
1985
1282
      "the default plugin load list. "
1986
1283
      "[for example: --plugin_load=crc32,logger_gearman]"),
1987
 
   NULL, NULL, 0,
 
1284
   (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
1988
1285
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1989
1286
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1990
1287
   N_("The size of the buffer that is allocated when preloading indexes"),
2006
1303
   N_("Allocation block size for storing ranges during optimization"),
2007
1304
   (char**) &global_system_variables.range_alloc_block_size,
2008
1305
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
2009
 
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
 
1306
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
2010
1307
   0, 1024, 0},
2011
1308
  {"read_buffer_size", OPT_RECORD_BUFFER,
2012
1309
    N_("Each thread that does a sequential scan allocates a buffer of this "
2033
1330
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
2034
1331
   (char**) &global_system_variables.sortbuff_size,
2035
1332
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
2036
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
 
1333
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
2037
1334
   MALLOC_OVERHEAD, 1, 0},
2038
1335
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
2039
1336
   N_("The number of cached table definitions."),
2053
1350
   (char**) &my_thread_stack_size,
2054
1351
   (char**) &my_thread_stack_size, 0, GET_SIZE,
2055
1352
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
2056
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
 
1353
   UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
2057
1354
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
2058
1355
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2059
1356
      " automatically convert it to an on-disk MyISAM table."),
2060
1357
   (char**) &global_system_variables.tmp_table_size,
2061
1358
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2062
 
   REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
1359
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2063
1360
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2064
1361
};
2065
1362
 
2085
1382
         "This software comes with ABSOLUTELY NO WARRANTY. "
2086
1383
         "This is free software,\n"
2087
1384
         "and you are welcome to modify and redistribute it under the GPL "
2088
 
         "license\n\n"));
 
1385
         "license\n\n"
 
1386
         "Starts the Drizzle database server\n"));
2089
1387
 
2090
 
 
2091
1388
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
2092
 
 
2093
 
  po::options_description all_options("Drizzled Options");
2094
 
  all_options.add(config_options);
2095
 
  all_options.add(plugin_load_options);
2096
 
  all_options.add(long_options);
2097
 
  all_options.add(plugin_options);
2098
 
  cout << all_options << endl;
2099
 
 
 
1389
  {
 
1390
     internal::print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
1391
     puts("");
 
1392
 
 
1393
     /* Print out all the options including plugin supplied options */
 
1394
     my_print_help_inc_plugins(my_long_options, long_options);
 
1395
  }
2100
1396
}
2101
1397
 
 
1398
 
2102
1399
/**
2103
1400
  Initialize all Drizzle global variables to default values.
2104
1401
 
2118
1415
static void drizzle_init_variables(void)
2119
1416
{
2120
1417
  /* Things reset to zero */
 
1418
  drizzle_home[0]= pidfile_name[0]= 0;
2121
1419
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
1420
  opt_secure_file_priv= 0;
2122
1421
  cleanup_done= 0;
 
1422
  defaults_argc= 0;
 
1423
  defaults_argv= 0;
2123
1424
  dropping_tables= ha_open_options=0;
2124
1425
  test_flags.reset();
2125
1426
  wake_thread=0;
2136
1437
  character_set_filesystem= &my_charset_bin;
2137
1438
 
2138
1439
  /* Things with default values that are not zero */
 
1440
  drizzle_home_ptr= drizzle_home;
 
1441
  pidfile_name_ptr= pidfile_name;
 
1442
  language_ptr= language;
 
1443
  data_home= data_home_real;
2139
1444
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2140
1445
  refresh_version= 1L;  /* Increments on each reload */
2141
1446
  global_thread_id= 1UL;
2142
 
  session::Cache::singleton().getCache().clear();
 
1447
  getSessionList().clear();
 
1448
 
 
1449
  /* Set directory paths */
 
1450
  strncpy(language, LANGUAGE, sizeof(language)-1);
 
1451
  strncpy(data_home_real, get_relative_path(LOCALSTATEDIR),
 
1452
          sizeof(data_home_real)-1);
 
1453
  data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
1454
  data_home_buff[1]=0;
 
1455
  data_home_len= 2;
2143
1456
 
2144
1457
  /* Variables in libraries */
2145
1458
  default_character_set_name= "utf8";
2154
1467
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2155
1468
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2156
1469
  max_system_variables.max_join_size=   (uint64_t) HA_POS_ERROR;
2157
 
  max_system_variables.auto_increment_increment= UINT64_MAX;
2158
 
  max_system_variables.auto_increment_offset= UINT64_MAX;
2159
 
  max_system_variables.completion_type= 2;
2160
 
  max_system_variables.log_warnings= true;
2161
 
  max_system_variables.bulk_insert_buff_size= ULONG_MAX;
2162
 
  max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
2163
 
  max_system_variables.group_concat_max_len= ULONG_MAX;
2164
 
  max_system_variables.join_buff_size= ULONG_MAX;
2165
 
  max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
2166
 
  max_system_variables.max_error_count= 65535;
2167
 
  max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
2168
 
  max_system_variables.max_join_size= INT32_MAX;
2169
 
  max_system_variables.max_length_for_sort_data= 8192*1024L;
2170
 
  max_system_variables.max_seeks_for_key= ULONG_MAX;
2171
 
  max_system_variables.max_sort_length= 8192*1024L;
2172
 
  max_system_variables.min_examined_row_limit= ULONG_MAX;
2173
 
  max_system_variables.optimizer_prune_level= 1;
2174
 
  max_system_variables.optimizer_search_depth= MAX_TABLES+2;
2175
 
  max_system_variables.preload_buff_size= 1024*1024*1024L;
2176
 
  max_system_variables.query_alloc_block_size= UINT32_MAX;
2177
 
  max_system_variables.query_prealloc_size= UINT32_MAX;
2178
 
  max_system_variables.range_alloc_block_size= SIZE_MAX;
2179
 
  max_system_variables.read_buff_size= INT32_MAX;
2180
 
  max_system_variables.read_rnd_buff_size= UINT32_MAX;
2181
 
  max_system_variables.sortbuff_size= SIZE_MAX;
2182
 
  max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
2183
 
 
2184
1470
  opt_scheduler_default= (char*) "multi_thread";
2185
1471
 
2186
1472
  /* Variables that depends on compile options */
2190
1476
  have_symlink=SHOW_OPTION_YES;
2191
1477
#endif
2192
1478
 
 
1479
  const char *tmpenv;
 
1480
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
1481
    tmpenv = PREFIX;
 
1482
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
 
1483
  
2193
1484
  connection_count= 0;
2194
1485
}
2195
1486
 
2196
1487
 
2197
 
/**
2198
 
  @todo
2199
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2200
 
*/
2201
 
static void get_options()
 
1488
int drizzled_get_one_option(int optid, const struct option *opt,
 
1489
                             char *argument)
2202
1490
{
2203
 
 
2204
 
  fs::path &data_home_catalog= getDataHomeCatalog();
2205
 
  data_home_catalog= getDataHome();
2206
 
  data_home_catalog /= "local"; 
2207
 
 
2208
 
  if (vm.count("user"))
2209
 
  {
2210
 
    if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
2211
 
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2212
 
 
 
1491
  switch(optid) {
 
1492
  case 'a':
 
1493
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
 
1494
    break;
 
1495
  case 'b':
 
1496
    strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
 
1497
    break;
 
1498
  case 'C':
 
1499
    if (default_collation_name == compiled_default_collation_name)
 
1500
      default_collation_name= 0;
 
1501
    break;
 
1502
  case 'h':
 
1503
    strncpy(data_home_real,argument, sizeof(data_home_real)-1);
 
1504
    /* Correct pointer set by my_getopt (for embedded library) */
 
1505
    data_home= data_home_real;
 
1506
    data_home_len= strlen(data_home);
 
1507
    break;
 
1508
  case 'u':
 
1509
    if (!drizzled_user || !strcmp(drizzled_user, argument))
 
1510
      drizzled_user= argument;
2213
1511
    else
2214
1512
      errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
2215
 
                                       "set to '%s' earlier on the command line\n"),
2216
 
                    vm["user"].as<string>().c_str(), drizzled_user);
2217
 
  }
2218
 
 
2219
 
  if (vm.count("version"))
2220
 
  {
 
1513
                          "set to '%s' earlier on the command line\n"),
 
1514
                        argument, drizzled_user);
 
1515
    break;
 
1516
  case 'L':
 
1517
    strncpy(language, argument, sizeof(language)-1);
 
1518
    break;
 
1519
  case 'V':
2221
1520
    print_version();
2222
1521
    exit(0);
2223
 
  }
2224
 
 
2225
 
  if (vm.count("sort-heap-threshold"))
2226
 
  {
2227
 
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2228
 
      (vm["sort-heap-threshold"].as<uint64_t>() < 
2229
 
      global_system_variables.sortbuff_size))
2230
 
    {
2231
 
      cout << N_("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2232
 
      exit(-1);
2233
 
    }
2234
 
 
2235
 
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2236
 
  }
2237
 
 
2238
 
  if (vm.count("join-heap-threshold"))
2239
 
  {
2240
 
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2241
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2242
 
      global_system_variables.join_buff_size))
2243
 
    {
2244
 
      cout << N_("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2245
 
      exit(-1);
2246
 
    }
2247
 
 
2248
 
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2249
 
  }
2250
 
 
2251
 
  if (vm.count("read-rnd-threshold"))
2252
 
  {
2253
 
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2254
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2255
 
      global_system_variables.read_rnd_buff_size))
2256
 
    {
2257
 
      cout << N_("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2258
 
      exit(-1);
2259
 
    }
2260
 
 
2261
 
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2262
 
  }
2263
 
 
2264
 
  if (vm.count("read-buffer-threshold"))
2265
 
  {
2266
 
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2267
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2268
 
      global_system_variables.read_buff_size))
2269
 
    {
2270
 
      cout << N_("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2271
 
      exit(-1);
2272
 
    }
2273
 
 
2274
 
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2275
 
  }
2276
 
 
2277
 
  if (vm.count("exit-info"))
2278
 
  {
2279
 
    if (vm["exit-info"].as<long>())
2280
 
    {
2281
 
      test_flags.set((uint32_t) vm["exit-info"].as<long>());
2282
 
    }
2283
 
  }
2284
 
 
2285
 
  if (vm.count("want-core"))
2286
 
  {
 
1522
  case 'W':
 
1523
    if (!argument)
 
1524
      global_system_variables.log_warnings++;
 
1525
    else if (argument == disabled_my_option)
 
1526
      global_system_variables.log_warnings= 0L;
 
1527
    else
 
1528
      global_system_variables.log_warnings= atoi(argument);
 
1529
    break;
 
1530
  case 'T':
 
1531
    if (argument)
 
1532
    {
 
1533
      test_flags.set((uint32_t) atoi(argument));
 
1534
    }
 
1535
    break;
 
1536
  case (int) OPT_WANT_CORE:
2287
1537
    test_flags.set(TEST_CORE_ON_SIGNAL);
2288
 
  }
2289
 
 
2290
 
  if (vm.count("skip-stack-trace"))
2291
 
  {
 
1538
    break;
 
1539
  case (int) OPT_SKIP_STACK_TRACE:
2292
1540
    test_flags.set(TEST_NO_STACKTRACE);
2293
 
  }
2294
 
 
2295
 
  if (vm.count("skip-symlinks"))
2296
 
  {
 
1541
    break;
 
1542
  case (int) OPT_SKIP_SYMLINKS:
2297
1543
    internal::my_use_symdir=0;
2298
 
  }
2299
 
 
2300
 
  if (vm.count("transaction-isolation"))
2301
 
  {
2302
 
    int type;
2303
 
    type= find_type_or_exit((char *)vm["transaction-isolation"].as<string>().c_str(), &tx_isolation_typelib, "transaction-isolation");
2304
 
    global_system_variables.tx_isolation= (type-1);
2305
 
  }
2306
 
 
2307
 
  /* @TODO Make this all strings */
2308
 
  if (vm.count("default-storage-engine"))
2309
 
  {
2310
 
    default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
2311
 
  }
 
1544
    break;
 
1545
  case (int) OPT_BIND_ADDRESS:
 
1546
    {
 
1547
      struct addrinfo *res_lst, hints;
 
1548
 
 
1549
      memset(&hints, 0, sizeof(struct addrinfo));
 
1550
      hints.ai_socktype= SOCK_STREAM;
 
1551
      hints.ai_protocol= IPPROTO_TCP;
 
1552
 
 
1553
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
 
1554
      {
 
1555
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
 
1556
        return EXIT_ARGUMENT_INVALID;
 
1557
      }
 
1558
 
 
1559
      if (res_lst->ai_next)
 
1560
      {
 
1561
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
 
1562
                          "multiple interfaces!"));
 
1563
        return EXIT_ARGUMENT_INVALID;
 
1564
      }
 
1565
      freeaddrinfo(res_lst);
 
1566
    }
 
1567
    break;
 
1568
  case (int) OPT_PID_FILE:
 
1569
    strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
 
1570
    break;
 
1571
  case OPT_SERVER_ID:
 
1572
    break;
 
1573
  case OPT_TX_ISOLATION:
 
1574
    {
 
1575
      int type;
 
1576
      type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
 
1577
      global_system_variables.tx_isolation= (type-1);
 
1578
      break;
 
1579
    }
 
1580
  case OPT_TC_HEURISTIC_RECOVER:
 
1581
    tc_heuristic_recover= find_type_or_exit(argument,
 
1582
                                            &tc_heuristic_recover_typelib,
 
1583
                                            opt->name);
 
1584
    break;
 
1585
  }
 
1586
 
 
1587
  return 0;
 
1588
}
 
1589
 
 
1590
static void option_error_reporter(enum loglevel level, const char *format, ...)
 
1591
{
 
1592
  va_list args;
 
1593
  va_start(args, format);
 
1594
 
 
1595
  /* Don't print warnings for --loose options during bootstrap */
 
1596
  if (level == ERROR_LEVEL || global_system_variables.log_warnings)
 
1597
  {
 
1598
    plugin::ErrorMessage::vprintf(NULL, ERROR_LEVEL, format, args);
 
1599
  }
 
1600
  va_end(args);
 
1601
}
 
1602
 
 
1603
 
 
1604
/**
 
1605
  @todo
 
1606
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
 
1607
*/
 
1608
static void get_options(int *argc,char **argv)
 
1609
{
 
1610
  int ho_error;
 
1611
 
 
1612
  my_getopt_error_reporter= option_error_reporter;
 
1613
 
 
1614
  string progname(argv[0]);
2312
1615
 
2313
1616
  /* Skip unknown options so that they may be processed later by plugins */
2314
1617
  my_getopt_skip_unknown= true;
2315
1618
 
 
1619
  if ((ho_error= handle_options(argc, &argv, my_long_options,
 
1620
                                drizzled_get_one_option)))
 
1621
    exit(ho_error);
 
1622
  (*argc)++; /* add back one for the progname handle_options removes */
 
1623
             /* no need to do this for argv as we are discarding it. */
2316
1624
 
2317
1625
#if defined(HAVE_BROKEN_REALPATH)
2318
1626
  internal::my_use_symdir=0;
2335
1643
 
2336
1644
  if (drizzled_chroot)
2337
1645
    set_root(drizzled_chroot);
 
1646
  fix_paths(progname);
2338
1647
 
2339
1648
  /*
2340
1649
    Set some global variables from the global_system_variables
2344
1653
}
2345
1654
 
2346
1655
 
2347
 
static void fix_paths()
2348
 
{
2349
 
  fs::path pid_file_path(pid_file);
2350
 
  if (pid_file_path.root_path().string() == "")
2351
 
  {
2352
 
    pid_file_path= getDataHome();
2353
 
    pid_file_path /= pid_file;
2354
 
  }
2355
 
  pid_file= fs::system_complete(pid_file_path);
2356
 
 
2357
 
  if (not opt_help)
2358
 
  {
2359
 
    const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
 
1656
static const char *get_relative_path(const char *path)
 
1657
{
 
1658
  if (internal::test_if_hard_path(path) &&
 
1659
      (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
 
1660
      strcmp(PREFIX,FN_ROOTDIR))
 
1661
  {
 
1662
    if (strlen(PREFIX) < strlen(path))
 
1663
      path+=(size_t) strlen(PREFIX);
 
1664
    while (*path == FN_LIBCHAR)
 
1665
      path++;
 
1666
  }
 
1667
  return path;
 
1668
}
 
1669
 
 
1670
 
 
1671
static void fix_paths(string &progname)
 
1672
{
 
1673
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
 
1674
  internal::convert_dirname(drizzle_home,drizzle_home,NULL);
 
1675
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
 
1676
#if defined(HAVE_BROKEN_REALPATH)
 
1677
   internal::my_load_path(drizzle_home, drizzle_home, NULL);
 
1678
#else
 
1679
  if (!realpath(drizzle_home,rp_buff))
 
1680
    internal::my_load_path(rp_buff, drizzle_home, NULL);
 
1681
  rp_buff[FN_REFLEN-1]= '\0';
 
1682
  strcpy(drizzle_home,rp_buff);
 
1683
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
 
1684
  pos= strchr(drizzle_home, '\0');
 
1685
#endif
 
1686
  if (pos[-1] != FN_LIBCHAR)
 
1687
  {
 
1688
    pos[0]= FN_LIBCHAR;
 
1689
    pos[1]= 0;
 
1690
  }
 
1691
  internal::convert_dirname(data_home_real,data_home_real,NULL);
 
1692
  (void) internal::fn_format(buff, data_home_real, "", "",
 
1693
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
1694
  (void) internal::unpack_dirname(data_home_real_unpacked, buff);
 
1695
  internal::convert_dirname(language,language,NULL);
 
1696
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
1697
  (void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
 
1698
  (void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
 
1699
 
 
1700
  if (opt_plugin_dir_ptr == NULL)
 
1701
  {
 
1702
    /* No plugin dir has been specified. Figure out where the plugins are */
 
1703
    if (progname[0] != FN_LIBCHAR)
 
1704
    {
 
1705
      /* We have a relative path and need to find the absolute */
 
1706
      char working_dir[FN_REFLEN];
 
1707
      char *working_dir_ptr= working_dir;
 
1708
      working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
 
1709
      string new_path(working_dir);
 
1710
      if (*(new_path.end()-1) != '/')
 
1711
        new_path.push_back('/');
 
1712
      if (progname[0] == '.' && progname[1] == '/')
 
1713
        new_path.append(progname.substr(2));
 
1714
      else
 
1715
        new_path.append(progname);
 
1716
      progname.swap(new_path);
 
1717
    }
 
1718
 
 
1719
    /* Now, trim off the exe name */
 
1720
    string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
 
1721
    if (progdir.rfind(".libs/") != string::npos)
 
1722
    {
 
1723
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
 
1724
    }
 
1725
    string testlofile(progdir);
 
1726
    testlofile.append("drizzled.lo");
 
1727
    string testofile(progdir);
 
1728
    testofile.append("drizzled.o");
 
1729
    struct stat testfile_stat;
 
1730
    if (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat))
 
1731
    {
 
1732
      /* neither drizzled.lo or drizzled.o exist - we are not in a source dir.
 
1733
       * Go on as usual
 
1734
       */
 
1735
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
 
1736
                                          drizzle_home);
 
1737
    }
 
1738
    else
 
1739
    {
 
1740
      /* We are in a source dir! Plugin dir is ../plugin/.libs */
 
1741
      size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
 
1742
      string source_plugindir(progdir.substr(0,last_libchar_pos));
 
1743
      source_plugindir.append("plugin/.libs");
 
1744
      (void) internal::my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
 
1745
    }
 
1746
  }
 
1747
  else
 
1748
  {
 
1749
    (void) internal::my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
 
1750
  }
 
1751
  opt_plugin_dir_ptr= opt_plugin_dir;
 
1752
 
 
1753
  const char *sharedir= get_relative_path(PKGDATADIR);
 
1754
  if (internal::test_if_hard_path(sharedir))
 
1755
    strncpy(buff,sharedir,sizeof(buff)-1);
 
1756
  else
 
1757
  {
 
1758
    strcpy(buff, drizzle_home);
 
1759
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
 
1760
  }
 
1761
  internal::convert_dirname(buff,buff,NULL);
 
1762
  (void) internal::my_load_path(language,language,buff);
 
1763
 
 
1764
  if (not opt_help and not opt_help_extended)
 
1765
  {
 
1766
    char *tmp_string;
2360
1767
    struct stat buf;
2361
 
    drizzle_tmpdir.clear();
2362
 
 
2363
 
    if (vm.count("tmpdir"))
 
1768
 
 
1769
    tmp_string= getenv("TMPDIR");
 
1770
 
 
1771
    if (opt_drizzle_tmpdir)
2364
1772
    {
2365
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
 
1773
      drizzle_tmpdir.append(opt_drizzle_tmpdir);
2366
1774
    }
2367
1775
    else if (tmp_string == NULL)
2368
1776
    {
2369
 
      drizzle_tmpdir.append(getDataHome().file_string());
2370
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2371
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
 
1777
      drizzle_tmpdir.append(data_home);
2372
1778
    }
2373
1779
    else
2374
1780
    {
2375
1781
      drizzle_tmpdir.append(tmp_string);
2376
1782
    }
2377
1783
 
2378
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2379
1784
    assert(drizzle_tmpdir.size());
 
1785
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
 
1786
    {
 
1787
      perror(drizzle_tmpdir.c_str());
 
1788
      exit(1);
 
1789
    }
 
1790
 
 
1791
    drizzle_tmpdir.append(FN_ROOTDIR);
 
1792
    drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2380
1793
 
2381
1794
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2382
1795
    {
2394
1807
    }
2395
1808
  }
2396
1809
 
 
1810
  /*
 
1811
    Convert the secure-file-priv option to system format, allowing
 
1812
    a quick strcmp to check if read or write is in an allowed dir
 
1813
   */
 
1814
  if (opt_secure_file_priv)
 
1815
  {
 
1816
    internal::convert_dirname(buff, opt_secure_file_priv, NULL);
 
1817
    free(opt_secure_file_priv);
 
1818
    opt_secure_file_priv= strdup(buff);
 
1819
    if (opt_secure_file_priv == NULL)
 
1820
      exit(1);
 
1821
  }
2397
1822
}
2398
1823
 
2399
1824
} /* namespace drizzled */