~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2010-07-15 23:18:11 UTC
  • mto: This revision was merged to the branch mainline in revision 1661.
  • Revision ID: brian@gaz-20100715231811-c5erivy1nvwf6bii
Merge in move identifier work.

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>
28
27
#include <netinet/in.h>
29
28
#include <signal.h>
30
29
#include <limits.h>
31
 
#include <stdexcept>
32
30
 
33
31
#include <boost/program_options.hpp>
34
 
#include "drizzled/program_options/config_file.h"
35
 
#include <boost/thread/recursive_mutex.hpp>
36
 
#include <boost/thread/mutex.hpp>
37
 
#include <boost/thread/shared_mutex.hpp>
38
 
#include <boost/thread/condition_variable.hpp>
39
 
#include <boost/filesystem.hpp>
40
32
 
41
33
#include "drizzled/internal/my_sys.h"
42
34
#include "drizzled/internal/my_bit.h"
60
52
#include "drizzled/plugin/monitored_in_transaction.h"
61
53
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
62
54
#include "drizzled/probes.h"
63
 
#include "drizzled/session/cache.h"
 
55
#include "drizzled/session_list.h"
64
56
#include "drizzled/charset.h"
65
57
#include "plugin/myisam/myisam.h"
66
58
#include "drizzled/drizzled.h"
67
59
#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
60
 
77
61
#include <google/protobuf/stubs/common.h>
78
62
 
130
114
#endif
131
115
 
132
116
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
133
 
#include "drizzled/constrained_value.h"
134
117
 
135
118
#include <drizzled/gettext.h>
136
119
 
137
120
 
138
 
#ifdef HAVE_VALGRIND
 
121
#ifdef HAVE_purify
139
122
#define IF_PURIFY(A,B) (A)
140
123
#else
141
124
#define IF_PURIFY(A,B) (B)
142
125
#endif
143
126
 
144
127
#define MAX_MEM_TABLE_SIZE SIZE_MAX
145
 
#include <iostream>
146
 
#include <fstream>
147
 
 
148
128
 
149
129
using namespace std;
150
 
namespace fs=boost::filesystem;
151
130
namespace po=boost::program_options;
152
 
namespace dpo=drizzled::program_options;
153
131
 
154
132
 
155
133
namespace drizzled
189
167
extern "C" int gethostname(char *name, int namelen);
190
168
#endif
191
169
 
 
170
/* Constants */
 
171
static const char *tc_heuristic_recover_names[]=
 
172
{
 
173
  "COMMIT", "ROLLBACK", NULL
 
174
};
 
175
static TYPELIB tc_heuristic_recover_typelib=
 
176
{
 
177
  array_elements(tc_heuristic_recover_names)-1,"",
 
178
  tc_heuristic_recover_names, NULL
 
179
};
 
180
 
192
181
const char *first_keyword= "first";
193
182
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
194
 
 
195
183
#define GET_HA_ROWS GET_ULL
196
184
 
197
185
const char *tx_isolation_names[] =
205
193
  Used with --help for detailed option
206
194
*/
207
195
bool opt_help= false;
 
196
bool opt_help_extended= false;
208
197
 
209
198
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
210
199
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
215
204
 
216
205
/* static variables */
217
206
 
218
 
static bool opt_debugging= false;
 
207
static bool opt_debugging= 0;
219
208
static uint32_t wake_thread;
220
209
static char *drizzled_chroot;
 
210
static char *language_ptr;
221
211
static const char *default_character_set_name;
222
212
static const char *character_set_filesystem_name;
223
213
static char *lc_time_names_name;
233
223
bool volatile abort_loop;
234
224
bool volatile shutdown_in_progress;
235
225
char *opt_scheduler_default;
236
 
const char *opt_scheduler= NULL;
 
226
char *opt_scheduler= NULL;
237
227
 
238
 
size_t my_thread_stack_size= 0;
 
228
size_t my_thread_stack_size= 65536;
239
229
 
240
230
/*
241
231
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
243
233
plugin::StorageEngine *heap_engine;
244
234
plugin::StorageEngine *myisam_engine;
245
235
 
 
236
char* opt_secure_file_priv= 0;
 
237
 
246
238
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
247
239
 
248
240
uint32_t drizzled_bind_timeout;
250
242
uint32_t dropping_tables, ha_open_options;
251
243
uint32_t tc_heuristic_recover= 0;
252
244
uint64_t session_startup_options;
253
 
back_log_constraints back_log(50);
 
245
uint32_t back_log;
254
246
uint32_t server_id;
255
247
uint64_t table_cache_size;
256
248
size_t table_def_size;
297
289
time_t server_start_time;
298
290
time_t flush_status_time;
299
291
 
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];
 
292
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
308
293
char *default_tz_name;
309
294
char glob_hostname[FN_REFLEN];
310
 
 
311
 
char *opt_tc_log_file;
 
295
char data_home_real[FN_REFLEN],
 
296
     language[FN_REFLEN], 
 
297
     *opt_tc_log_file;
 
298
char data_home_real_unpacked[FN_REFLEN];
312
299
const key_map key_map_empty(0);
313
300
key_map key_map_full(0);                        // Will be initialized later
314
301
 
 
302
uint32_t data_home_len;
 
303
char data_home_buff[2], *data_home=data_home_real;
315
304
std::string drizzle_tmpdir;
316
305
char *opt_drizzle_tmpdir= NULL;
317
306
 
326
315
 
327
316
FILE *stderror_file=0;
328
317
 
329
 
struct drizzle_system_variables global_system_variables;
330
 
struct drizzle_system_variables max_system_variables;
 
318
struct system_variables global_system_variables;
 
319
struct system_variables max_system_variables;
331
320
struct global_counters current_global_counters;
332
321
 
333
322
const CHARSET_INFO *system_charset_info, *files_charset_info ;
339
328
SHOW_COMP_OPTION have_symlink;
340
329
 
341
330
/* Thread specific variables */
342
 
boost::mutex LOCK_global_system_variables;
343
 
 
344
 
boost::condition_variable_any COND_refresh;
345
 
boost::condition_variable COND_thread_count;
 
331
 
 
332
pthread_key_t THR_Mem_root;
 
333
pthread_key_t THR_Session;
 
334
pthread_mutex_t LOCK_create_db;
 
335
pthread_mutex_t LOCK_open;
 
336
pthread_mutex_t LOCK_thread_count;
 
337
pthread_mutex_t LOCK_status;
 
338
pthread_mutex_t LOCK_global_read_lock;
 
339
pthread_mutex_t LOCK_global_system_variables;
 
340
 
 
341
pthread_rwlock_t        LOCK_system_variables_hash;
 
342
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
346
343
pthread_t signal_thread;
347
 
boost::condition_variable COND_server_end;
 
344
pthread_cond_t  COND_server_end;
348
345
 
349
346
/* Static variables */
350
347
 
351
348
int cleanup_done;
 
349
static char *drizzle_home_ptr, *pidfile_name_ptr;
 
350
static int defaults_argc;
 
351
static char **defaults_argv;
352
352
 
353
353
passwd *user_info;
354
354
 
355
355
atomic<uint32_t> connection_count;
356
356
 
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
357
/** 
363
358
  Refresh value. We use to test this to find out if a refresh even has happened recently.
364
359
*/
368
363
bool drizzle_rm_tmp_tables();
369
364
 
370
365
static void drizzle_init_variables(void);
371
 
static void get_options();
372
 
static void fix_paths();
 
366
static void get_options(int *argc,char **argv);
 
367
int drizzled_get_one_option(int, const struct option *, char *);
 
368
static const char *get_relative_path(const char *path);
 
369
static void fix_paths(string &progname);
373
370
 
374
371
static void usage(void);
375
372
void close_connections(void);
376
373
 
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;
 
374
po::options_description long_options("Allowed Options");
387
375
po::variables_map vm;
388
376
 
389
 
fs::path data_home(LOCALSTATEDIR);
390
 
fs::path full_data_home(LOCALSTATEDIR);
391
 
 
392
377
po::variables_map &getVariablesMap()
393
378
{
394
379
  return vm;
395
380
}
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
381
 
409
382
/****************************************************************************
410
383
** Code to end drizzled
416
389
  plugin::Listen::shutdown();
417
390
 
418
391
  /* kill connection thread */
 
392
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
393
 
 
394
  while (select_thread_in_use)
419
395
  {
420
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
396
    struct timespec abstime;
 
397
    int error;
421
398
 
422
 
    while (select_thread_in_use)
 
399
    set_timespec(abstime, 2);
 
400
    for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
423
401
    {
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
 
      }
 
402
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
 
403
      if (error != EINTR)
 
404
        break;
434
405
    }
435
406
  }
 
407
  (void) pthread_mutex_unlock(&LOCK_thread_count);
436
408
 
437
409
 
438
410
  /*
441
413
    statements and inform their clients that the server is about to die.
442
414
  */
443
415
 
 
416
  Session *tmp;
 
417
 
 
418
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
419
 
 
420
  for( SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
444
421
  {
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 )
 
422
    tmp= *it;
 
423
    tmp->killed= Session::KILL_CONNECTION;
 
424
    tmp->scheduler->killSession(tmp);
 
425
    DRIZZLE_CONNECTION_DONE(tmp->thread_id);
 
426
    if (tmp->mysys_var)
449
427
    {
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();
 
428
      tmp->mysys_var->abort=1;
 
429
      pthread_mutex_lock(&tmp->mysys_var->mutex);
 
430
      if (tmp->mysys_var->current_cond)
 
431
      {
 
432
        pthread_mutex_lock(tmp->mysys_var->current_mutex);
 
433
        pthread_cond_broadcast(tmp->mysys_var->current_cond);
 
434
        pthread_mutex_unlock(tmp->mysys_var->current_mutex);
 
435
      }
 
436
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
457
437
    }
458
438
  }
 
439
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
459
440
 
460
 
  if (session::Cache::singleton().count())
 
441
  if (connection_count)
461
442
    sleep(2);                                   // Give threads time to die
462
443
 
463
444
  /*
467
448
  */
468
449
  for (;;)
469
450
  {
470
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
471
 
    session::Cache::list list= session::Cache::singleton().getCache();
472
 
 
473
 
    if (list.empty())
 
451
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
452
    if (getSessionList().empty())
474
453
    {
 
454
      (void) pthread_mutex_unlock(&LOCK_thread_count);
475
455
      break;
476
456
    }
 
457
    tmp= getSessionList().front();
477
458
    /* Close before unlock, avoiding crash. See LP bug#436685 */
478
 
    list.front()->client->close();
 
459
    tmp->client->close();
 
460
    (void) pthread_mutex_unlock(&LOCK_thread_count);
479
461
  }
480
462
}
481
463
 
 
464
/**
 
465
  cleanup all memory and end program nicely.
 
466
 
 
467
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
468
    by the main thread. To get Drizzle to shut down nicely in this case
 
469
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
470
 
 
471
  @note
 
472
    This function never returns.
 
473
*/
 
474
void unireg_end(void)
 
475
{
 
476
  clean_up(1);
 
477
  internal::my_thread_end();
 
478
#if defined(SIGNALS_DONT_BREAK_READ)
 
479
  exit(0);
 
480
#else
 
481
  pthread_exit(0);                              // Exit is in main thread
 
482
#endif
 
483
}
 
484
 
482
485
 
483
486
void unireg_abort(int exit_code)
484
487
{
485
488
 
486
489
  if (exit_code)
487
490
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
488
 
  else if (opt_help)
 
491
  else if (opt_help || opt_help_extended)
489
492
    usage();
490
493
  clean_up(!opt_help && (exit_code));
 
494
  clean_up_mutexes();
491
495
  internal::my_end();
492
496
  exit(exit_code);
493
497
}
499
503
    return;
500
504
 
501
505
  table_cache_free();
 
506
  TableShare::cacheStop();
 
507
  set_var_free();
502
508
  free_charsets();
503
509
  module::Registry &modules= module::Registry::singleton();
504
510
  modules.shutdownModules();
505
511
  xid_cache_free();
 
512
  if (defaults_argv)
 
513
    internal::free_defaults(defaults_argv);
 
514
  if (opt_secure_file_priv)
 
515
    free(opt_secure_file_priv);
506
516
 
507
517
  deinit_temporal_formats();
508
518
 
510
520
  google::protobuf::ShutdownProtobufLibrary();
511
521
#endif
512
522
 
513
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
 
523
  (void) unlink(pidfile_name);  // This may not always exist
514
524
 
515
525
  if (print_message && server_start_time)
516
526
    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
 
  }
 
527
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
528
  ready_to_exit=1;
 
529
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
530
  (void) pthread_cond_broadcast(&COND_server_end);
 
531
  (void) pthread_mutex_unlock(&LOCK_thread_count);
524
532
 
525
533
  /*
526
534
    The following lines may never be executed as the main thread may have
529
537
} /* clean_up */
530
538
 
531
539
 
 
540
void clean_up_mutexes()
 
541
{
 
542
  (void) pthread_mutex_destroy(&LOCK_create_db);
 
543
  (void) pthread_mutex_destroy(&LOCK_open);
 
544
  (void) pthread_mutex_destroy(&LOCK_thread_count);
 
545
  (void) pthread_mutex_destroy(&LOCK_status);
 
546
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
 
547
  (void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
 
548
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
 
549
  (void) pthread_cond_destroy(&COND_thread_count);
 
550
  (void) pthread_cond_destroy(&COND_server_end);
 
551
  (void) pthread_cond_destroy(&COND_refresh);
 
552
  (void) pthread_cond_destroy(&COND_global_read_lock);
 
553
}
 
554
 
 
555
 
532
556
/* Change to run as another user if started with --user */
533
557
 
534
558
passwd *check_user(const char *user)
550
574
    }
551
575
    return NULL;
552
576
  }
553
 
  if (not user)
 
577
  if (!user)
554
578
  {
555
579
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
556
580
                      "the manual to find out how to run drizzled as root!\n"));
594
618
void set_user(const char *user, passwd *user_info_arg)
595
619
{
596
620
  assert(user_info_arg != 0);
 
621
  /*
 
622
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
 
623
    is configured to use LDAP and the server is statically linked.  We set
 
624
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
 
625
    output a specific message to help the user resolve this problem.
 
626
  */
 
627
  calling_initgroups= true;
597
628
  initgroups((char*) user, user_info_arg->pw_gid);
 
629
  calling_initgroups= false;
598
630
  if (setgid(user_info_arg->pw_gid) == -1)
599
631
  {
600
 
    sql_perror(N_("Set process group ID failed"));
 
632
    sql_perror("setgid");
601
633
    unireg_abort(1);
602
634
  }
603
635
  if (setuid(user_info_arg->pw_uid) == -1)
604
636
  {
605
 
    sql_perror(N_("Set process user ID failed"));
 
637
    sql_perror("setuid");
606
638
    unireg_abort(1);
607
639
  }
608
640
}
614
646
{
615
647
  if ((chroot(path) == -1) || !chdir("/"))
616
648
  {
617
 
    sql_perror(N_("Process chroot failed"));
 
649
    sql_perror("chroot");
618
650
    unireg_abort(1);
619
651
  }
620
652
}
626
658
  SYNOPSIS
627
659
    Session::unlink()
628
660
    session              Thread handler
 
661
 
 
662
  NOTES
 
663
    LOCK_thread_count is locked and left locked
629
664
*/
630
665
 
631
 
void drizzled::Session::unlink(Session::shared_ptr &session)
 
666
void Session::unlink(Session *session)
632
667
{
633
668
  connection_count.decrement();
634
669
 
635
670
  session->cleanup();
636
671
 
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);
 
672
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
673
  pthread_mutex_lock(&session->LOCK_delete);
 
674
 
 
675
  getSessionList().erase(remove(getSessionList().begin(),
 
676
                         getSessionList().end(),
 
677
                         session));
 
678
 
 
679
  delete session;
 
680
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
681
 
 
682
  return;
644
683
}
645
684
 
646
685
 
659
698
  DRIZZLE_CONFIG_NAME, "server", 0, 0
660
699
};
661
700
 
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)
 
701
int init_common_variables(const char *conf_file_name, int argc,
 
702
                          char **argv, const char **groups)
1105
703
{
1106
704
  time_t curr_time;
1107
705
  umask(((~internal::my_umask) & 0666));
1115
713
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1116
714
  server_start_time= flush_status_time= curr_time;
1117
715
 
 
716
  if (init_thread_environment())
 
717
    return 1;
1118
718
  drizzle_init_variables();
1119
719
 
1120
 
  find_plugin_dir(argv[0]);
1121
720
  {
1122
721
    struct tm tm_tmp;
1123
722
    localtime_r(&server_start_time,&tm_tmp);
1138
737
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1139
738
    errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1140
739
                  glob_hostname);
1141
 
    pid_file= "drizzle";
 
740
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1142
741
  }
1143
742
  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();
 
743
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
744
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
 
745
 
 
746
  internal::load_defaults(conf_file_name, groups, &argc, &argv);
 
747
  defaults_argv=argv;
 
748
  defaults_argc=argc;
 
749
  get_options(&defaults_argc, defaults_argv);
1510
750
 
1511
751
  current_pid= getpid();                /* Save for later ref */
1512
752
  init_time();                          /* Init time-functions (read zone) */
1513
753
 
1514
754
  if (item_create_init())
1515
755
    return 1;
1516
 
  if (sys_var_init())
 
756
  if (set_var_init())
1517
757
    return 1;
1518
758
  /* Creates static regex matching for temporal values */
1519
759
  if (! init_temporal_formats())
1522
762
  if (!(default_charset_info=
1523
763
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1524
764
  {
1525
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error getting default charset"));
1526
765
    return 1;                           // Eof of the list
1527
766
  }
1528
767
 
1529
 
  if (vm.count("scheduler"))
1530
 
    opt_scheduler= vm["scheduler"].as<string>().c_str();
1531
 
 
1532
768
  if (default_collation_name)
1533
769
  {
1534
770
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1551
787
 
1552
788
  if (not (character_set_filesystem=
1553
789
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1554
 
  {
1555
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error setting collation"));
1556
790
    return 1;
1557
 
  }
1558
791
  global_system_variables.character_set_filesystem= character_set_filesystem;
1559
792
 
1560
793
  if (!(my_default_lc_time_names=
1572
805
}
1573
806
 
1574
807
 
 
808
int init_thread_environment()
 
809
{
 
810
   pthread_mutexattr_t attr; 
 
811
   pthread_mutexattr_init(&attr);
 
812
 
 
813
  (void) pthread_mutex_init(&LOCK_create_db, NULL);
 
814
  (void) pthread_mutex_init(&LOCK_open, NULL);
 
815
 
 
816
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 
 
817
  (void) pthread_mutex_init(&LOCK_thread_count, &attr);
 
818
  (void) pthread_mutex_init(&LOCK_global_system_variables, &attr);
 
819
 
 
820
  (void) pthread_mutex_init(&LOCK_status, MY_MUTEX_INIT_FAST);
 
821
  (void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
 
822
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
 
823
  (void) pthread_cond_init(&COND_thread_count,NULL);
 
824
  (void) pthread_cond_init(&COND_server_end,NULL);
 
825
  (void) pthread_cond_init(&COND_refresh,NULL);
 
826
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
 
827
 
 
828
  pthread_mutexattr_destroy(&attr);
 
829
 
 
830
  if (pthread_key_create(&THR_Session,NULL) ||
 
831
      pthread_key_create(&THR_Mem_root,NULL))
 
832
  {
 
833
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
 
834
    return 1;
 
835
  }
 
836
  return 0;
 
837
}
 
838
 
 
839
 
1575
840
int init_server_components(module::Registry &plugins)
1576
841
{
1577
842
  /*
1579
844
    all things are initialized so that unireg_abort() doesn't fail
1580
845
  */
1581
846
  if (table_cache_init())
1582
 
  {
1583
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not initialize table cache\n"));
1584
847
    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);
 
848
  TableShare::cacheStart();
1591
849
 
1592
850
  setup_fpu();
 
851
  init_thr_lock();
1593
852
 
1594
853
  /* Setup logs */
1595
854
 
1596
855
  if (xid_cache_init())
1597
856
  {
1598
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("XA cache initialization failed: Out of memory\n"));
 
857
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1599
858
    unireg_abort(1);
1600
859
  }
1601
860
 
1602
861
  /* Allow storage engine to give real error messages */
1603
862
  ha_init_errors();
1604
863
 
1605
 
 
1606
 
  if (opt_help)
 
864
  if (plugin_init(plugins, &defaults_argc, defaults_argv,
 
865
                  ((opt_help) ? true : false), long_options))
 
866
  {
 
867
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
 
868
    unireg_abort(1);
 
869
  }
 
870
 
 
871
 
 
872
  if (opt_help || opt_help_extended)
1607
873
    unireg_abort(0);
1608
874
 
1609
 
  if (plugin_finalize(plugins))
 
875
  po::parsed_options parsed= po::command_line_parser(defaults_argc,
 
876
                                                     defaults_argv).
 
877
    options(long_options).allow_unregistered().run();
 
878
 
 
879
  vector<string> unknown_options=
 
880
    po::collect_unrecognized(parsed.options, po::include_positional);
 
881
 
 
882
  /* we do want to exit if there are any other unknown options */
 
883
  /** @TODO: We should perhaps remove allowed_unregistered() and catch the
 
884
    exception here */
 
885
  if (unknown_options.size() > 0)
1610
886
  {
1611
 
    unireg_abort(1);
 
887
     fprintf(stderr,
 
888
            _("%s: Too many arguments (first extra is '%s').\n"
 
889
              "Use --verbose --help to get a list of available options\n"),
 
890
            internal::my_progname, unknown_options[0].c_str());
 
891
      unireg_abort(1);
1612
892
  }
1613
893
 
 
894
  po::store(parsed, vm);
 
895
  po::notify(vm);
 
896
 
1614
897
  string scheduler_name;
1615
898
  if (opt_scheduler)
1616
899
  {
1649
932
    engine= plugin::StorageEngine::findByName(name);
1650
933
    if (engine == NULL)
1651
934
    {
1652
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s\n"),
 
935
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s"),
1653
936
                    default_storage_engine_str);
1654
937
      unireg_abort(1);
1655
938
    }
1656
939
    global_system_variables.storage_engine= engine;
1657
940
  }
1658
941
 
1659
 
  if (plugin::XaResourceManager::recoverAllXids())
 
942
  if (plugin::XaResourceManager::recoverAllXids(0))
1660
943
  {
1661
 
    /* This function alredy generates error messages */
1662
944
    unireg_abort(1);
1663
945
  }
1664
946
 
1689
971
  OPT_LOCAL_INFILE,
1690
972
  OPT_BACK_LOG,
1691
973
  OPT_JOIN_BUFF_SIZE,
 
974
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
 
975
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1692
976
  OPT_MAX_ALLOWED_PACKET,
1693
977
  OPT_MAX_CONNECT_ERRORS,
1694
978
  OPT_MAX_HEP_TABLE_SIZE,
1733
1017
  OPT_PLUGIN_DIR,
1734
1018
  OPT_PORT_OPEN_TIMEOUT,
1735
1019
  OPT_SECURE_FILE_PRIV,
1736
 
  OPT_MIN_EXAMINED_ROW_LIMIT,
1737
 
  OPT_PRINT_DEFAULTS
 
1020
  OPT_MIN_EXAMINED_ROW_LIMIT
1738
1021
};
1739
1022
 
1740
1023
 
1741
1024
struct option my_long_options[] =
1742
1025
{
1743
 
 
1744
1026
  {"help", '?', N_("Display this help and exit."),
1745
1027
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1746
1028
   0, 0},
 
1029
  {"help-extended", '?',
 
1030
   N_("Display this help and exit after initializing plugins."),
 
1031
   (char**) &opt_help_extended, (char**) &opt_help_extended,
 
1032
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1747
1033
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1748
1034
   N_("Auto-increment columns are incremented by this"),
1749
1035
   (char**) &global_system_variables.auto_increment_increment,
1750
1036
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1751
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
 
1037
   OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1752
1038
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1753
1039
   N_("Offset added to Auto-increment columns. Used when "
1754
1040
      "auto-increment-increment != 1"),
1755
1041
   (char**) &global_system_variables.auto_increment_offset,
1756
1042
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1757
 
   1, 1, INT64_MAX, 0, 1, 0 },
 
1043
   1, 1, UINT64_MAX, 0, 1, 0 },
1758
1044
  {"basedir", 'b',
1759
1045
   N_("Path to installation directory. All paths are usually resolved "
1760
1046
      "relative to this."),
1761
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
 
1047
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1762
1048
   0, 0, 0, 0, 0, 0},
1763
1049
  {"chroot", 'r',
1764
1050
   N_("Chroot drizzled daemon during startup."),
1779
1065
   NO_ARG, 0, 0, 0, 0, 0, 0},
1780
1066
  {"datadir", 'h',
1781
1067
   N_("Path to the database root."),
1782
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1068
   (char**) &data_home,
 
1069
   (char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1783
1070
  {"default-storage-engine", OPT_STORAGE_ENGINE,
1784
1071
   N_("Set the default storage engine (table type) for tables."),
1785
1072
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1798
1085
   N_("Set up signals usable for debugging"),
1799
1086
   (char**) &opt_debugging, (char**) &opt_debugging,
1800
1087
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1088
  {"language", 'L',
 
1089
   N_("(IGNORED)"),
 
1090
   (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
 
1091
   0, 0, 0, 0, 0, 0},
1801
1092
  {"lc-time-names", OPT_LC_TIME_NAMES,
1802
1093
   N_("Set the language used for the month names and the days of the week."),
1803
1094
   (char**) &lc_time_names_name,
1809
1100
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1810
1101
   0, 0, 0},
1811
1102
  {"pid-file", OPT_PID_FILE,
1812
 
   N_("Pid file used by drizzled."),
1813
 
   NULL, NULL, 0, GET_STR,
 
1103
   N_("Pid file used by safe_mysqld."),
 
1104
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1814
1105
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1815
1106
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1816
1107
   N_("Maximum time in seconds to wait for the port to become free. "
1820
1111
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1821
1112
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1822
1113
      "within specified directory"),
1823
 
   NULL, NULL, 0,
 
1114
   (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1824
1115
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
1116
  {"server-id", OPT_SERVER_ID,
1826
1117
   N_("Uniquely identifies the server instance in the community of "
1894
1185
   N_("Max packetlength to send/receive from to server."),
1895
1186
   (char**) &global_system_variables.max_allowed_packet,
1896
1187
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1897
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1188
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1898
1189
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
1899
1190
   N_("If there is more than this number of interrupted connections from a "
1900
1191
      "host this host will be blocked from further connections."),
1909
1200
   N_("Don't allow creation of heap tables bigger than this."),
1910
1201
   (char**) &global_system_variables.max_heap_table_size,
1911
1202
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1912
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
 
1203
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1913
1204
   MALLOC_OVERHEAD, 1024, 0},
1914
1205
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1915
1206
   N_("Joins that are probably going to read more than max_join_size records "
1966
1257
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
1967
1258
  {"plugin_dir", OPT_PLUGIN_DIR,
1968
1259
   N_("Directory for plugins."),
1969
 
   NULL, NULL, 0,
 
1260
   (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
1970
1261
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1971
1262
  {"plugin_add", OPT_PLUGIN_ADD,
1972
1263
   N_("Optional comma separated list of plugins to load at startup in addition "
1973
1264
      "to the default list of plugins. "
1974
1265
      "[for example: --plugin_add=crc32,logger_gearman]"),
1975
 
   NULL, NULL, 0,
 
1266
   (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
1976
1267
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1977
1268
  {"plugin_remove", OPT_PLUGIN_ADD,
1978
1269
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
1979
1270
      "removes a plugin from the list of plugins to be loaded. "
1980
1271
      "[for example: --plugin_remove=crc32,logger_gearman]"),
1981
 
   NULL, NULL, 0,
 
1272
   (char**) &opt_plugin_remove, (char**) &opt_plugin_remove, 0,
1982
1273
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1983
1274
  {"plugin_load", OPT_PLUGIN_LOAD,
1984
1275
   N_("Optional comma separated list of plugins to load at starup instead of "
1985
1276
      "the default plugin load list. "
1986
1277
      "[for example: --plugin_load=crc32,logger_gearman]"),
1987
 
   NULL, NULL, 0,
 
1278
   (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
1988
1279
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1989
1280
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1990
1281
   N_("The size of the buffer that is allocated when preloading indexes"),
2006
1297
   N_("Allocation block size for storing ranges during optimization"),
2007
1298
   (char**) &global_system_variables.range_alloc_block_size,
2008
1299
   (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,
 
1300
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
2010
1301
   0, 1024, 0},
2011
1302
  {"read_buffer_size", OPT_RECORD_BUFFER,
2012
1303
    N_("Each thread that does a sequential scan allocates a buffer of this "
2033
1324
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
2034
1325
   (char**) &global_system_variables.sortbuff_size,
2035
1326
   (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,
 
1327
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
2037
1328
   MALLOC_OVERHEAD, 1, 0},
2038
1329
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
2039
1330
   N_("The number of cached table definitions."),
2053
1344
   (char**) &my_thread_stack_size,
2054
1345
   (char**) &my_thread_stack_size, 0, GET_SIZE,
2055
1346
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
2056
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
 
1347
   UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
2057
1348
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
2058
1349
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2059
1350
      " automatically convert it to an on-disk MyISAM table."),
2060
1351
   (char**) &global_system_variables.tmp_table_size,
2061
1352
   (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},
 
1353
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2063
1354
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2064
1355
};
2065
1356
 
2085
1376
         "This software comes with ABSOLUTELY NO WARRANTY. "
2086
1377
         "This is free software,\n"
2087
1378
         "and you are welcome to modify and redistribute it under the GPL "
2088
 
         "license\n\n"));
 
1379
         "license\n\n"
 
1380
         "Starts the Drizzle database server\n"));
2089
1381
 
2090
 
 
2091
1382
  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
 
 
 
1383
  {
 
1384
     internal::print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
1385
     puts("");
 
1386
 
 
1387
     /* Print out all the options including plugin supplied options */
 
1388
     my_print_help_inc_plugins(my_long_options, long_options);
 
1389
  }
2100
1390
}
2101
1391
 
 
1392
 
2102
1393
/**
2103
1394
  Initialize all Drizzle global variables to default values.
2104
1395
 
2118
1409
static void drizzle_init_variables(void)
2119
1410
{
2120
1411
  /* Things reset to zero */
 
1412
  drizzle_home[0]= pidfile_name[0]= 0;
2121
1413
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
1414
  opt_secure_file_priv= 0;
2122
1415
  cleanup_done= 0;
 
1416
  defaults_argc= 0;
 
1417
  defaults_argv= 0;
2123
1418
  dropping_tables= ha_open_options=0;
2124
1419
  test_flags.reset();
2125
1420
  wake_thread=0;
2136
1431
  character_set_filesystem= &my_charset_bin;
2137
1432
 
2138
1433
  /* Things with default values that are not zero */
 
1434
  drizzle_home_ptr= drizzle_home;
 
1435
  pidfile_name_ptr= pidfile_name;
 
1436
  language_ptr= language;
 
1437
  data_home= data_home_real;
2139
1438
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2140
1439
  refresh_version= 1L;  /* Increments on each reload */
2141
1440
  global_thread_id= 1UL;
2142
 
  session::Cache::singleton().getCache().clear();
 
1441
  getSessionList().clear();
 
1442
 
 
1443
  /* Set directory paths */
 
1444
  strncpy(language, LANGUAGE, sizeof(language)-1);
 
1445
  strncpy(data_home_real, get_relative_path(LOCALSTATEDIR),
 
1446
          sizeof(data_home_real)-1);
 
1447
  data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
1448
  data_home_buff[1]=0;
 
1449
  data_home_len= 2;
2143
1450
 
2144
1451
  /* Variables in libraries */
2145
1452
  default_character_set_name= "utf8";
2154
1461
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2155
1462
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2156
1463
  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
1464
  opt_scheduler_default= (char*) "multi_thread";
2185
1465
 
2186
1466
  /* Variables that depends on compile options */
2190
1470
  have_symlink=SHOW_OPTION_YES;
2191
1471
#endif
2192
1472
 
 
1473
  const char *tmpenv;
 
1474
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
1475
    tmpenv = PREFIX;
 
1476
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
 
1477
  
2193
1478
  connection_count= 0;
2194
1479
}
2195
1480
 
2196
1481
 
2197
 
/**
2198
 
  @todo
2199
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2200
 
*/
2201
 
static void get_options()
 
1482
int drizzled_get_one_option(int optid, const struct option *opt,
 
1483
                             char *argument)
2202
1484
{
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
 
 
 
1485
  switch(optid) {
 
1486
  case 'a':
 
1487
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
 
1488
    break;
 
1489
  case 'b':
 
1490
    strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
 
1491
    break;
 
1492
  case 'C':
 
1493
    if (default_collation_name == compiled_default_collation_name)
 
1494
      default_collation_name= 0;
 
1495
    break;
 
1496
  case 'h':
 
1497
    strncpy(data_home_real,argument, sizeof(data_home_real)-1);
 
1498
    /* Correct pointer set by my_getopt (for embedded library) */
 
1499
    data_home= data_home_real;
 
1500
    data_home_len= strlen(data_home);
 
1501
    break;
 
1502
  case 'u':
 
1503
    if (!drizzled_user || !strcmp(drizzled_user, argument))
 
1504
      drizzled_user= argument;
2213
1505
    else
2214
1506
      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
 
  {
 
1507
                          "set to '%s' earlier on the command line\n"),
 
1508
                        argument, drizzled_user);
 
1509
    break;
 
1510
  case 'L':
 
1511
    strncpy(language, argument, sizeof(language)-1);
 
1512
    break;
 
1513
  case 'V':
2221
1514
    print_version();
2222
1515
    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
 
  {
 
1516
  case 'W':
 
1517
    if (!argument)
 
1518
      global_system_variables.log_warnings++;
 
1519
    else if (argument == disabled_my_option)
 
1520
      global_system_variables.log_warnings= 0L;
 
1521
    else
 
1522
      global_system_variables.log_warnings= atoi(argument);
 
1523
    break;
 
1524
  case 'T':
 
1525
    if (argument)
 
1526
    {
 
1527
      test_flags.set((uint32_t) atoi(argument));
 
1528
    }
 
1529
    break;
 
1530
  case (int) OPT_WANT_CORE:
2287
1531
    test_flags.set(TEST_CORE_ON_SIGNAL);
2288
 
  }
2289
 
 
2290
 
  if (vm.count("skip-stack-trace"))
2291
 
  {
 
1532
    break;
 
1533
  case (int) OPT_SKIP_STACK_TRACE:
2292
1534
    test_flags.set(TEST_NO_STACKTRACE);
2293
 
  }
2294
 
 
2295
 
  if (vm.count("skip-symlinks"))
2296
 
  {
 
1535
    break;
 
1536
  case (int) OPT_SKIP_SYMLINKS:
2297
1537
    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
 
  }
 
1538
    break;
 
1539
  case (int) OPT_BIND_ADDRESS:
 
1540
    {
 
1541
      struct addrinfo *res_lst, hints;
 
1542
 
 
1543
      memset(&hints, 0, sizeof(struct addrinfo));
 
1544
      hints.ai_socktype= SOCK_STREAM;
 
1545
      hints.ai_protocol= IPPROTO_TCP;
 
1546
 
 
1547
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
 
1548
      {
 
1549
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
 
1550
        return EXIT_ARGUMENT_INVALID;
 
1551
      }
 
1552
 
 
1553
      if (res_lst->ai_next)
 
1554
      {
 
1555
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
 
1556
                          "multiple interfaces!"));
 
1557
        return EXIT_ARGUMENT_INVALID;
 
1558
      }
 
1559
      freeaddrinfo(res_lst);
 
1560
    }
 
1561
    break;
 
1562
  case (int) OPT_PID_FILE:
 
1563
    strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
 
1564
    break;
 
1565
  case OPT_SERVER_ID:
 
1566
    break;
 
1567
  case OPT_TX_ISOLATION:
 
1568
    {
 
1569
      int type;
 
1570
      type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
 
1571
      global_system_variables.tx_isolation= (type-1);
 
1572
      break;
 
1573
    }
 
1574
  case OPT_TC_HEURISTIC_RECOVER:
 
1575
    tc_heuristic_recover= find_type_or_exit(argument,
 
1576
                                            &tc_heuristic_recover_typelib,
 
1577
                                            opt->name);
 
1578
    break;
 
1579
  }
 
1580
 
 
1581
  return 0;
 
1582
}
 
1583
 
 
1584
static void option_error_reporter(enum loglevel level, const char *format, ...)
 
1585
{
 
1586
  va_list args;
 
1587
  va_start(args, format);
 
1588
 
 
1589
  /* Don't print warnings for --loose options during bootstrap */
 
1590
  if (level == ERROR_LEVEL || global_system_variables.log_warnings)
 
1591
  {
 
1592
    plugin::ErrorMessage::vprintf(NULL, ERROR_LEVEL, format, args);
 
1593
  }
 
1594
  va_end(args);
 
1595
}
 
1596
 
 
1597
 
 
1598
/**
 
1599
  @todo
 
1600
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
 
1601
*/
 
1602
static void get_options(int *argc,char **argv)
 
1603
{
 
1604
  int ho_error;
 
1605
 
 
1606
  my_getopt_error_reporter= option_error_reporter;
 
1607
 
 
1608
  string progname(argv[0]);
2312
1609
 
2313
1610
  /* Skip unknown options so that they may be processed later by plugins */
2314
1611
  my_getopt_skip_unknown= true;
2315
1612
 
 
1613
  if ((ho_error= handle_options(argc, &argv, my_long_options,
 
1614
                                drizzled_get_one_option)))
 
1615
    exit(ho_error);
 
1616
  (*argc)++; /* add back one for the progname handle_options removes */
 
1617
             /* no need to do this for argv as we are discarding it. */
2316
1618
 
2317
1619
#if defined(HAVE_BROKEN_REALPATH)
2318
1620
  internal::my_use_symdir=0;
2335
1637
 
2336
1638
  if (drizzled_chroot)
2337
1639
    set_root(drizzled_chroot);
 
1640
  fix_paths(progname);
2338
1641
 
2339
1642
  /*
2340
1643
    Set some global variables from the global_system_variables
2344
1647
}
2345
1648
 
2346
1649
 
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;
 
1650
static const char *get_relative_path(const char *path)
 
1651
{
 
1652
  if (internal::test_if_hard_path(path) &&
 
1653
      (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
 
1654
      strcmp(PREFIX,FN_ROOTDIR))
 
1655
  {
 
1656
    if (strlen(PREFIX) < strlen(path))
 
1657
      path+=(size_t) strlen(PREFIX);
 
1658
    while (*path == FN_LIBCHAR)
 
1659
      path++;
 
1660
  }
 
1661
  return path;
 
1662
}
 
1663
 
 
1664
 
 
1665
static void fix_paths(string &progname)
 
1666
{
 
1667
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
 
1668
  internal::convert_dirname(drizzle_home,drizzle_home,NULL);
 
1669
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
 
1670
#if defined(HAVE_BROKEN_REALPATH)
 
1671
   internal::my_load_path(drizzle_home, drizzle_home, NULL);
 
1672
#else
 
1673
  if (!realpath(drizzle_home,rp_buff))
 
1674
    internal::my_load_path(rp_buff, drizzle_home, NULL);
 
1675
  rp_buff[FN_REFLEN-1]= '\0';
 
1676
  strcpy(drizzle_home,rp_buff);
 
1677
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
 
1678
  pos= strchr(drizzle_home, '\0');
 
1679
#endif
 
1680
  if (pos[-1] != FN_LIBCHAR)
 
1681
  {
 
1682
    pos[0]= FN_LIBCHAR;
 
1683
    pos[1]= 0;
 
1684
  }
 
1685
  internal::convert_dirname(data_home_real,data_home_real,NULL);
 
1686
  (void) internal::fn_format(buff, data_home_real, "", "",
 
1687
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
1688
  (void) internal::unpack_dirname(data_home_real_unpacked, buff);
 
1689
  internal::convert_dirname(language,language,NULL);
 
1690
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
1691
  (void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
 
1692
  (void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
 
1693
 
 
1694
  if (opt_plugin_dir_ptr == NULL)
 
1695
  {
 
1696
    /* No plugin dir has been specified. Figure out where the plugins are */
 
1697
    if (progname[0] != FN_LIBCHAR)
 
1698
    {
 
1699
      /* We have a relative path and need to find the absolute */
 
1700
      char working_dir[FN_REFLEN];
 
1701
      char *working_dir_ptr= working_dir;
 
1702
      working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
 
1703
      string new_path(working_dir);
 
1704
      if (*(new_path.end()-1) != '/')
 
1705
        new_path.push_back('/');
 
1706
      if (progname[0] == '.' && progname[1] == '/')
 
1707
        new_path.append(progname.substr(2));
 
1708
      else
 
1709
        new_path.append(progname);
 
1710
      progname.swap(new_path);
 
1711
    }
 
1712
 
 
1713
    /* Now, trim off the exe name */
 
1714
    string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
 
1715
    if (progdir.rfind(".libs/") != string::npos)
 
1716
    {
 
1717
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
 
1718
    }
 
1719
    string testlofile(progdir);
 
1720
    testlofile.append("drizzled.lo");
 
1721
    string testofile(progdir);
 
1722
    testofile.append("drizzled.o");
 
1723
    struct stat testfile_stat;
 
1724
    if (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat))
 
1725
    {
 
1726
      /* neither drizzled.lo or drizzled.o exist - we are not in a source dir.
 
1727
       * Go on as usual
 
1728
       */
 
1729
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
 
1730
                                          drizzle_home);
 
1731
    }
 
1732
    else
 
1733
    {
 
1734
      /* We are in a source dir! Plugin dir is ../plugin/.libs */
 
1735
      size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
 
1736
      string source_plugindir(progdir.substr(0,last_libchar_pos));
 
1737
      source_plugindir.append("plugin/.libs");
 
1738
      (void) internal::my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
 
1739
    }
 
1740
  }
 
1741
  else
 
1742
  {
 
1743
    (void) internal::my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
 
1744
  }
 
1745
  opt_plugin_dir_ptr= opt_plugin_dir;
 
1746
 
 
1747
  const char *sharedir= get_relative_path(PKGDATADIR);
 
1748
  if (internal::test_if_hard_path(sharedir))
 
1749
    strncpy(buff,sharedir,sizeof(buff)-1);
 
1750
  else
 
1751
  {
 
1752
    strcpy(buff, drizzle_home);
 
1753
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
 
1754
  }
 
1755
  internal::convert_dirname(buff,buff,NULL);
 
1756
  (void) internal::my_load_path(language,language,buff);
 
1757
 
 
1758
  if (not opt_help and not opt_help_extended)
 
1759
  {
 
1760
    char *tmp_string;
2360
1761
    struct stat buf;
2361
 
    drizzle_tmpdir.clear();
2362
 
 
2363
 
    if (vm.count("tmpdir"))
 
1762
 
 
1763
    tmp_string= getenv("TMPDIR");
 
1764
 
 
1765
    if (opt_drizzle_tmpdir)
2364
1766
    {
2365
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
 
1767
      drizzle_tmpdir.append(opt_drizzle_tmpdir);
2366
1768
    }
2367
1769
    else if (tmp_string == NULL)
2368
1770
    {
2369
 
      drizzle_tmpdir.append(getDataHome().file_string());
2370
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2371
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
 
1771
      drizzle_tmpdir.append(data_home);
2372
1772
    }
2373
1773
    else
2374
1774
    {
2375
1775
      drizzle_tmpdir.append(tmp_string);
2376
1776
    }
2377
1777
 
2378
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2379
1778
    assert(drizzle_tmpdir.size());
 
1779
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
 
1780
    {
 
1781
      perror(drizzle_tmpdir.c_str());
 
1782
      exit(1);
 
1783
    }
 
1784
 
 
1785
    drizzle_tmpdir.append(FN_ROOTDIR);
 
1786
    drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2380
1787
 
2381
1788
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2382
1789
    {
2394
1801
    }
2395
1802
  }
2396
1803
 
 
1804
  /*
 
1805
    Convert the secure-file-priv option to system format, allowing
 
1806
    a quick strcmp to check if read or write is in an allowed dir
 
1807
   */
 
1808
  if (opt_secure_file_priv)
 
1809
  {
 
1810
    internal::convert_dirname(buff, opt_secure_file_priv, NULL);
 
1811
    free(opt_secure_file_priv);
 
1812
    opt_secure_file_priv= strdup(buff);
 
1813
    if (opt_secure_file_priv == NULL)
 
1814
      exit(1);
 
1815
  }
2397
1816
}
2398
1817
 
2399
1818
} /* namespace drizzled */