~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Brian Aker
  • Date: 2010-10-06 18:16:00 UTC
  • mto: (1818.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1819.
  • Revision ID: brian@tangent.org-20101006181600-q7zuzw31zlq030ra
Convert sql_string to use size_t (this should clean up ICC warnings).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
21
 
 
22
 
#include <drizzled/configmake.h>
23
 
#include <drizzled/atomics.h>
24
 
#include <drizzled/data_home.h>
 
20
#include "config.h"
 
21
#include "drizzled/configmake.h"
 
22
#include "drizzled/atomics.h"
 
23
#include "drizzled/data_home.h"
25
24
 
26
25
#include <netdb.h>
27
26
#include <sys/types.h>
32
31
#include <stdexcept>
33
32
 
34
33
#include <boost/program_options.hpp>
35
 
#include <drizzled/program_options/config_file.h>
36
34
#include <boost/thread/recursive_mutex.hpp>
37
35
#include <boost/thread/mutex.hpp>
38
 
#include <boost/thread/shared_mutex.hpp>
39
36
#include <boost/thread/condition_variable.hpp>
40
37
#include <boost/filesystem.hpp>
41
 
#include <boost/detail/atomic_count.hpp>
42
38
 
43
 
#include <drizzled/cached_directory.h>
44
 
#include <drizzled/charset.h>
45
 
#include <drizzled/data_home.h>
46
 
#include <drizzled/debug.h>
47
 
#include <drizzled/definition/cache.h>
48
 
#include <drizzled/drizzled.h>
 
39
#include "drizzled/internal/my_sys.h"
 
40
#include "drizzled/internal/my_bit.h"
 
41
#include <drizzled/my_hash.h>
 
42
#include <drizzled/error.h>
49
43
#include <drizzled/errmsg_print.h>
50
 
#include <drizzled/error.h>
51
 
#include <drizzled/global_buffer.h>
52
 
#include <drizzled/internal/my_bit.h>
53
 
#include <drizzled/internal/my_sys.h>
 
44
#include <drizzled/tztime.h>
 
45
#include <drizzled/sql_base.h>
 
46
#include <drizzled/show.h>
 
47
#include <drizzled/sql_parse.h>
54
48
#include <drizzled/item/cmpfunc.h>
 
49
#include <drizzled/session.h>
55
50
#include <drizzled/item/create.h>
56
 
#include <drizzled/message/cache.h>
57
 
#include <drizzled/module/load_list.h>
58
 
#include <drizzled/module/registry.h>
59
 
#include <drizzled/my_hash.h>
60
 
#include <drizzled/plugin/client.h>
61
 
#include <drizzled/plugin/error_message.h>
62
 
#include <drizzled/plugin/event_observer.h>
63
 
#include <drizzled/plugin/listen.h>
64
 
#include <drizzled/plugin/monitored_in_transaction.h>
65
 
#include <drizzled/plugin/scheduler.h>
66
 
#include <drizzled/plugin/storage_engine.h>
67
 
#include <drizzled/plugin/xa_resource_manager.h>
68
 
#include <drizzled/probes.h>
69
 
#include <drizzled/replication_services.h> /* For ReplicationServices::evaluateRegisteredPlugins() */
70
 
#include <drizzled/session.h>
71
 
#include <drizzled/session/cache.h>
72
 
#include <drizzled/show.h>
73
 
#include <drizzled/sql_base.h>
74
 
#include <drizzled/sql_parse.h>
75
 
#include <drizzled/temporal_format.h> /* For init_temporal_formats() */
76
 
#include <drizzled/tztime.h>
77
51
#include <drizzled/unireg.h>
78
 
#include <plugin/myisam/myisam.h>
79
 
#include <drizzled/typelib.h>
80
 
#include <drizzled/visibility.h>
 
52
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
 
53
#include "drizzled/plugin/listen.h"
 
54
#include "drizzled/plugin/error_message.h"
 
55
#include "drizzled/plugin/client.h"
 
56
#include "drizzled/plugin/scheduler.h"
 
57
#include "drizzled/plugin/xa_resource_manager.h"
 
58
#include "drizzled/plugin/monitored_in_transaction.h"
 
59
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
 
60
#include "drizzled/probes.h"
 
61
#include "drizzled/session_list.h"
 
62
#include "drizzled/charset.h"
 
63
#include "plugin/myisam/myisam.h"
 
64
#include "drizzled/drizzled.h"
 
65
#include "drizzled/module/registry.h"
 
66
#include "drizzled/module/load_list.h"
81
67
 
82
68
#include <google/protobuf/stubs/common.h>
83
69
 
84
 
#include <drizzled/refresh_version.h>
85
 
 
86
70
#if TIME_WITH_SYS_TIME
87
71
# include <sys/time.h>
88
72
# include <time.h>
102
86
 
103
87
#include <errno.h>
104
88
#include <sys/stat.h>
105
 
#include <drizzled/option.h>
 
89
#include "drizzled/option.h"
106
90
#ifdef HAVE_SYSENT_H
107
91
#include <sysent.h>
108
92
#endif
136
120
#include <sys/fpu.h>
137
121
#endif
138
122
 
139
 
#include <drizzled/internal/my_pthread.h>                       // For thr_setconcurency()
140
 
#include <drizzled/constrained_value.h>
 
123
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
141
124
 
142
125
#include <drizzled/gettext.h>
143
126
 
144
127
 
145
 
#ifdef HAVE_VALGRIND
 
128
#ifdef HAVE_purify
146
129
#define IF_PURIFY(A,B) (A)
147
130
#else
148
131
#define IF_PURIFY(A,B) (B)
156
139
using namespace std;
157
140
namespace fs=boost::filesystem;
158
141
namespace po=boost::program_options;
159
 
namespace dpo=drizzled::program_options;
160
142
 
161
 
bool opt_daemon= false;
162
143
 
163
144
namespace drizzled
164
145
{
165
146
 
 
147
#define mysqld_charset &my_charset_utf8_general_ci
166
148
inline void setup_fpu()
167
149
{
168
150
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
222
204
 
223
205
/* static variables */
224
206
 
225
 
static bool opt_debugging= false;
 
207
static bool opt_debugging= 0;
226
208
static uint32_t wake_thread;
227
209
static char *drizzled_chroot;
228
210
static const char *default_character_set_name;
234
216
 
235
217
/* Global variables */
236
218
 
 
219
bool volatile ready_to_exit;
237
220
char *drizzled_user;
238
221
bool volatile select_thread_in_use;
239
222
bool volatile abort_loop;
240
 
DRIZZLED_API bool volatile shutdown_in_progress;
 
223
bool volatile shutdown_in_progress;
241
224
char *opt_scheduler_default;
242
225
const char *opt_scheduler= NULL;
243
226
 
244
 
DRIZZLED_API size_t my_thread_stack_size= 0;
 
227
size_t my_thread_stack_size= 0;
245
228
 
246
229
/*
247
230
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
249
232
plugin::StorageEngine *heap_engine;
250
233
plugin::StorageEngine *myisam_engine;
251
234
 
 
235
char* opt_secure_file_priv= 0;
 
236
 
252
237
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
253
238
 
254
239
uint32_t drizzled_bind_timeout;
 
240
std::bitset<12> test_flags;
255
241
uint32_t dropping_tables, ha_open_options;
256
242
uint32_t tc_heuristic_recover= 0;
257
243
uint64_t session_startup_options;
258
 
back_log_constraints back_log(50);
259
 
DRIZZLED_API uint32_t server_id;
 
244
uint32_t back_log;
 
245
uint32_t server_id;
260
246
uint64_t table_cache_size;
261
247
size_t table_def_size;
 
248
uint64_t max_connect_errors;
262
249
uint32_t global_thread_id= 1UL;
263
250
pid_t current_pid;
264
251
 
301
288
time_t server_start_time;
302
289
time_t flush_status_time;
303
290
 
304
 
fs::path basedir(PREFIX);
305
 
fs::path pid_file;
306
 
fs::path secure_file_priv("");
307
 
fs::path plugin_dir;
308
 
fs::path system_config_dir(SYSCONFDIR);
309
 
 
 
291
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
 
292
char *default_tz_name;
 
293
char glob_hostname[FN_REFLEN];
310
294
 
311
295
char *opt_tc_log_file;
312
296
const key_map key_map_empty(0);
321
305
const char *in_additional_cond= "<IN COND>";
322
306
const char *in_having_cond= "<IN HAVING>";
323
307
 
 
308
my_decimal decimal_zero;
324
309
/* classes for comparation parsing/processing */
325
310
 
326
311
FILE *stderror_file=0;
327
312
 
328
 
drizzle_system_variables global_system_variables;
329
 
drizzle_system_variables max_system_variables;
330
 
global_counters current_global_counters;
 
313
struct system_variables global_system_variables;
 
314
struct system_variables max_system_variables;
 
315
struct global_counters current_global_counters;
331
316
 
332
 
DRIZZLED_API const CHARSET_INFO *system_charset_info;
333
 
const CHARSET_INFO *files_charset_info;
 
317
const CHARSET_INFO *system_charset_info, *files_charset_info ;
334
318
const CHARSET_INFO *table_alias_charset;
335
319
const CHARSET_INFO *character_set_filesystem;
336
320
 
338
322
 
339
323
SHOW_COMP_OPTION have_symlink;
340
324
 
341
 
boost::condition_variable_any COND_refresh;
 
325
/* Thread specific variables */
 
326
 
 
327
boost::mutex LOCK_open;
 
328
boost::mutex LOCK_global_system_variables;
 
329
boost::mutex LOCK_thread_count;
 
330
 
 
331
boost::condition_variable COND_refresh;
342
332
boost::condition_variable COND_thread_count;
343
333
pthread_t signal_thread;
 
334
boost::condition_variable COND_server_end;
344
335
 
345
336
/* Static variables */
346
337
 
347
338
int cleanup_done;
 
339
static char *drizzle_home_ptr, *pidfile_name_ptr;
348
340
 
349
341
passwd *user_info;
350
342
 
351
 
boost::detail::atomic_count connection_count(0);
352
 
 
353
 
global_buffer_constraint<uint64_t> global_sort_buffer(0);
354
 
global_buffer_constraint<uint64_t> global_join_buffer(0);
355
 
global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
356
 
global_buffer_constraint<uint64_t> global_read_buffer(0);
357
 
 
358
 
DRIZZLED_API size_t transaction_message_threshold;
 
343
atomic<uint32_t> connection_count;
 
344
 
 
345
/** 
 
346
  Refresh value. We use to test this to find out if a refresh even has happened recently.
 
347
*/
 
348
uint64_t refresh_version;  /* Increments on each reload */
 
349
 
 
350
/* Function declarations */
 
351
bool drizzle_rm_tmp_tables();
359
352
 
360
353
static void drizzle_init_variables(void);
361
354
static void get_options();
 
355
static const char *get_relative_path(const char *path);
362
356
static void fix_paths();
363
357
 
364
358
static void usage(void);
366
360
 
367
361
fs::path base_plugin_dir(PKGPLUGINDIR);
368
362
 
369
 
po::options_description config_options(_("Config File Options"));
370
 
po::options_description long_options(_("Kernel Options"));
371
 
po::options_description plugin_load_options(_("Plugin Loading Options"));
372
 
po::options_description plugin_options(_("Plugin Options"));
373
 
po::options_description initial_options(_("Config and Plugin Loading"));
374
 
po::options_description full_options(_("Kernel and Plugin Loading and Plugin"));
 
363
po::options_description config_options("Config File Options");
 
364
po::options_description long_options("Kernel Options");
 
365
po::options_description plugin_load_options("Plugin Loading Options");
 
366
po::options_description plugin_options("Plugin Options");
 
367
po::options_description initial_options("Config and Plugin Loading");
 
368
po::options_description full_options("Kernel and Plugin Loading and Plugin");
375
369
vector<string> unknown_options;
376
370
vector<string> defaults_file_list;
377
371
po::variables_map vm;
 
372
char * data_dir_ptr;
378
373
 
379
374
po::variables_map &getVariablesMap()
380
375
{
381
376
  return vm;
382
377
}
383
378
 
384
 
namespace
385
 
{
386
 
 
387
 
std::string &getGlobHostname()
388
 
{
389
 
  static std::string glob_hostname("localhost");
390
 
  return glob_hostname;
391
 
}
392
 
 
393
 
void setServerHostname(const std::string &hostname)
394
 
{
395
 
  getGlobHostname()= hostname;
396
 
}
397
 
}
398
 
 
399
 
const std::string &getServerHostname()
400
 
{
401
 
  return getGlobHostname();
402
 
}
403
 
 
 
379
std::string& getDataHome()
 
380
{
 
381
  static string data_home(LOCALSTATEDIR);
 
382
  return data_home;
 
383
}
 
384
 
 
385
std::string& getDataHomeCatalog()
 
386
{
 
387
  static string data_home_catalog(getDataHome());
 
388
  return data_home_catalog;
 
389
}
 
390
 
 
391
char *getDatadir()
 
392
{
 
393
  return data_dir_ptr;
 
394
}
 
395
 
 
396
char **getDatadirPtr()
 
397
{
 
398
  return &data_dir_ptr;
 
399
}
 
400
 
404
401
/****************************************************************************
405
402
** Code to end drizzled
406
403
****************************************************************************/
412
409
 
413
410
  /* kill connection thread */
414
411
  {
415
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
412
    boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
416
413
 
417
414
    while (select_thread_in_use)
418
415
    {
436
433
    statements and inform their clients that the server is about to die.
437
434
  */
438
435
 
 
436
  Session *tmp;
 
437
 
 
438
  LOCK_thread_count.lock(); // For unlink from list
 
439
 
 
440
  for( SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
439
441
  {
440
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
441
 
    session::Cache::list list= session::Cache::singleton().getCache();
442
 
 
443
 
    for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
444
 
    {
445
 
      Session::shared_ptr tmp(*it);
446
 
 
447
 
      tmp->setKilled(Session::KILL_CONNECTION);
448
 
      tmp->scheduler->killSession(tmp.get());
449
 
      DRIZZLE_CONNECTION_DONE(tmp->thread_id);
450
 
 
451
 
      tmp->lockOnSys();
452
 
    }
 
442
    tmp= *it;
 
443
    tmp->killed= Session::KILL_CONNECTION;
 
444
    tmp->scheduler->killSession(tmp);
 
445
    DRIZZLE_CONNECTION_DONE(tmp->thread_id);
 
446
    tmp->lockOnSys();
453
447
  }
 
448
  LOCK_thread_count.unlock(); // For unlink from list
454
449
 
455
 
  if (session::Cache::singleton().count())
 
450
  if (connection_count)
456
451
    sleep(2);                                   // Give threads time to die
457
452
 
458
453
  /*
462
457
  */
463
458
  for (;;)
464
459
  {
465
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
466
 
    session::Cache::list list= session::Cache::singleton().getCache();
467
 
 
468
 
    if (list.empty())
 
460
    LOCK_thread_count.lock(); // For unlink from list
 
461
    if (getSessionList().empty())
469
462
    {
 
463
      LOCK_thread_count.unlock();
470
464
      break;
471
465
    }
 
466
    tmp= getSessionList().front();
472
467
    /* Close before unlock, avoiding crash. See LP bug#436685 */
473
 
    list.front()->getClient()->close();
 
468
    tmp->client->close();
 
469
    LOCK_thread_count.unlock();
474
470
  }
475
471
}
476
472
 
 
473
/**
 
474
  cleanup all memory and end program nicely.
 
475
 
 
476
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
477
    by the main thread. To get Drizzle to shut down nicely in this case
 
478
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
479
 
 
480
  @note
 
481
    This function never returns.
 
482
*/
 
483
void unireg_end(void)
 
484
{
 
485
  clean_up(1);
 
486
  internal::my_thread_end();
 
487
#if defined(SIGNALS_DONT_BREAK_READ)
 
488
  exit(0);
 
489
#else
 
490
  pthread_exit(0);                              // Exit is in main thread
 
491
#endif
 
492
}
 
493
 
477
494
 
478
495
void unireg_abort(int exit_code)
479
496
{
480
497
 
481
498
  if (exit_code)
482
 
  {
483
 
    errmsg_printf(error::ERROR, _("Aborting"));
484
 
  }
 
499
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
485
500
  else if (opt_help)
486
 
  {
487
501
    usage();
488
 
  }
489
 
 
490
502
  clean_up(!opt_help && (exit_code));
491
503
  internal::my_end();
492
504
  exit(exit_code);
499
511
    return;
500
512
 
501
513
  table_cache_free();
 
514
  set_var_free();
502
515
  free_charsets();
503
516
  module::Registry &modules= module::Registry::singleton();
504
517
  modules.shutdownModules();
505
518
  xid_cache_free();
 
519
  if (opt_secure_file_priv)
 
520
    free(opt_secure_file_priv);
506
521
 
507
522
  deinit_temporal_formats();
508
523
 
510
525
  google::protobuf::ShutdownProtobufLibrary();
511
526
#endif
512
527
 
513
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
 
528
  (void) unlink(pidfile_name);  // This may not always exist
514
529
 
515
530
  if (print_message && server_start_time)
516
 
    errmsg_printf(drizzled::error::INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
517
 
 
518
 
  session::Cache::singleton().shutdownFirst();
519
 
 
 
531
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
 
532
  LOCK_thread_count.lock();
 
533
  ready_to_exit=1;
 
534
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
535
  COND_server_end.notify_all();
 
536
  LOCK_thread_count.unlock();
 
537
 
 
538
  char **data_home_ptr= getDatadirPtr();
 
539
  delete[](*data_home_ptr);
520
540
  /*
521
541
    The following lines may never be executed as the main thread may have
522
542
    killed us
540
560
      tmp_user_info= getpwnam(user);
541
561
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
542
562
          global_system_variables.log_warnings)
543
 
            errmsg_printf(error::WARN, _("One can only use the --user switch "
 
563
            errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
544
564
                            "if running as root\n"));
545
565
    }
546
566
    return NULL;
547
567
  }
548
 
  if (not user)
 
568
  if (!user)
549
569
  {
550
 
      errmsg_printf(error::ERROR, _("Fatal error: Please read \"Security\" section of "
551
 
                                    "the manual to find out how to run drizzled as root"));
 
570
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
 
571
                      "the manual to find out how to run drizzled as root!\n"));
552
572
    unireg_abort(1);
553
573
  }
554
 
 
555
 
  if (not strcmp(user, "root"))
 
574
  if (!strcmp(user,"root"))
556
575
    return NULL;                        // Avoid problem with dynamic libraries
557
576
 
558
577
  if (!(tmp_user_info= getpwnam(user)))
559
578
  {
560
579
    // Allow a numeric uid to be used
561
580
    const char *pos;
562
 
    for (pos= user; my_isdigit(&my_charset_utf8_general_ci,*pos); pos++) ;
 
581
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
563
582
    if (*pos)                                   // Not numeric id
564
583
      goto err;
565
584
    if (!(tmp_user_info= getpwuid(atoi(user))))
568
587
  return tmp_user_info;
569
588
 
570
589
err:
571
 
  errmsg_printf(error::ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
 
590
  errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
572
591
                    "Please check that the user exists!\n"),user);
573
592
  unireg_abort(1);
574
593
 
575
594
#ifdef PR_SET_DUMPABLE
576
 
  if (getDebug().test(debug::CORE_ON_SIGNAL))
 
595
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
577
596
  {
578
597
    /* inform kernel that process is dumpable */
579
598
    (void) prctl(PR_SET_DUMPABLE, 1);
593
612
  initgroups((char*) user, user_info_arg->pw_gid);
594
613
  if (setgid(user_info_arg->pw_gid) == -1)
595
614
  {
596
 
    sql_perror(_("Set process group ID failed"));
 
615
    sql_perror(N_("Set process group ID failed"));
597
616
    unireg_abort(1);
598
617
  }
599
618
  if (setuid(user_info_arg->pw_uid) == -1)
600
619
  {
601
 
    sql_perror(_("Set process user ID failed"));
 
620
    sql_perror(N_("Set process user ID failed"));
602
621
    unireg_abort(1);
603
622
  }
604
623
}
610
629
{
611
630
  if ((chroot(path) == -1) || !chdir("/"))
612
631
  {
613
 
    sql_perror(_("Process chroot failed"));
 
632
    sql_perror(N_("Process chroot failed"));
614
633
    unireg_abort(1);
615
634
  }
616
635
}
622
641
  SYNOPSIS
623
642
    Session::unlink()
624
643
    session              Thread handler
 
644
 
 
645
  NOTES
 
646
    LOCK_thread_count is locked and left locked
625
647
*/
626
648
 
627
 
void drizzled::Session::unlink(session_id_t &session_id)
628
 
{
629
 
  Session::shared_ptr session= session::Cache::singleton().find(session_id);
630
 
 
631
 
  if (session)
632
 
    unlink(session);
633
 
}
634
 
 
635
 
void drizzled::Session::unlink(Session::shared_ptr &session)
636
 
{
637
 
  --connection_count;
 
649
void Session::unlink(Session *session)
 
650
{
 
651
  connection_count.decrement();
638
652
 
639
653
  session->cleanup();
640
654
 
641
 
  boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
642
 
 
643
 
  if (unlikely(plugin::EventObserver::disconnectSession(*session)))
644
 
  {
645
 
    // We should do something about an error...
646
 
  }
647
 
  session::Cache::singleton().erase(session);
 
655
  LOCK_thread_count.lock();
 
656
  session->lockForDelete();
 
657
 
 
658
  getSessionList().erase(remove(getSessionList().begin(),
 
659
                         getSessionList().end(),
 
660
                         session));
 
661
 
 
662
  delete session;
 
663
  LOCK_thread_count.unlock();
648
664
}
649
665
 
650
666
 
665
681
 
666
682
static void find_plugin_dir(string progname)
667
683
{
668
 
  fs::path full_progname(fs::system_complete(progname));
669
 
 
670
 
  fs::path progdir(full_progname.parent_path());
671
 
  if (progdir.filename() == ".libs")
672
 
  {
673
 
    progdir= progdir.parent_path();
674
 
  }
675
 
 
676
 
  if (fs::exists(progdir / "drizzled.lo") || fs::exists(progdir / "drizzled.o"))
 
684
  if (progname[0] != FN_LIBCHAR)
 
685
  {
 
686
    /* We have a relative path and need to find the absolute */
 
687
    char working_dir[FN_REFLEN];
 
688
    char *working_dir_ptr= working_dir;
 
689
    working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
 
690
    string new_path(working_dir);
 
691
    if (*(new_path.end()-1) != '/')
 
692
      new_path.push_back('/');
 
693
    if (progname[0] == '.' && progname[1] == '/')
 
694
      new_path.append(progname.substr(2));
 
695
    else
 
696
      new_path.append(progname);
 
697
    progname.swap(new_path);
 
698
  }
 
699
 
 
700
  /* Now, trim off the exe name */
 
701
  string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
 
702
  if (progdir.rfind(".libs/") != string::npos)
 
703
  {
 
704
    progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
 
705
  }
 
706
  string testlofile(progdir);
 
707
  testlofile.append("drizzled.lo");
 
708
  string testofile(progdir);
 
709
  testofile.append("drizzled.o");
 
710
  struct stat testfile_stat;
 
711
  if (not (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat)))
677
712
  {
678
713
    /* We are in a source dir! Plugin dir is ../plugin/.libs */
679
 
    base_plugin_dir= progdir.parent_path();
 
714
    size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
 
715
    base_plugin_dir= progdir.substr(0,last_libchar_pos);
680
716
    base_plugin_dir /= "plugin";
681
717
    base_plugin_dir /= ".libs";
682
718
  }
683
 
 
684
 
  if (plugin_dir.root_directory() == "")
685
 
  {
686
 
    fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
687
 
    full_plugin_dir /= plugin_dir;
688
 
    plugin_dir= full_plugin_dir;
689
 
  }
690
 
}
691
 
 
692
 
static void notify_plugin_dir(fs::path in_plugin_dir)
693
 
{
694
 
  plugin_dir= in_plugin_dir;
695
 
  if (plugin_dir.root_directory() == "")
696
 
  {
697
 
    fs::path full_plugin_dir(fs::system_complete(basedir));
698
 
    full_plugin_dir /= plugin_dir;
699
 
    plugin_dir= full_plugin_dir;
700
 
  }
701
 
}
702
 
 
703
 
static void expand_secure_file_priv(fs::path in_secure_file_priv)
704
 
{
705
 
  secure_file_priv= fs::system_complete(in_secure_file_priv);
 
719
  (void) internal::my_load_path(opt_plugin_dir, fs::path(fs::system_complete(base_plugin_dir)).file_string().c_str(), "");
 
720
}
 
721
 
 
722
static void notify_plugin_dir(string in_plugin_dir)
 
723
{
 
724
  if (not in_plugin_dir.empty())
 
725
  {
 
726
    (void) internal::my_load_path(opt_plugin_dir, in_plugin_dir.c_str(), drizzle_home);
 
727
  }
706
728
}
707
729
 
708
730
static void check_limits_aii(uint64_t in_auto_increment_increment)
710
732
  global_system_variables.auto_increment_increment= 1;
711
733
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
712
734
  {
713
 
    cout << _("Error: Invalid Value for auto_increment_increment");
 
735
    cout << N_("Error: Invalid Value for auto_increment_increment");
714
736
    exit(-1);
715
737
  }
716
738
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
721
743
  global_system_variables.auto_increment_offset= 1;
722
744
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
723
745
  {
724
 
    cout << _("Error: Invalid Value for auto_increment_offset");
 
746
    cout << N_("Error: Invalid Value for auto_increment_offset");
725
747
    exit(-1);
726
748
  }
727
749
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
732
754
  global_system_variables.completion_type= 0;
733
755
  if (in_completion_type > 2)
734
756
  {
735
 
    cout << _("Error: Invalid Value for completion_type");
 
757
    cout << N_("Error: Invalid Value for completion_type");
736
758
    exit(-1);
737
759
  }
738
760
  global_system_variables.completion_type= in_completion_type;
739
761
}
740
762
 
 
763
static void check_limits_back_log(uint32_t in_back_log)
 
764
{
 
765
  back_log= 50;
 
766
  if (in_back_log < 1 || in_back_log > 65535)
 
767
  {
 
768
    cout << N_("Error: Invalid Value for back_log");
 
769
    exit(-1);
 
770
  }
 
771
  back_log= in_back_log;
 
772
}
741
773
 
742
774
static void check_limits_dpi(uint32_t in_div_precincrement)
743
775
{
744
776
  global_system_variables.div_precincrement= 4;
745
777
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
746
778
  {
747
 
    cout << _("Error: Invalid Value for div-precision-increment");
 
779
    cout << N_("Error: Invalid Value for div-precision-increment");
748
780
    exit(-1);
749
781
  }
750
782
  global_system_variables.div_precincrement= in_div_precincrement;
755
787
  global_system_variables.group_concat_max_len= 1024;
756
788
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
757
789
  {
758
 
    cout << _("Error: Invalid Value for group_concat_max_len");
 
790
    cout << N_("Error: Invalid Value for group_concat_max_len");
759
791
    exit(-1);
760
792
  }
761
793
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
766
798
  global_system_variables.join_buff_size= (128*1024L);
767
799
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
768
800
  {
769
 
    cout << _("Error: Invalid Value for join_buffer_size");
 
801
    cout << N_("Error: Invalid Value for join_buffer_size");
770
802
    exit(-1);
771
803
  }
772
804
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
775
807
 
776
808
static void check_limits_map(uint32_t in_max_allowed_packet)
777
809
{
778
 
  global_system_variables.max_allowed_packet= (64*1024*1024L);
 
810
  global_system_variables.max_allowed_packet= (1024*1024L);
779
811
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
780
812
  {
781
 
    cout << _("Error: Invalid Value for max_allowed_packet");
 
813
    cout << N_("Error: Invalid Value for max_allowed_packet");
782
814
    exit(-1);
783
815
  }
784
816
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
785
817
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
786
818
}
787
819
 
 
820
static void check_limits_mce(uint64_t in_max_connect_errors)
 
821
{
 
822
  max_connect_errors= MAX_CONNECT_ERRORS;
 
823
  if (in_max_connect_errors < 1 || in_max_connect_errors > ULONG_MAX)
 
824
  {
 
825
    cout << N_("Error: Invalid Value for max_connect_errors");
 
826
    exit(-1);
 
827
  }
 
828
  max_connect_errors= in_max_connect_errors;
 
829
}
 
830
 
788
831
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
789
832
{
790
833
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
791
834
  if (in_max_error_count > 65535)
792
835
  {
793
 
    cout << _("Error: Invalid Value for max_error_count");
 
836
    cout << N_("Error: Invalid Value for max_error_count");
794
837
    exit(-1);
795
838
  }
796
839
  global_system_variables.max_error_count= in_max_error_count;
801
844
  global_system_variables.max_heap_table_size= (16*1024*1024L);
802
845
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
803
846
  {
804
 
    cout << _("Error: Invalid Value for max_heap_table_size");
 
847
    cout << N_("Error: Invalid Value for max_heap_table_size");
805
848
    exit(-1);
806
849
  }
807
850
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
813
856
  global_system_variables.min_examined_row_limit= 0;
814
857
  if (in_min_examined_row_limit > ULONG_MAX)
815
858
  {
816
 
    cout << _("Error: Invalid Value for min_examined_row_limit");
 
859
    cout << N_("Error: Invalid Value for min_examined_row_limit");
817
860
    exit(-1);
818
861
  }
819
862
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
824
867
  global_system_variables.max_join_size= INT32_MAX;
825
868
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
826
869
  {
827
 
    cout << _("Error: Invalid Value for max_join_size");
 
870
    cout << N_("Error: Invalid Value for max_join_size");
828
871
    exit(-1);
829
872
  }
830
873
  global_system_variables.max_join_size= in_max_join_size;
835
878
  global_system_variables.max_length_for_sort_data= 1024;
836
879
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
837
880
  {
838
 
    cout << _("Error: Invalid Value for max_length_for_sort_data");
 
881
    cout << N_("Error: Invalid Value for max_length_for_sort_data");
839
882
    exit(-1);
840
883
  }
841
884
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
846
889
  global_system_variables.max_seeks_for_key= ULONG_MAX;
847
890
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
848
891
  {
849
 
    cout << _("Error: Invalid Value for max_seeks_for_key");
 
892
    cout << N_("Error: Invalid Value for max_seeks_for_key");
850
893
    exit(-1);
851
894
  }
852
895
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
857
900
  global_system_variables.max_sort_length= 1024;
858
901
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
859
902
  {
860
 
    cout << _("Error: Invalid Value for max_sort_length");
 
903
    cout << N_("Error: Invalid Value for max_sort_length");
861
904
    exit(-1);
862
905
  }
863
906
  global_system_variables.max_sort_length= in_max_sort_length;
864
907
}
865
908
 
 
909
static void check_limits_mwlc(uint64_t in_min_examined_row_limit)
 
910
{
 
911
  global_system_variables.min_examined_row_limit= ULONG_MAX;
 
912
  if (in_min_examined_row_limit > ULONG_MAX)
 
913
  {
 
914
    cout << N_("Error: Invalid Value for min_examined_row_limit");
 
915
    exit(-1);
 
916
  }
 
917
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
 
918
}
 
919
 
866
920
static void check_limits_osd(uint32_t in_optimizer_search_depth)
867
921
{
868
922
  global_system_variables.optimizer_search_depth= 0;
869
923
  if (in_optimizer_search_depth > MAX_TABLES + 2)
870
924
  {
871
 
    cout << _("Error: Invalid Value for optimizer_search_depth");
 
925
    cout << N_("Error: Invalid Value for optimizer_search_depth");
872
926
    exit(-1);
873
927
  }
874
928
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
879
933
  global_system_variables.preload_buff_size= (32*1024L);
880
934
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
881
935
  {
882
 
    cout << _("Error: Invalid Value for preload_buff_size");
 
936
    cout << N_("Error: Invalid Value for preload_buff_size");
883
937
    exit(-1);
884
938
  }
885
939
  global_system_variables.preload_buff_size= in_preload_buff_size;
890
944
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
891
945
  if (in_query_alloc_block_size < 1024)
892
946
  {
893
 
    cout << _("Error: Invalid Value for query_alloc_block_size");
 
947
    cout << N_("Error: Invalid Value for query_alloc_block_size");
894
948
    exit(-1);
895
949
  }
896
950
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
902
956
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
903
957
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
904
958
  {
905
 
    cout << _("Error: Invalid Value for query_prealloc_size");
 
959
    cout << N_("Error: Invalid Value for query_prealloc_size");
906
960
    exit(-1);
907
961
  }
908
962
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
914
968
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
915
969
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
916
970
  {
917
 
    cout << _("Error: Invalid Value for range_alloc_block_size");
 
971
    cout << N_("Error: Invalid Value for range_alloc_block_size");
918
972
    exit(-1);
919
973
  }
920
974
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
926
980
  global_system_variables.read_buff_size= (128*1024L);
927
981
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
928
982
  {
929
 
    cout << _("Error: Invalid Value for read_buff_size");
 
983
    cout << N_("Error: Invalid Value for read_buff_size");
930
984
    exit(-1);
931
985
  }
932
986
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
938
992
  global_system_variables.read_rnd_buff_size= (256*1024L);
939
993
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
940
994
  {
941
 
    cout << _("Error: Invalid Value for read_rnd_buff_size");
 
995
    cout << N_("Error: Invalid Value for read_rnd_buff_size");
942
996
    exit(-1);
943
997
  }
944
998
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
949
1003
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
950
1004
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
951
1005
  {
952
 
    cout << _("Error: Invalid Value for sort_buff_size");
 
1006
    cout << N_("Error: Invalid Value for sort_buff_size");
953
1007
    exit(-1);
954
1008
  }
955
1009
  global_system_variables.sortbuff_size= in_sortbuff_size;
960
1014
  table_def_size= 128;
961
1015
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
962
1016
  {
963
 
    cout << _("Error: Invalid Value for table_def_size");
 
1017
    cout << N_("Error: Invalid Value for table_def_size");
964
1018
    exit(-1);
965
1019
  }
966
1020
  table_def_size= in_table_def_size;
971
1025
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
972
1026
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
973
1027
  {
974
 
    cout << _("Error: Invalid Value for table_cache_size");
 
1028
    cout << N_("Error: Invalid Value for table_cache_size");
975
1029
    exit(-1);
976
1030
  }
977
1031
  table_cache_size= in_table_cache_size;
982
1036
  table_lock_wait_timeout= 50;
983
1037
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
984
1038
  {
985
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
 
1039
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
986
1040
    exit(-1);
987
1041
  }
988
1042
  table_lock_wait_timeout= in_table_lock_wait_timeout;
998
1052
  global_system_variables.tmp_table_size= 16*1024*1024L;
999
1053
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
1000
1054
  {
1001
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
 
1055
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1002
1056
    exit(-1);
1003
1057
  }
1004
1058
  global_system_variables.tmp_table_size= in_tmp_table_size;
1005
1059
}
1006
1060
 
1007
 
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1008
 
{
1009
 
  transaction_message_threshold= 1024*1024;
1010
 
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1011
 
  {
1012
 
    cout << _("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1013
 
    exit(-1);
1014
 
  }
1015
 
  transaction_message_threshold= in_transaction_message_threshold;
 
1061
static pair<string, string> parse_size_suffixes(string s)
 
1062
{
 
1063
  size_t equal_pos= s.find("=");
 
1064
  if (equal_pos != string::npos)
 
1065
  {
 
1066
    string arg_key(s.substr(0, equal_pos));
 
1067
    string arg_val(s.substr(equal_pos+1));
 
1068
 
 
1069
    try
 
1070
    {
 
1071
      size_t size_suffix_pos= arg_val.find_last_of("kmgKMG");
 
1072
      if (size_suffix_pos == arg_val.size()-1)
 
1073
      {
 
1074
        char suffix= arg_val[size_suffix_pos];
 
1075
        string size_val(arg_val.substr(0, size_suffix_pos));
 
1076
 
 
1077
        uint64_t base_size= boost::lexical_cast<uint64_t>(size_val);
 
1078
        uint64_t new_size= 0;
 
1079
 
 
1080
        switch (suffix)
 
1081
        {
 
1082
        case 'K':
 
1083
        case 'k':
 
1084
          new_size= base_size * 1024;
 
1085
          break;
 
1086
        case 'M':
 
1087
        case 'm':
 
1088
          new_size= base_size * 1024 * 1024;
 
1089
          break;
 
1090
        case 'G':
 
1091
        case 'g':
 
1092
          new_size= base_size * 1024 * 1024 * 1024;
 
1093
          break;
 
1094
        }
 
1095
        return make_pair(arg_key,
 
1096
                         boost::lexical_cast<string>(new_size));
 
1097
      }
 
1098
    }
 
1099
    catch (...)
 
1100
    {
 
1101
      /* Screw it, let the normal parser take over */
 
1102
    }
 
1103
  }
 
1104
 
 
1105
  return make_pair(string(""), string(""));
 
1106
}
 
1107
 
 
1108
static pair<string, string> parse_size_arg(string s)
 
1109
{
 
1110
  if (s.find("--") == 0)
 
1111
  {
 
1112
    return parse_size_suffixes(s.substr(2));
 
1113
  }
 
1114
  return make_pair(string(""), string(""));
1016
1115
}
1017
1116
 
1018
1117
static void process_defaults_files()
1021
1120
       iter != defaults_file_list.end();
1022
1121
       ++iter)
1023
1122
  {
1024
 
    fs::path file_location= *iter;
 
1123
    string file_location(vm["config-dir"].as<string>());
 
1124
    if ((*iter)[0] != '/')
 
1125
    {
 
1126
      /* Relative path - add config dir */
 
1127
      file_location.push_back('/');
 
1128
      file_location.append(*iter);
 
1129
    }
 
1130
    else
 
1131
    {
 
1132
      file_location= *iter;
 
1133
    }
1025
1134
 
1026
 
    ifstream input_defaults_file(file_location.file_string().c_str());
 
1135
    ifstream input_defaults_file(file_location.c_str());
1027
1136
    
1028
1137
    po::parsed_options file_parsed=
1029
 
      dpo::parse_config_file(input_defaults_file, full_options, true);
 
1138
      po::parse_config_file(input_defaults_file, full_options, true);
1030
1139
    vector<string> file_unknown= 
1031
1140
      po::collect_unrecognized(file_parsed.options, po::include_positional);
1032
1141
 
1061
1170
       it != in_options.end();
1062
1171
       ++it)
1063
1172
  {
1064
 
    fs::path p(*it);
1065
 
    if (fs::is_regular_file(p))
1066
 
      defaults_file_list.push_back(*it);
1067
 
    else
1068
 
    {
1069
 
      errmsg_printf(error::ERROR,
1070
 
                  _("Defaults file '%s' not found\n"), (*it).c_str());
1071
 
      unireg_abort(1);
1072
 
    }
1073
 
 
 
1173
    defaults_file_list.push_back(*it);
1074
1174
  }
1075
1175
}
1076
1176
 
1077
 
int init_basic_variables(int argc, char **argv)
 
1177
int init_common_variables(int argc, char **argv, module::Registry &plugins)
1078
1178
{
1079
1179
  time_t curr_time;
1080
1180
  umask(((~internal::my_umask) & 0666));
1081
 
  decimal_zero.set_zero(); // set decimal_zero constant;
 
1181
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1082
1182
  tzset();                      // Set tzname
1083
1183
 
1084
1184
  curr_time= time(NULL);
1091
1191
  drizzle_init_variables();
1092
1192
 
1093
1193
  find_plugin_dir(argv[0]);
 
1194
  {
 
1195
    struct tm tm_tmp;
 
1196
    localtime_r(&server_start_time,&tm_tmp);
 
1197
    strncpy(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
 
1198
            sizeof(system_time_zone)-1);
1094
1199
 
 
1200
  }
1095
1201
  /*
1096
1202
    We set SYSTEM time zone as reasonable default and
1097
1203
    also for failure of my_tz_init() and bootstrap mode.
1100
1206
  */
1101
1207
  global_system_variables.time_zone= my_tz_SYSTEM;
1102
1208
 
1103
 
  char ret_hostname[FN_REFLEN];
1104
 
  if (gethostname(ret_hostname,sizeof(ret_hostname)) < 0)
 
1209
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
1105
1210
  {
1106
 
    errmsg_printf(error::WARN,
1107
 
                  _("gethostname failed, using '%s' as hostname"),
1108
 
                  getServerHostname().c_str());
1109
 
    pid_file= "drizzle";
 
1211
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
 
1212
    errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
 
1213
                  glob_hostname);
 
1214
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1110
1215
  }
1111
1216
  else
1112
 
  {
1113
 
    setServerHostname(ret_hostname);
1114
 
    pid_file= getServerHostname();
1115
 
  }
1116
 
  pid_file.replace_extension(".pid");
1117
 
 
1118
 
  system_config_dir /= "drizzle";
 
1217
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
1218
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
 
1219
 
 
1220
  std::string system_config_dir_drizzle(SYSCONFDIR);
 
1221
  system_config_dir_drizzle.append("/drizzle");
 
1222
 
 
1223
  std::string system_config_file_drizzle("drizzled.cnf");
1119
1224
 
1120
1225
  config_options.add_options()
1121
1226
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1122
 
  _("Display this help and exit."))
1123
 
  ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
1124
 
  _("Run as a daemon."))
 
1227
  N_("Display this help and exit."))
1125
1228
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1126
 
  _("Configuration file defaults are not used if no-defaults is set"))
 
1229
  N_("Configuration file defaults are not used if no-defaults is set"))
1127
1230
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1128
 
  _("Configuration file to use"))
1129
 
  ("config-dir", po::value<fs::path>(&system_config_dir),
1130
 
  _("Base location for config files"))
1131
 
  ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(&notify_plugin_dir),
1132
 
  _("Directory for plugins."))
 
1231
   N_("Configuration file to use"))
 
1232
  ("config-dir", po::value<string>()->default_value(system_config_dir_drizzle),
 
1233
   N_("Base location for config files"))
 
1234
  ("plugin-dir", po::value<string>()->notifier(&notify_plugin_dir),
 
1235
  N_("Directory for plugins."))
1133
1236
  ;
1134
1237
 
1135
1238
  plugin_load_options.add_options()
1136
1239
  ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1137
 
  _("Optional comma separated list of plugins to load at startup in addition "
 
1240
  N_("Optional comma separated list of plugins to load at startup in addition "
1138
1241
     "to the default list of plugins. "
1139
1242
     "[for example: --plugin_add=crc32,logger_gearman]"))    
1140
1243
  ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1141
 
  _("Optional comma separated list of plugins to not load at startup. Effectively "
 
1244
  N_("Optional comma separated list of plugins to not load at startup. Effectively "
1142
1245
     "removes a plugin from the list of plugins to be loaded. "
1143
1246
     "[for example: --plugin_remove=crc32,logger_gearman]"))
1144
1247
  ("plugin-load", po::value<string>()->notifier(&notify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1145
 
  _("Optional comma separated list of plugins to load at starup instead of "
 
1248
  N_("Optional comma separated list of plugins to load at starup instead of "
1146
1249
     "the default plugin load list. "
1147
1250
     "[for example: --plugin_load=crc32,logger_gearman]"))
1148
1251
  ;
1149
1252
 
1150
1253
  long_options.add_options()
1151
1254
  ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1152
 
  _("Auto-increment columns are incremented by this"))
 
1255
  N_("Auto-increment columns are incremented by this"))
1153
1256
  ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1154
 
  _("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1155
 
  ("basedir,b", po::value<fs::path>(&basedir),
1156
 
  _("Path to installation directory. All paths are usually resolved "
 
1257
  N_("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
 
1258
  ("basedir,b", po::value<string>(),
 
1259
  N_("Path to installation directory. All paths are usually resolved "
1157
1260
     "relative to this."))
1158
1261
  ("chroot,r", po::value<string>(),
1159
 
  _("Chroot drizzled daemon during startup."))
 
1262
  N_("Chroot drizzled daemon during startup."))
1160
1263
  ("collation-server", po::value<string>(),
1161
 
  _("Set the default collation."))      
 
1264
  N_("Set the default collation."))      
1162
1265
  ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1163
 
  _("Default completion type."))
1164
 
  ("core-file",  _("Write core on errors."))
1165
 
  ("datadir", po::value<fs::path>(&getDataHome()),
1166
 
  _("Path to the database root."))
 
1266
  N_("Default completion type."))
 
1267
  ("core-file",  N_("Write core on errors."))
 
1268
  ("datadir", po::value<string>(),
 
1269
  N_("Path to the database root."))
1167
1270
  ("default-storage-engine", po::value<string>(),
1168
 
  _("Set the default storage engine for tables."))
 
1271
  N_("Set the default storage engine for tables."))
1169
1272
  ("default-time-zone", po::value<string>(),
1170
 
  _("Set the default time zone."))
 
1273
  N_("Set the default time zone."))
1171
1274
  ("exit-info,T", po::value<long>(),
1172
 
  _("Used for debugging;  Use at your own risk!"))
 
1275
  N_("Used for debugging;  Use at your own risk!"))
1173
1276
  ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1174
 
  _("Set up signals usable for debugging"))
 
1277
  N_("Set up signals usable for debugging"))
1175
1278
  ("lc-time-name", po::value<string>(),
1176
 
  _("Set the language used for the month names and the days of the week."))
1177
 
  ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1178
 
  _("Log some not critical warnings to the log file."))  
1179
 
  ("pid-file", po::value<fs::path>(&pid_file),
1180
 
  _("Pid file used by drizzled."))
 
1279
  N_("Set the language used for the month names and the days of the week."))
 
1280
  ("log-warnings,W", po::value<string>(),
 
1281
  N_("Log some not critical warnings to the log file."))  
 
1282
  ("pid-file", po::value<string>(),
 
1283
  N_("Pid file used by drizzled."))
1181
1284
  ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1182
 
  _("Maximum time in seconds to wait for the port to become free. "))
1183
 
  ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1184
 
  _("Include the SQL query in replicated protobuf messages."))
1185
 
  ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1186
 
  _("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
 
1285
  N_("Maximum time in seconds to wait for the port to become free. "))
 
1286
  ("secure-file-priv", po::value<string>(),
 
1287
  N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1187
1288
     "within specified directory"))
1188
1289
  ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1189
 
  _("Uniquely identifies the server instance in the community of "
 
1290
  N_("Uniquely identifies the server instance in the community of "
1190
1291
     "replication partners."))
1191
1292
  ("skip-stack-trace",  
1192
 
  _("Don't print a stack trace on failure."))
 
1293
  N_("Don't print a stack trace on failure."))
1193
1294
  ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1194
 
  _("Enable symbolic link support."))
 
1295
  N_("Enable symbolic link support."))
1195
1296
  ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1196
 
  _("Specify whether to time mutexes (only InnoDB mutexes are currently "
 
1297
  N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1197
1298
     "supported)")) 
1198
1299
  ("tmpdir,t", po::value<string>(),
1199
 
  _("Path for temporary files."))
 
1300
  N_("Path for temporary files."))
1200
1301
  ("transaction-isolation", po::value<string>(),
1201
 
  _("Default transaction isolation level."))
1202
 
  ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1203
 
  _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
 
1302
  N_("Default transaction isolation level."))
1204
1303
  ("user,u", po::value<string>(),
1205
 
  _("Run drizzled daemon as user."))  
 
1304
  N_("Run drizzled daemon as user."))  
1206
1305
  ("version,V", 
1207
 
  _("Output version information and exit."))
1208
 
  ("back-log", po::value<back_log_constraints>(&back_log),
1209
 
  _("The number of outstanding connection requests Drizzle can have. This "
 
1306
  N_("Output version information and exit."))
 
1307
  ("back-log", po::value<uint32_t>(&back_log)->default_value(50)->notifier(&check_limits_back_log),
 
1308
  N_("The number of outstanding connection requests Drizzle can have. This "
1210
1309
     "comes into play when the main Drizzle thread gets very many connection "
1211
1310
     "requests in a very short time."))
1212
1311
  ("bulk-insert-buffer-size", 
1213
1312
  po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1214
 
  _("Size of tree cache used in bulk insert optimization. Note that this is "
 
1313
  N_("Size of tree cache used in bulk insert optimization. Note that this is "
1215
1314
     "a limit per thread!"))
1216
1315
  ("div-precision-increment",  po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1217
 
  _("Precision of the result of '/' operator will be increased on that "
 
1316
  N_("Precision of the result of '/' operator will be increased on that "
1218
1317
     "value."))
1219
1318
  ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1220
 
  _("The maximum length of the result of function  group_concat."))
 
1319
  N_("The maximum length of the result of function  group_concat."))
1221
1320
  ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1222
 
  _("The size of the buffer that is used for full joins."))
1223
 
  ("join-heap-threshold",
1224
 
  po::value<uint64_t>()->default_value(0),
1225
 
  _("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1226
 
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1227
 
  _("Max packetlength to send/receive from to server."))
 
1321
  N_("The size of the buffer that is used for full joins."))
 
1322
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(1024*1024L)->notifier(&check_limits_map),
 
1323
  N_("Max packetlength to send/receive from to server."))
 
1324
  ("max-connect-errors", po::value<uint64_t>(&max_connect_errors)->default_value(MAX_CONNECT_ERRORS)->notifier(&check_limits_mce),
 
1325
  N_("If there is more than this number of interrupted connections from a "
 
1326
     "host this host will be blocked from further connections."))
1228
1327
  ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1229
 
  _("Max number of errors/warnings to store for a statement."))
 
1328
  N_("Max number of errors/warnings to store for a statement."))
1230
1329
  ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1231
 
  _("Don't allow creation of heap tables bigger than this."))
 
1330
  N_("Don't allow creation of heap tables bigger than this."))
1232
1331
  ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1233
 
  _("Joins that are probably going to read more than max_join_size records "
 
1332
  N_("Joins that are probably going to read more than max_join_size records "
1234
1333
     "return an error."))
1235
1334
  ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1236
 
  _("Max number of bytes in sorted records."))
 
1335
  N_("Max number of bytes in sorted records."))
1237
1336
  ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1238
 
  _("Limit assumed max number of seeks when looking up rows based on a key"))
 
1337
  N_("Limit assumed max number of seeks when looking up rows based on a key"))
1239
1338
  ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),  
1240
 
  _("The number of bytes to use when sorting BLOB or TEXT values "
 
1339
  N_("The number of bytes to use when sorting BLOB or TEXT values "
1241
1340
     "(only the first max_sort_length bytes of each value are used; the "
1242
1341
     "rest are ignored)."))
1243
 
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1244
 
  _("After this many write locks, allow some read locks to run in between."))
 
1342
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(ULONG_MAX)->notifier(&check_limits_mwlc),
 
1343
  N_("After this many write locks, allow some read locks to run in between."))
1245
1344
  ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1246
 
  _("Don't log queries which examine less than min_examined_row_limit "
 
1345
  N_("Don't log queries which examine less than min_examined_row_limit "
1247
1346
     "rows to file."))
1248
1347
  ("disable-optimizer-prune",
1249
 
  _("Do not apply any heuristic(s) during query optimization to prune, "
 
1348
  N_("Do not apply any heuristic(s) during query optimization to prune, "
1250
1349
     "thus perform an exhaustive search from the optimizer search space."))
1251
1350
  ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1252
 
  _("Maximum depth of search performed by the query optimizer. Values "
 
1351
  N_("Maximum depth of search performed by the query optimizer. Values "
1253
1352
     "larger than the number of relations in a query result in better query "
1254
1353
     "plans, but take longer to compile a query. Smaller values than the "
1255
1354
     "number of tables in a relation result in faster optimization, but may "
1258
1357
     "optimizer will switch to the original find_best (used for "
1259
1358
     "testing/comparison)."))
1260
1359
  ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1261
 
  _("The size of the buffer that is allocated when preloading indexes"))
 
1360
  N_("The size of the buffer that is allocated when preloading indexes"))
1262
1361
  ("query-alloc-block-size", 
1263
1362
  po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1264
 
  _("Allocation block size for query parsing and execution"))
 
1363
  N_("Allocation block size for query parsing and execution"))
1265
1364
  ("query-prealloc-size",
1266
1365
  po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1267
 
  _("Persistent buffer for query parsing and execution"))
 
1366
  N_("Persistent buffer for query parsing and execution"))
1268
1367
  ("range-alloc-block-size",
1269
1368
  po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1270
 
  _("Allocation block size for storing ranges during optimization"))
 
1369
  N_("Allocation block size for storing ranges during optimization"))
1271
1370
  ("read-buffer-size",
1272
1371
  po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1273
 
  _("Each thread that does a sequential scan allocates a buffer of this "
 
1372
  N_("Each thread that does a sequential scan allocates a buffer of this "
1274
1373
      "size for each table it scans. If you do many sequential scans, you may "
1275
1374
      "want to increase this value."))
1276
 
  ("read-buffer-threshold",
1277
 
  po::value<uint64_t>()->default_value(0),
1278
 
  _("A global cap on the size of read-buffer-size (0 means unlimited)"))
1279
1375
  ("read-rnd-buffer-size",
1280
1376
  po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1281
 
  _("When reading rows in sorted order after a sort, the rows are read "
 
1377
  N_("When reading rows in sorted order after a sort, the rows are read "
1282
1378
     "through this buffer to avoid a disk seeks. If not set, then it's set "
1283
1379
     "to the value of record_buffer."))
1284
 
  ("read-rnd-threshold",
1285
 
  po::value<uint64_t>()->default_value(0),
1286
 
  _("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1287
1380
  ("scheduler", po::value<string>(),
1288
 
  _("Select scheduler to be used (by default multi-thread)."))
 
1381
  N_("Select scheduler to be used (by default multi-thread)."))
1289
1382
  ("sort-buffer-size",
1290
1383
  po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1291
 
  _("Each thread that needs to do a sort allocates a buffer of this size."))
1292
 
  ("sort-heap-threshold",
1293
 
  po::value<uint64_t>()->default_value(0),
1294
 
  _("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
 
1384
  N_("Each thread that needs to do a sort allocates a buffer of this size."))
1295
1385
  ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1296
 
  _("The number of cached table definitions."))
 
1386
  N_("The number of cached table definitions."))
1297
1387
  ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1298
 
  _("The number of cached open tables."))
 
1388
  N_("The number of cached open tables."))
1299
1389
  ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1300
 
  _("Timeout in seconds to wait for a table level lock before returning an "
 
1390
  N_("Timeout in seconds to wait for a table level lock before returning an "
1301
1391
     "error. Used only if the connection has active cursors."))
1302
1392
  ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1303
 
  _("The stack size for each thread."))
 
1393
  N_("The stack size for each thread."))
1304
1394
  ("tmp-table-size", 
1305
1395
  po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1306
 
  _("If an internal in-memory temporary table exceeds this size, Drizzle will"
 
1396
  N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1307
1397
     " automatically convert it to an on-disk MyISAM table."))
1308
 
  ("verbose", po::value<std::string>()->default_value(error::verbose_string())->notifier(&error::check_verbosity),
1309
 
  _("The stack size for each thread."))
1310
1398
  ;
1311
1399
 
1312
1400
  full_options.add(long_options);
1326
1414
  {
1327
1415
    po::store(parsed, vm);
1328
1416
  }
1329
 
  catch (std::exception&)
 
1417
  catch (...)
1330
1418
  {
1331
 
    errmsg_printf(error::ERROR, _("Duplicate entry for command line option\n"));
 
1419
    errmsg_printf(ERRMSG_LVL_ERROR, _("Duplicate entry for command line option\n"));
1332
1420
    unireg_abort(1);
1333
1421
  }
1334
1422
 
1335
1423
  if (not vm["no-defaults"].as<bool>())
1336
1424
  {
1337
 
    fs::path system_config_file_drizzle(system_config_dir);
1338
 
    system_config_file_drizzle /= "drizzled.cnf";
1339
1425
    defaults_file_list.insert(defaults_file_list.begin(),
1340
 
                              system_config_file_drizzle.file_string());
1341
 
 
1342
 
    fs::path config_conf_d_location(system_config_dir);
1343
 
    config_conf_d_location /= "conf.d";
1344
 
 
1345
 
 
1346
 
    CachedDirectory config_conf_d(config_conf_d_location.file_string());
1347
 
    if (not config_conf_d.fail())
 
1426
                              system_config_file_drizzle);
 
1427
  }
 
1428
 
 
1429
  string config_conf_d_location(vm["config-dir"].as<string>());
 
1430
  config_conf_d_location.append("/conf.d");
 
1431
  CachedDirectory config_conf_d(config_conf_d_location);
 
1432
  if (not config_conf_d.fail())
 
1433
  {
 
1434
 
 
1435
    for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
 
1436
         iter != config_conf_d.getEntries().end();
 
1437
         ++iter)
1348
1438
    {
1349
 
 
1350
 
      for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1351
 
           iter != config_conf_d.getEntries().end();
1352
 
           ++iter)
 
1439
      string file_entry((*iter)->filename);
 
1440
          
 
1441
      if (not file_entry.empty()
 
1442
          && file_entry != "."
 
1443
          && file_entry != "..")
1353
1444
      {
1354
 
        string file_entry((*iter)->filename);
1355
 
 
1356
 
        if (not file_entry.empty()
1357
 
            && file_entry != "."
1358
 
            && file_entry != "..")
1359
 
        {
1360
 
          fs::path the_entry(config_conf_d_location);
1361
 
          the_entry /= file_entry;
1362
 
          defaults_file_list.push_back(the_entry.file_string());
1363
 
        }
 
1445
        string the_entry(config_conf_d_location);
 
1446
        the_entry.push_back('/');
 
1447
        the_entry.append(file_entry);
 
1448
        defaults_file_list.push_back(the_entry);
1364
1449
      }
1365
1450
    }
1366
1451
  }
1367
1452
 
 
1453
  process_defaults_files();
1368
1454
  /* TODO: here is where we should add a process_env_vars */
1369
1455
 
1370
1456
  /* We need a notify here so that plugin_init will work properly */
1371
 
  try
1372
 
  {
1373
 
    po::notify(vm);
1374
 
  }
1375
 
  catch (po::validation_error &err)
1376
 
  {
1377
 
    errmsg_printf(error::ERROR,  
1378
 
                  _("%s: %s.\n"
1379
 
                    "Use --help to get a list of available options\n"),
1380
 
                  internal::my_progname, err.what());
1381
 
    unireg_abort(1);
1382
 
  }
1383
 
 
1384
 
  process_defaults_files();
1385
 
 
1386
 
  /* Process with notify a second time because a config file may contain
1387
 
     plugin loader options */
1388
 
 
1389
 
  try
1390
 
  {
1391
 
    po::notify(vm);
1392
 
  }
1393
 
  catch (po::validation_error &err)
1394
 
  {
1395
 
    errmsg_printf(error::ERROR,
1396
 
                  _("%s: %s.\n"
1397
 
                    "Use --help to get a list of available options\n"),
1398
 
                  internal::my_progname, err.what());
1399
 
    unireg_abort(1);
1400
 
  }
1401
 
 
1402
 
  return 0;
1403
 
}
1404
 
 
1405
 
int init_remaining_variables(module::Registry &plugins)
1406
 
{
1407
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1408
 
 
1409
 
  current_pid= getpid();                /* Save for later ref */
1410
 
 
 
1457
  po::notify(vm);
1411
1458
  /* At this point, we've read all the options we need to read from files and
1412
1459
     collected most of them into unknown options - now let's load everything
1413
1460
  */
1414
1461
 
1415
1462
  if (plugin_init(plugins, plugin_options))
1416
1463
  {
1417
 
    errmsg_printf(error::ERROR, _("Failed to initialize plugins\n"));
 
1464
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins\n"));
1418
1465
    unireg_abort(1);
1419
1466
  }
1420
1467
 
1425
1472
  {
1426
1473
    po::parsed_options final_parsed=
1427
1474
      po::command_line_parser(unknown_options).style(style).
1428
 
      options(full_options).extra_parser(dpo::parse_size_arg).run();
 
1475
      options(full_options).extra_parser(parse_size_arg).run();
1429
1476
 
1430
1477
    final_unknown_options=
1431
1478
      po::collect_unrecognized(final_parsed.options, po::include_positional);
1433
1480
    po::store(final_parsed, vm);
1434
1481
 
1435
1482
  }
1436
 
  catch (po::validation_error &err)
1437
 
  {
1438
 
    errmsg_printf(error::ERROR,
1439
 
                  _("%s: %s.\n"
1440
 
                    "Use --help to get a list of available options\n"),
1441
 
                  internal::my_progname, err.what());
1442
 
    unireg_abort(1);
1443
 
  }
1444
1483
  catch (po::invalid_command_line_syntax &err)
1445
1484
  {
1446
 
    errmsg_printf(error::ERROR,
 
1485
    errmsg_printf(ERRMSG_LVL_ERROR,
1447
1486
                  _("%s: %s.\n"
1448
1487
                    "Use --help to get a list of available options\n"),
1449
1488
                  internal::my_progname, err.what());
1451
1490
  }
1452
1491
  catch (po::unknown_option &err)
1453
1492
  {
1454
 
    errmsg_printf(error::ERROR,
 
1493
    errmsg_printf(ERRMSG_LVL_ERROR,
1455
1494
                  _("%s\nUse --help to get a list of available options\n"),
1456
1495
                  err.what());
1457
1496
    unireg_abort(1);
1458
1497
  }
1459
1498
 
1460
 
  try
1461
 
  {
1462
 
    po::notify(vm);
1463
 
  }
1464
 
  catch (po::validation_error &err)
1465
 
  {
1466
 
    errmsg_printf(error::ERROR,  
1467
 
                  _("%s: %s.\n"
1468
 
                    "Use --help to get a list of available options\n"),
1469
 
                  internal::my_progname, err.what());
1470
 
    unireg_abort(1);
1471
 
  }
 
1499
  po::notify(vm);
1472
1500
 
1473
1501
  get_options();
1474
1502
 
1487
1515
 
1488
1516
  fix_paths();
1489
1517
 
 
1518
  current_pid= getpid();                /* Save for later ref */
1490
1519
  init_time();                          /* Init time-functions (read zone) */
1491
1520
 
1492
1521
  if (item_create_init())
1493
1522
    return 1;
1494
 
  if (sys_var_init())
 
1523
  if (set_var_init())
1495
1524
    return 1;
1496
1525
  /* Creates static regex matching for temporal values */
1497
1526
  if (! init_temporal_formats())
1500
1529
  if (!(default_charset_info=
1501
1530
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1502
1531
  {
1503
 
    errmsg_printf(error::ERROR, _("Error getting default charset"));
 
1532
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error getting default charset"));
1504
1533
    return 1;                           // Eof of the list
1505
1534
  }
1506
1535
 
1512
1541
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1513
1542
    if (not default_collation)
1514
1543
    {
1515
 
      errmsg_printf(error::ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
 
1544
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1516
1545
      return 1;
1517
1546
    }
1518
1547
    if (not my_charset_same(default_charset_info, default_collation))
1519
1548
    {
1520
 
      errmsg_printf(error::ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
 
1549
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1521
1550
                    default_collation_name,
1522
1551
                    default_charset_info->csname);
1523
1552
      return 1;
1530
1559
  if (not (character_set_filesystem=
1531
1560
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1532
1561
  {
1533
 
    errmsg_printf(error::ERROR, _("Error setting collation"));
 
1562
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error setting collation"));
1534
1563
    return 1;
1535
1564
  }
1536
1565
  global_system_variables.character_set_filesystem= character_set_filesystem;
1538
1567
  if (!(my_default_lc_time_names=
1539
1568
        my_locale_by_name(lc_time_names_name)))
1540
1569
  {
1541
 
    errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
 
1570
    errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1542
1571
    return 1;
1543
1572
  }
1544
1573
  global_system_variables.lc_time_names= my_default_lc_time_names;
1558
1587
  */
1559
1588
  if (table_cache_init())
1560
1589
  {
1561
 
    errmsg_printf(error::ERROR, _("Could not initialize table cache\n"));
 
1590
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not initialize table cache\n"));
1562
1591
    unireg_abort(1);
1563
1592
  }
1564
 
 
1565
 
  // Resize the definition Cache at startup
1566
 
  table::Cache::singleton().rehash(table_def_size);
1567
 
  definition::Cache::singleton().rehash(table_def_size);
1568
 
  message::Cache::singleton().rehash(table_def_size);
 
1593
  TableShare::cacheStart();
1569
1594
 
1570
1595
  setup_fpu();
1571
1596
 
1573
1598
 
1574
1599
  if (xid_cache_init())
1575
1600
  {
1576
 
    errmsg_printf(error::ERROR, _("XA cache initialization failed: Out of memory\n"));
 
1601
    errmsg_printf(ERRMSG_LVL_ERROR, _("XA cache initialization failed: Out of memory\n"));
1577
1602
    unireg_abort(1);
1578
1603
  }
1579
1604
 
1602
1627
 
1603
1628
  if (plugin::Scheduler::setPlugin(scheduler_name))
1604
1629
  {
1605
 
      errmsg_printf(error::ERROR,
 
1630
      errmsg_printf(ERRMSG_LVL_ERROR,
1606
1631
                   _("No scheduler found, cannot continue!\n"));
1607
1632
      unireg_abort(1);
1608
1633
  }
1627
1652
    engine= plugin::StorageEngine::findByName(name);
1628
1653
    if (engine == NULL)
1629
1654
    {
1630
 
      errmsg_printf(error::ERROR, _("Unknown/unsupported storage engine: %s\n"),
 
1655
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s\n"),
1631
1656
                    default_storage_engine_str);
1632
1657
      unireg_abort(1);
1633
1658
    }
1668
1693
  OPT_BACK_LOG,
1669
1694
  OPT_JOIN_BUFF_SIZE,
1670
1695
  OPT_MAX_ALLOWED_PACKET,
 
1696
  OPT_MAX_CONNECT_ERRORS,
1671
1697
  OPT_MAX_HEP_TABLE_SIZE,
1672
1698
  OPT_MAX_JOIN_SIZE,
1673
1699
  OPT_MAX_SORT_LENGTH,
1721
1747
  {"help", '?', N_("Display this help and exit."),
1722
1748
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1723
1749
   0, 0},
1724
 
  {"daemon", 'd', N_("Run as daemon."),
1725
 
   (char**) &opt_daemon, (char**) &opt_daemon, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1726
 
   0, 0},
1727
1750
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1728
1751
   N_("Auto-increment columns are incremented by this"),
1729
1752
   (char**) &global_system_variables.auto_increment_increment,
1730
1753
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1731
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
 
1754
   OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1732
1755
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1733
1756
   N_("Offset added to Auto-increment columns. Used when "
1734
1757
      "auto-increment-increment != 1"),
1735
1758
   (char**) &global_system_variables.auto_increment_offset,
1736
1759
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1737
 
   1, 1, INT64_MAX, 0, 1, 0 },
 
1760
   1, 1, UINT64_MAX, 0, 1, 0 },
1738
1761
  {"basedir", 'b',
1739
1762
   N_("Path to installation directory. All paths are usually resolved "
1740
1763
      "relative to this."),
1741
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
 
1764
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1742
1765
   0, 0, 0, 0, 0, 0},
1743
1766
  {"chroot", 'r',
1744
1767
   N_("Chroot drizzled daemon during startup."),
1760
1783
  {"datadir", 'h',
1761
1784
   N_("Path to the database root."),
1762
1785
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1786
  {"default-storage-engine", OPT_STORAGE_ENGINE,
 
1787
   N_("Set the default storage engine (table type) for tables."),
 
1788
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
 
1789
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1790
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE,
 
1791
   N_("Set the default time zone."),
 
1792
   (char**) &default_tz_name, (char**) &default_tz_name,
 
1793
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1763
1794
  /* See how it's handled in get_one_option() */
1764
1795
  {"exit-info", 'T',
1765
1796
   N_("Used for debugging;  Use at your own risk!"),
1770
1801
   N_("Set up signals usable for debugging"),
1771
1802
   (char**) &opt_debugging, (char**) &opt_debugging,
1772
1803
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1804
  {"lc-time-names", OPT_LC_TIME_NAMES,
 
1805
   N_("Set the language used for the month names and the days of the week."),
 
1806
   (char**) &lc_time_names_name,
 
1807
   (char**) &lc_time_names_name,
 
1808
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1773
1809
  {"log-warnings", 'W',
1774
1810
   N_("Log some not critical warnings to the log file."),
1775
1811
   (char**) &global_system_variables.log_warnings,
1777
1813
   0, 0, 0},
1778
1814
  {"pid-file", OPT_PID_FILE,
1779
1815
   N_("Pid file used by drizzled."),
1780
 
   NULL, NULL, 0, GET_STR,
 
1816
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1781
1817
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1782
1818
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1783
1819
   N_("Maximum time in seconds to wait for the port to become free. "
1787
1823
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1788
1824
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1789
1825
      "within specified directory"),
1790
 
   NULL, NULL, 0,
 
1826
   (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1791
1827
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1792
1828
  {"server-id", OPT_SERVER_ID,
1793
1829
   N_("Uniquely identifies the server instance in the community of "
1812
1848
      "supported)"),
1813
1849
   (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1814
1850
    0, 0, 0, 0, 0},
 
1851
  {"tmpdir", 't',
 
1852
   N_("Path for temporary files."),
 
1853
   (char**) &opt_drizzle_tmpdir,
 
1854
   (char**) &opt_drizzle_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1815
1855
  {"transaction-isolation", OPT_TX_ISOLATION,
1816
1856
   N_("Default transaction isolation level."),
1817
1857
   0, 0, 0, GET_STR, REQUIRED_ARG, 0,
1820
1860
   N_("Run drizzled daemon as user."),
1821
1861
   0, 0, 0, GET_STR, REQUIRED_ARG,
1822
1862
   0, 0, 0, 0, 0, 0},
 
1863
  {"version", 'V',
 
1864
   N_("Output version information and exit."),
 
1865
   0, 0, 0, GET_NO_ARG,
 
1866
   NO_ARG, 0, 0, 0, 0, 0, 0},
1823
1867
  {"back_log", OPT_BACK_LOG,
1824
1868
   N_("The number of outstanding connection requests Drizzle can have. This "
1825
1869
      "comes into play when the main Drizzle thread gets very many connection "
1838
1882
   (char**) &global_system_variables.div_precincrement,
1839
1883
   (char**) &max_system_variables.div_precincrement, 0, GET_UINT,
1840
1884
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
 
1885
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
 
1886
    N_("The maximum length of the result of function  group_concat."),
 
1887
    (char**) &global_system_variables.group_concat_max_len,
 
1888
    (char**) &max_system_variables.group_concat_max_len, 0, GET_UINT64,
 
1889
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
1841
1890
  { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
1842
1891
    N_("The size of the buffer that is used for full joins."),
1843
1892
   (char**) &global_system_variables.join_buff_size,
1848
1897
   N_("Max packetlength to send/receive from to server."),
1849
1898
   (char**) &global_system_variables.max_allowed_packet,
1850
1899
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1851
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1900
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1901
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
 
1902
   N_("If there is more than this number of interrupted connections from a "
 
1903
      "host this host will be blocked from further connections."),
 
1904
   (char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_UINT64,
 
1905
   REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
 
1906
  {"max_error_count", OPT_MAX_ERROR_COUNT,
 
1907
   N_("Max number of errors/warnings to store for a statement."),
 
1908
   (char**) &global_system_variables.max_error_count,
 
1909
   (char**) &max_system_variables.max_error_count,
 
1910
   0, GET_UINT64, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
1852
1911
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
1853
1912
   N_("Don't allow creation of heap tables bigger than this."),
1854
1913
   (char**) &global_system_variables.max_heap_table_size,
1855
1914
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1856
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
 
1915
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1857
1916
   MALLOC_OVERHEAD, 1024, 0},
1858
1917
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1859
1918
   N_("Joins that are probably going to read more than max_join_size records "
1950
2009
   N_("Allocation block size for storing ranges during optimization"),
1951
2010
   (char**) &global_system_variables.range_alloc_block_size,
1952
2011
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
1953
 
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
 
2012
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
1954
2013
   0, 1024, 0},
1955
2014
  {"read_buffer_size", OPT_RECORD_BUFFER,
1956
2015
    N_("Each thread that does a sequential scan allocates a buffer of this "
1968
2027
   (char**) &max_system_variables.read_rnd_buff_size, 0,
1969
2028
   GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
1970
2029
   UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
 
2030
  {"scheduler", OPT_SCHEDULER,
 
2031
   N_("Select scheduler to be used (by default multi-thread)."),
 
2032
   (char**)&opt_scheduler, (char**)&opt_scheduler,
 
2033
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1971
2034
  /* x8 compared to MySQL's x2. We have UTF8 to consider. */
1972
2035
  {"sort_buffer_size", OPT_SORT_BUFFER,
1973
2036
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
1974
2037
   (char**) &global_system_variables.sortbuff_size,
1975
2038
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
1976
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
 
2039
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
1977
2040
   MALLOC_OVERHEAD, 1, 0},
1978
2041
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
1979
2042
   N_("The number of cached table definitions."),
1993
2056
   (char**) &my_thread_stack_size,
1994
2057
   (char**) &my_thread_stack_size, 0, GET_SIZE,
1995
2058
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
1996
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
 
2059
   UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
1997
2060
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
1998
2061
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1999
2062
      " automatically convert it to an on-disk MyISAM table."),
2000
2063
   (char**) &global_system_variables.tmp_table_size,
2001
2064
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2002
 
   REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
2065
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2003
2066
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2004
2067
};
2005
2068
 
2058
2121
static void drizzle_init_variables(void)
2059
2122
{
2060
2123
  /* Things reset to zero */
 
2124
  drizzle_home[0]= pidfile_name[0]= 0;
2061
2125
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
2126
  opt_secure_file_priv= 0;
2062
2127
  cleanup_done= 0;
2063
2128
  dropping_tables= ha_open_options=0;
2064
 
  getDebug().reset();
 
2129
  test_flags.reset();
2065
2130
  wake_thread=0;
2066
2131
  abort_loop= select_thread_in_use= false;
2067
 
  shutdown_in_progress= 0;
 
2132
  ready_to_exit= shutdown_in_progress= 0;
2068
2133
  drizzled_user= drizzled_chroot= 0;
2069
2134
  memset(&current_global_counters, 0, sizeof(current_global_counters));
2070
2135
  key_map_full.set();
2076
2141
  character_set_filesystem= &my_charset_bin;
2077
2142
 
2078
2143
  /* Things with default values that are not zero */
 
2144
  drizzle_home_ptr= drizzle_home;
 
2145
  pidfile_name_ptr= pidfile_name;
2079
2146
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2080
2147
  refresh_version= 1L;  /* Increments on each reload */
2081
2148
  global_thread_id= 1UL;
2082
 
  session::Cache::singleton().getCache().clear();
 
2149
  getSessionList().clear();
2083
2150
 
2084
2151
  /* Variables in libraries */
2085
2152
  default_character_set_name= "utf8";
2097
2164
  max_system_variables.auto_increment_increment= UINT64_MAX;
2098
2165
  max_system_variables.auto_increment_offset= UINT64_MAX;
2099
2166
  max_system_variables.completion_type= 2;
2100
 
  max_system_variables.log_warnings= true;
 
2167
  max_system_variables.log_warnings= 1;
2101
2168
  max_system_variables.bulk_insert_buff_size= ULONG_MAX;
2102
2169
  max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
2103
2170
  max_system_variables.group_concat_max_len= ULONG_MAX;
2129
2196
#else
2130
2197
  have_symlink=SHOW_OPTION_YES;
2131
2198
#endif
 
2199
 
 
2200
  const char *tmpenv;
 
2201
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
2202
    tmpenv = PREFIX;
 
2203
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
 
2204
  
 
2205
  connection_count= 0;
2132
2206
}
2133
2207
 
2134
2208
 
2139
2213
static void get_options()
2140
2214
{
2141
2215
 
2142
 
  fs::path &data_home_catalog= getDataHomeCatalog();
 
2216
  if (vm.count("base-dir"))
 
2217
  {
 
2218
    strncpy(drizzle_home,vm["base-dir"].as<string>().c_str(),sizeof(drizzle_home)-1);
 
2219
  }
 
2220
 
 
2221
  if (vm.count("datadir"))
 
2222
  {
 
2223
    getDataHome()= vm["datadir"].as<string>();
 
2224
  }
 
2225
  string &data_home_catalog= getDataHomeCatalog();
2143
2226
  data_home_catalog= getDataHome();
2144
 
  data_home_catalog /= "local"; 
 
2227
  data_home_catalog.push_back('/');
 
2228
  data_home_catalog.append("local");
2145
2229
 
2146
2230
  if (vm.count("user"))
2147
2231
  {
2149
2233
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2150
2234
 
2151
2235
    else
2152
 
      errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was "
 
2236
      errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
2153
2237
                                       "set to '%s' earlier on the command line\n"),
2154
2238
                    vm["user"].as<string>().c_str(), drizzled_user);
2155
2239
  }
2160
2244
    exit(0);
2161
2245
  }
2162
2246
 
2163
 
  if (vm.count("sort-heap-threshold"))
2164
 
  {
2165
 
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2166
 
      (vm["sort-heap-threshold"].as<uint64_t>() < 
2167
 
      global_system_variables.sortbuff_size))
2168
 
    {
2169
 
      cout << _("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2170
 
      exit(-1);
2171
 
    }
2172
 
 
2173
 
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2174
 
  }
2175
 
 
2176
 
  if (vm.count("join-heap-threshold"))
2177
 
  {
2178
 
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2179
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2180
 
      global_system_variables.join_buff_size))
2181
 
    {
2182
 
      cout << _("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2183
 
      exit(-1);
2184
 
    }
2185
 
 
2186
 
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2187
 
  }
2188
 
 
2189
 
  if (vm.count("read-rnd-threshold"))
2190
 
  {
2191
 
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2192
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2193
 
      global_system_variables.read_rnd_buff_size))
2194
 
    {
2195
 
      cout << _("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2196
 
      exit(-1);
2197
 
    }
2198
 
 
2199
 
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2200
 
  }
2201
 
 
2202
 
  if (vm.count("read-buffer-threshold"))
2203
 
  {
2204
 
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2205
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2206
 
      global_system_variables.read_buff_size))
2207
 
    {
2208
 
      cout << _("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2209
 
      exit(-1);
2210
 
    }
2211
 
 
2212
 
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
 
2247
  if (vm.count("log-warnings"))
 
2248
  {
 
2249
    if (vm["log-warnings"].as<string>().empty())
 
2250
      global_system_variables.log_warnings++;
 
2251
    else if (vm["log-warnings"].as<string>().compare("0"))
 
2252
      global_system_variables.log_warnings= 0L;
 
2253
    else
 
2254
      global_system_variables.log_warnings= atoi(vm["log-warnings"].as<string>().c_str());
2213
2255
  }
2214
2256
 
2215
2257
  if (vm.count("exit-info"))
2216
2258
  {
2217
2259
    if (vm["exit-info"].as<long>())
2218
2260
    {
2219
 
      getDebug().set((uint32_t) vm["exit-info"].as<long>());
 
2261
      test_flags.set((uint32_t) vm["exit-info"].as<long>());
2220
2262
    }
2221
2263
  }
2222
2264
 
2223
2265
  if (vm.count("want-core"))
2224
2266
  {
2225
 
    getDebug().set(debug::CORE_ON_SIGNAL);
 
2267
    test_flags.set(TEST_CORE_ON_SIGNAL);
2226
2268
  }
2227
2269
 
2228
2270
  if (vm.count("skip-stack-trace"))
2229
2271
  {
2230
 
    getDebug().set(debug::NO_STACKTRACE);
 
2272
    test_flags.set(TEST_NO_STACKTRACE);
2231
2273
  }
2232
2274
 
2233
2275
  if (vm.count("skip-symlinks"))
2235
2277
    internal::my_use_symdir=0;
2236
2278
  }
2237
2279
 
 
2280
  if (vm.count("pid-file"))
 
2281
  {
 
2282
    strncpy(pidfile_name, vm["pid-file"].as<string>().c_str(), sizeof(pidfile_name)-1);
 
2283
  }
 
2284
 
2238
2285
  if (vm.count("transaction-isolation"))
2239
2286
  {
2240
 
    int type= tx_isolation_typelib.find_type_or_exit(vm["transaction-isolation"].as<string>().c_str(), "transaction-isolation");
2241
 
    global_system_variables.tx_isolation= type - 1;
 
2287
    int type;
 
2288
    type= find_type_or_exit((char *)vm["transaction-isolation"].as<string>().c_str(), &tx_isolation_typelib, "transaction-isolation");
 
2289
    global_system_variables.tx_isolation= (type-1);
2242
2290
  }
2243
2291
 
2244
2292
  /* @TODO Make this all strings */
2265
2313
  if (opt_debugging)
2266
2314
  {
2267
2315
    /* Allow break with SIGINT, no core or stack trace */
2268
 
    getDebug().set(debug::ALLOW_SIGINT);
2269
 
    getDebug().set(debug::NO_STACKTRACE);
2270
 
    getDebug().reset(debug::CORE_ON_SIGNAL);
 
2316
    test_flags.set(TEST_SIGINT);
 
2317
    test_flags.set(TEST_NO_STACKTRACE);
 
2318
    test_flags.reset(TEST_CORE_ON_SIGNAL);
2271
2319
  }
2272
2320
 
2273
2321
  if (drizzled_chroot)
2281
2329
}
2282
2330
 
2283
2331
 
 
2332
static const char *get_relative_path(const char *path)
 
2333
{
 
2334
  if (internal::test_if_hard_path(path) &&
 
2335
      (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
 
2336
      strcmp(PREFIX,FN_ROOTDIR))
 
2337
  {
 
2338
    if (strlen(PREFIX) < strlen(path))
 
2339
      path+=(size_t) strlen(PREFIX);
 
2340
    while (*path == FN_LIBCHAR)
 
2341
      path++;
 
2342
  }
 
2343
  return path;
 
2344
}
 
2345
 
 
2346
 
2284
2347
static void fix_paths()
2285
2348
{
2286
 
  fs::path pid_file_path(pid_file);
 
2349
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
 
2350
  internal::convert_dirname(drizzle_home,drizzle_home,NULL);
 
2351
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
 
2352
#if defined(HAVE_BROKEN_REALPATH)
 
2353
   internal::my_load_path(drizzle_home, drizzle_home, NULL);
 
2354
#else
 
2355
  if (!realpath(drizzle_home,rp_buff))
 
2356
    internal::my_load_path(rp_buff, drizzle_home, NULL);
 
2357
  rp_buff[FN_REFLEN-1]= '\0';
 
2358
  strcpy(drizzle_home,rp_buff);
 
2359
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
 
2360
  pos= strchr(drizzle_home, '\0');
 
2361
#endif
 
2362
  if (pos[-1] != FN_LIBCHAR)
 
2363
  {
 
2364
    pos[0]= FN_LIBCHAR;
 
2365
    pos[1]= 0;
 
2366
  }
 
2367
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
2368
 
 
2369
  fs::path pid_file_path(pidfile_name);
2287
2370
  if (pid_file_path.root_path().string() == "")
2288
2371
  {
2289
 
    pid_file_path= getDataHome();
2290
 
    pid_file_path /= pid_file;
2291
 
  }
2292
 
  pid_file= fs::system_complete(pid_file_path);
 
2372
    pid_file_path= fs::path(getDataHome());
 
2373
    pid_file_path /= pidfile_name;
 
2374
  }
 
2375
  strncpy(pidfile_name, pid_file_path.file_string().c_str(), sizeof(pidfile_name)-1);
 
2376
 
 
2377
 
 
2378
  const char *sharedir= get_relative_path(PKGDATADIR);
 
2379
  if (internal::test_if_hard_path(sharedir))
 
2380
    strncpy(buff,sharedir,sizeof(buff)-1);
 
2381
  else
 
2382
  {
 
2383
    strcpy(buff, drizzle_home);
 
2384
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
 
2385
  }
 
2386
  internal::convert_dirname(buff,buff,NULL);
2293
2387
 
2294
2388
  if (not opt_help)
2295
2389
  {
2303
2397
    }
2304
2398
    else if (tmp_string == NULL)
2305
2399
    {
2306
 
      drizzle_tmpdir.append(getDataHome().file_string());
 
2400
      drizzle_tmpdir.append(getDataHome());
2307
2401
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2308
2402
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2309
2403
    }
2319
2413
    {
2320
2414
      if (errno != EEXIST)
2321
2415
      {
2322
 
        errmsg_printf(error::ERROR, _("There was an error creating the '%s' part of the path '%s'.  Please check the path exists and is writable.\n"), fs::path(drizzle_tmpdir).leaf().c_str(), drizzle_tmpdir.c_str());
 
2416
        perror(drizzle_tmpdir.c_str());
2323
2417
        exit(1);
2324
2418
      }
2325
2419
    }
2326
2420
 
2327
2421
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
2328
2422
    {
2329
 
      errmsg_printf(error::ERROR, _("There was an error opening the path '%s', please check the path exists and is writable.\n"), drizzle_tmpdir.c_str());
 
2423
      perror(drizzle_tmpdir.c_str());
2330
2424
      exit(1);
2331
2425
    }
2332
2426
  }
2333
2427
 
 
2428
  /*
 
2429
    Convert the secure-file-priv option to system format, allowing
 
2430
    a quick strcmp to check if read or write is in an allowed dir
 
2431
   */
 
2432
  if (vm.count("secure-file-priv"))
 
2433
  {
 
2434
    internal::convert_dirname(buff, vm["secure-file-priv"].as<string>().c_str(), NULL);
 
2435
    free(opt_secure_file_priv);
 
2436
    opt_secure_file_priv= strdup(buff);
 
2437
    if (opt_secure_file_priv == NULL)
 
2438
      exit(1);
 
2439
  }
2334
2440
}
2335
2441
 
2336
2442
} /* namespace drizzled */