~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2010-04-22 02:46:23 UTC
  • mto: (1497.3.4 enable-dtrace)
  • mto: This revision was merged to the branch mainline in revision 1527.
  • Revision ID: mordred@inaugust.com-20100422024623-4urw8fi8eraci08p
Don't overwrite the pandora_vc_revinfo file if we don't have new
authoratative information.

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
18
18
 */
19
19
 
20
20
#include "config.h"
21
 
 
22
21
#include <drizzled/configmake.h>
23
22
#include <drizzled/atomics.h>
24
 
#include <drizzled/data_home.h>
25
23
 
26
24
#include <netdb.h>
27
25
#include <sys/types.h>
29
27
#include <netinet/in.h>
30
28
#include <signal.h>
31
29
#include <limits.h>
32
 
#include <stdexcept>
33
 
 
34
 
#include <boost/program_options.hpp>
35
 
#include <drizzled/program_options/config_file.h>
36
 
#include <boost/thread/recursive_mutex.hpp>
37
 
#include <boost/thread/mutex.hpp>
38
 
#include <boost/thread/shared_mutex.hpp>
39
 
#include <boost/thread/condition_variable.hpp>
40
 
#include <boost/filesystem.hpp>
41
 
#include <boost/detail/atomic_count.hpp>
42
 
 
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>
 
30
 
 
31
#include "drizzled/internal/my_sys.h"
 
32
#include "drizzled/internal/my_bit.h"
 
33
#include <drizzled/my_hash.h>
 
34
#include <drizzled/error.h>
49
35
#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>
 
36
#include <drizzled/tztime.h>
 
37
#include <drizzled/sql_base.h>
 
38
#include <drizzled/show.h>
 
39
#include <drizzled/sql_parse.h>
54
40
#include <drizzled/item/cmpfunc.h>
 
41
#include <drizzled/session.h>
55
42
#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
43
#include <drizzled/unireg.h>
78
 
#include <plugin/myisam/myisam.h>
79
 
 
80
 
#include "drizzled/visibility.h"
 
44
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
 
45
#include "drizzled/plugin/listen.h"
 
46
#include "drizzled/plugin/error_message.h"
 
47
#include "drizzled/plugin/client.h"
 
48
#include "drizzled/plugin/scheduler.h"
 
49
#include "drizzled/plugin/xa_resource_manager.h"
 
50
#include "drizzled/plugin/monitored_in_transaction.h"
 
51
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
 
52
#include "drizzled/probes.h"
 
53
#include "drizzled/session_list.h"
 
54
#include "drizzled/charset.h"
 
55
#include "plugin/myisam/myisam.h"
 
56
#include "drizzled/drizzled.h"
81
57
 
82
58
#include <google/protobuf/stubs/common.h>
83
59
 
84
 
#include <drizzled/refresh_version.h>
85
 
 
86
60
#if TIME_WITH_SYS_TIME
87
61
# include <sys/time.h>
88
62
# include <time.h>
137
111
#endif
138
112
 
139
113
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
140
 
#include "drizzled/constrained_value.h"
141
114
 
142
115
#include <drizzled/gettext.h>
143
116
 
144
117
 
145
 
#ifdef HAVE_VALGRIND
 
118
#ifdef HAVE_purify
146
119
#define IF_PURIFY(A,B) (A)
147
120
#else
148
121
#define IF_PURIFY(A,B) (B)
149
122
#endif
150
123
 
151
124
#define MAX_MEM_TABLE_SIZE SIZE_MAX
152
 
#include <iostream>
153
 
#include <fstream>
154
 
 
155
125
 
156
126
using namespace std;
157
 
namespace fs=boost::filesystem;
158
 
namespace po=boost::program_options;
159
 
namespace dpo=drizzled::program_options;
160
 
 
161
 
bool opt_daemon= false;
162
127
 
163
128
namespace drizzled
164
129
{
165
130
 
 
131
#define mysqld_charset &my_charset_utf8_general_ci
166
132
inline void setup_fpu()
167
133
{
168
134
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
196
162
extern "C" int gethostname(char *name, int namelen);
197
163
#endif
198
164
 
 
165
/* Constants */
 
166
static const char *tc_heuristic_recover_names[]=
 
167
{
 
168
  "COMMIT", "ROLLBACK", NULL
 
169
};
 
170
static TYPELIB tc_heuristic_recover_typelib=
 
171
{
 
172
  array_elements(tc_heuristic_recover_names)-1,"",
 
173
  tc_heuristic_recover_names, NULL
 
174
};
 
175
 
199
176
const char *first_keyword= "first";
200
177
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
201
 
 
202
178
#define GET_HA_ROWS GET_ULL
203
179
 
204
180
const char *tx_isolation_names[] =
212
188
  Used with --help for detailed option
213
189
*/
214
190
bool opt_help= false;
 
191
bool opt_help_extended= false;
215
192
 
216
193
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
217
194
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
222
199
 
223
200
/* static variables */
224
201
 
225
 
static bool opt_debugging= false;
 
202
static bool opt_debugging= 0;
226
203
static uint32_t wake_thread;
227
204
static char *drizzled_chroot;
 
205
static char *language_ptr;
228
206
static const char *default_character_set_name;
229
207
static const char *character_set_filesystem_name;
230
208
static char *lc_time_names_name;
234
212
 
235
213
/* Global variables */
236
214
 
 
215
bool volatile ready_to_exit;
237
216
char *drizzled_user;
238
217
bool volatile select_thread_in_use;
239
218
bool volatile abort_loop;
240
 
DRIZZLED_API bool volatile shutdown_in_progress;
241
 
char *opt_scheduler_default;
242
 
const char *opt_scheduler= NULL;
 
219
bool volatile shutdown_in_progress;
 
220
uint32_t max_used_connections;
 
221
const string opt_scheduler_default("multi_thread");
 
222
char *opt_scheduler= NULL;
243
223
 
244
 
DRIZZLED_API size_t my_thread_stack_size= 0;
 
224
size_t my_thread_stack_size= 65536;
245
225
 
246
226
/*
247
227
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
249
229
plugin::StorageEngine *heap_engine;
250
230
plugin::StorageEngine *myisam_engine;
251
231
 
 
232
char* opt_secure_file_priv= 0;
 
233
 
252
234
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
253
235
 
254
236
uint32_t drizzled_bind_timeout;
 
237
std::bitset<12> test_flags;
255
238
uint32_t dropping_tables, ha_open_options;
256
239
uint32_t tc_heuristic_recover= 0;
257
240
uint64_t session_startup_options;
258
 
back_log_constraints back_log(50);
259
 
DRIZZLED_API uint32_t server_id;
 
241
uint32_t back_log;
 
242
uint32_t server_id;
260
243
uint64_t table_cache_size;
261
244
size_t table_def_size;
 
245
uint64_t aborted_threads;
 
246
uint64_t aborted_connects;
 
247
uint64_t max_connect_errors;
262
248
uint32_t global_thread_id= 1UL;
263
249
pid_t current_pid;
264
250
 
301
287
time_t server_start_time;
302
288
time_t flush_status_time;
303
289
 
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
 
 
310
 
 
311
 
char system_time_zone[30];
 
290
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
312
291
char *default_tz_name;
313
 
DRIZZLED_API char glob_hostname[FN_REFLEN];
314
 
 
315
 
char *opt_tc_log_file;
 
292
char glob_hostname[FN_REFLEN];
 
293
char data_home_real[FN_REFLEN],
 
294
     language[FN_REFLEN], 
 
295
     *opt_tc_log_file;
 
296
char data_home_real_unpacked[FN_REFLEN];
316
297
const key_map key_map_empty(0);
317
298
key_map key_map_full(0);                        // Will be initialized later
318
299
 
319
 
std::string drizzle_tmpdir;
 
300
uint32_t data_home_len;
 
301
char data_home_buff[2], *data_home=data_home_real;
 
302
char *drizzle_tmpdir= NULL;
320
303
char *opt_drizzle_tmpdir= NULL;
321
304
 
322
305
/** name of reference on left espression in rewritten IN subquery */
325
308
const char *in_additional_cond= "<IN COND>";
326
309
const char *in_having_cond= "<IN HAVING>";
327
310
 
 
311
my_decimal decimal_zero;
328
312
/* classes for comparation parsing/processing */
329
313
 
330
314
FILE *stderror_file=0;
331
315
 
332
 
drizzle_system_variables global_system_variables;
333
 
drizzle_system_variables max_system_variables;
334
 
global_counters current_global_counters;
 
316
struct system_variables global_system_variables;
 
317
struct system_variables max_system_variables;
 
318
struct system_status_var global_status_var;
335
319
 
336
 
DRIZZLED_API const CHARSET_INFO *system_charset_info;
337
 
const CHARSET_INFO *files_charset_info;
 
320
const CHARSET_INFO *system_charset_info, *files_charset_info ;
338
321
const CHARSET_INFO *table_alias_charset;
339
322
const CHARSET_INFO *character_set_filesystem;
340
323
 
342
325
 
343
326
SHOW_COMP_OPTION have_symlink;
344
327
 
345
 
boost::condition_variable_any COND_refresh;
346
 
boost::condition_variable COND_thread_count;
 
328
/* Thread specific variables */
 
329
 
 
330
pthread_key_t THR_Mem_root;
 
331
pthread_key_t THR_Session;
 
332
pthread_mutex_t LOCK_create_db;
 
333
pthread_mutex_t LOCK_open;
 
334
pthread_mutex_t LOCK_thread_count;
 
335
pthread_mutex_t LOCK_status;
 
336
pthread_mutex_t LOCK_global_read_lock;
 
337
pthread_mutex_t LOCK_global_system_variables;
 
338
 
 
339
pthread_rwlock_t        LOCK_system_variables_hash;
 
340
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
347
341
pthread_t signal_thread;
 
342
pthread_cond_t  COND_server_end;
348
343
 
349
344
/* Static variables */
350
345
 
351
346
int cleanup_done;
 
347
static char *drizzle_home_ptr, *pidfile_name_ptr;
 
348
static int defaults_argc;
 
349
static char **defaults_argv;
352
350
 
353
351
passwd *user_info;
354
352
 
355
 
boost::detail::atomic_count connection_count(0);
356
 
 
357
 
global_buffer_constraint<uint64_t> global_sort_buffer(0);
358
 
global_buffer_constraint<uint64_t> global_join_buffer(0);
359
 
global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
360
 
global_buffer_constraint<uint64_t> global_read_buffer(0);
361
 
 
362
 
DRIZZLED_API size_t transaction_message_threshold;
 
353
/**
 
354
  Number of currently active user connections. The variable is protected by
 
355
  LOCK_thread_count.
 
356
*/
 
357
atomic<uint32_t> connection_count;
 
358
 
 
359
/** 
 
360
  Refresh value. We use to test this to find out if a refresh even has happened recently.
 
361
*/
 
362
uint64_t refresh_version;  /* Increments on each reload */
363
363
 
364
364
/* Function declarations */
365
365
bool drizzle_rm_tmp_tables();
366
366
 
367
367
static void drizzle_init_variables(void);
368
 
static void get_options();
369
 
static void fix_paths();
 
368
static void get_options(int *argc,char **argv);
 
369
int drizzled_get_one_option(int, const struct option *, char *);
 
370
static int init_thread_environment();
 
371
static const char *get_relative_path(const char *path);
 
372
static void fix_paths(string &progname);
370
373
 
371
374
static void usage(void);
372
375
void close_connections(void);
373
 
 
374
 
fs::path base_plugin_dir(PKGPLUGINDIR);
375
 
 
376
 
po::options_description config_options("Config File Options");
377
 
po::options_description long_options("Kernel Options");
378
 
po::options_description plugin_load_options("Plugin Loading Options");
379
 
po::options_description plugin_options("Plugin Options");
380
 
po::options_description initial_options("Config and Plugin Loading");
381
 
po::options_description full_options("Kernel and Plugin Loading and Plugin");
382
 
vector<string> unknown_options;
383
 
vector<string> defaults_file_list;
384
 
po::variables_map vm;
385
 
 
386
 
po::variables_map &getVariablesMap()
387
 
{
388
 
  return vm;
389
 
}
390
 
 
391
 
 
 
376
 
392
377
/****************************************************************************
393
378
** Code to end drizzled
394
379
****************************************************************************/
399
384
  plugin::Listen::shutdown();
400
385
 
401
386
  /* kill connection thread */
 
387
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
388
 
 
389
  while (select_thread_in_use)
402
390
  {
403
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
391
    struct timespec abstime;
 
392
    int error;
404
393
 
405
 
    while (select_thread_in_use)
 
394
    set_timespec(abstime, 2);
 
395
    for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
406
396
    {
407
 
      boost::xtime xt; 
408
 
      xtime_get(&xt, boost::TIME_UTC); 
409
 
      xt.sec += 2; 
410
 
 
411
 
      for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
412
 
      {
413
 
        bool success= COND_thread_count.timed_wait(scopedLock, xt);
414
 
        if (not success)
415
 
          break;
416
 
      }
 
397
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
 
398
      if (error != EINTR)
 
399
        break;
417
400
    }
418
401
  }
 
402
  (void) pthread_mutex_unlock(&LOCK_thread_count);
419
403
 
420
404
 
421
405
  /*
424
408
    statements and inform their clients that the server is about to die.
425
409
  */
426
410
 
 
411
  Session *tmp;
 
412
 
 
413
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
414
 
 
415
  for( SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
427
416
  {
428
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
429
 
    session::Cache::list list= session::Cache::singleton().getCache();
430
 
 
431
 
    for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
 
417
    tmp= *it;
 
418
    tmp->killed= Session::KILL_CONNECTION;
 
419
    tmp->scheduler->killSession(tmp);
 
420
    DRIZZLE_CONNECTION_DONE(tmp->thread_id);
 
421
    if (tmp->mysys_var)
432
422
    {
433
 
      Session::shared_ptr tmp(*it);
434
 
 
435
 
      tmp->setKilled(Session::KILL_CONNECTION);
436
 
      tmp->scheduler->killSession(tmp.get());
437
 
      DRIZZLE_CONNECTION_DONE(tmp->thread_id);
438
 
 
439
 
      tmp->lockOnSys();
 
423
      tmp->mysys_var->abort=1;
 
424
      pthread_mutex_lock(&tmp->mysys_var->mutex);
 
425
      if (tmp->mysys_var->current_cond)
 
426
      {
 
427
        pthread_mutex_lock(tmp->mysys_var->current_mutex);
 
428
        pthread_cond_broadcast(tmp->mysys_var->current_cond);
 
429
        pthread_mutex_unlock(tmp->mysys_var->current_mutex);
 
430
      }
 
431
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
440
432
    }
441
433
  }
 
434
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
442
435
 
443
 
  if (session::Cache::singleton().count())
 
436
  if (connection_count)
444
437
    sleep(2);                                   // Give threads time to die
445
438
 
446
439
  /*
450
443
  */
451
444
  for (;;)
452
445
  {
453
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
454
 
    session::Cache::list list= session::Cache::singleton().getCache();
455
 
 
456
 
    if (list.empty())
 
446
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
447
    if (getSessionList().empty())
457
448
    {
 
449
      (void) pthread_mutex_unlock(&LOCK_thread_count);
458
450
      break;
459
451
    }
 
452
    tmp= getSessionList().front();
460
453
    /* Close before unlock, avoiding crash. See LP bug#436685 */
461
 
    list.front()->getClient()->close();
 
454
    tmp->client->close();
 
455
    (void) pthread_mutex_unlock(&LOCK_thread_count);
462
456
  }
463
457
}
464
458
 
 
459
/**
 
460
  cleanup all memory and end program nicely.
 
461
 
 
462
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
463
    by the main thread. To get Drizzle to shut down nicely in this case
 
464
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
465
 
 
466
  @note
 
467
    This function never returns.
 
468
*/
 
469
void unireg_end(void)
 
470
{
 
471
  clean_up(1);
 
472
  internal::my_thread_end();
 
473
#if defined(SIGNALS_DONT_BREAK_READ)
 
474
  exit(0);
 
475
#else
 
476
  pthread_exit(0);                              // Exit is in main thread
 
477
#endif
 
478
}
 
479
 
465
480
 
466
481
void unireg_abort(int exit_code)
467
482
{
468
483
 
469
484
  if (exit_code)
470
 
  {
471
 
    errmsg_printf(error::ERROR, _("Aborting"));
472
 
  }
473
 
  else if (opt_help)
474
 
  {
 
485
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
 
486
  else if (opt_help || opt_help_extended)
475
487
    usage();
476
 
  }
477
 
 
478
488
  clean_up(!opt_help && (exit_code));
 
489
  clean_up_mutexes();
479
490
  internal::my_end();
480
491
  exit(exit_code);
481
492
}
487
498
    return;
488
499
 
489
500
  table_cache_free();
 
501
  TableShare::cacheStop();
 
502
  set_var_free();
490
503
  free_charsets();
491
 
  module::Registry &modules= module::Registry::singleton();
492
 
  modules.shutdownModules();
 
504
  plugin::Registry &plugins= plugin::Registry::singleton();
 
505
  plugin_shutdown(plugins);
493
506
  xid_cache_free();
 
507
  free_status_vars();
 
508
  if (defaults_argv)
 
509
    internal::free_defaults(defaults_argv);
 
510
  free(drizzle_tmpdir);
 
511
  if (opt_secure_file_priv)
 
512
    free(opt_secure_file_priv);
494
513
 
495
514
  deinit_temporal_formats();
496
515
 
498
517
  google::protobuf::ShutdownProtobufLibrary();
499
518
#endif
500
519
 
501
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
 
520
  (void) unlink(pidfile_name);  // This may not always exist
502
521
 
503
522
  if (print_message && server_start_time)
504
 
    errmsg_printf(drizzled::error::INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
505
 
 
506
 
  session::Cache::singleton().shutdownFirst();
 
523
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
 
524
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
525
  ready_to_exit=1;
 
526
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
527
  (void) pthread_cond_broadcast(&COND_server_end);
 
528
  (void) pthread_mutex_unlock(&LOCK_thread_count);
507
529
 
508
530
  /*
509
531
    The following lines may never be executed as the main thread may have
512
534
} /* clean_up */
513
535
 
514
536
 
 
537
void clean_up_mutexes()
 
538
{
 
539
  (void) pthread_mutex_destroy(&LOCK_create_db);
 
540
  (void) pthread_mutex_destroy(&LOCK_open);
 
541
  (void) pthread_mutex_destroy(&LOCK_thread_count);
 
542
  (void) pthread_mutex_destroy(&LOCK_status);
 
543
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
 
544
  (void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
 
545
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
 
546
  (void) pthread_cond_destroy(&COND_thread_count);
 
547
  (void) pthread_cond_destroy(&COND_server_end);
 
548
  (void) pthread_cond_destroy(&COND_refresh);
 
549
  (void) pthread_cond_destroy(&COND_global_read_lock);
 
550
}
 
551
 
 
552
 
515
553
/* Change to run as another user if started with --user */
516
554
 
517
555
passwd *check_user(const char *user)
528
566
      tmp_user_info= getpwnam(user);
529
567
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
530
568
          global_system_variables.log_warnings)
531
 
            errmsg_printf(error::WARN, _("One can only use the --user switch "
 
569
            errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
532
570
                            "if running as root\n"));
533
571
    }
534
572
    return NULL;
535
573
  }
536
 
  if (not user)
 
574
  if (!user)
537
575
  {
538
 
      errmsg_printf(error::ERROR, _("Fatal error: Please read \"Security\" section of "
539
 
                                    "the manual to find out how to run drizzled as root"));
 
576
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
 
577
                      "the manual to find out how to run drizzled as root!\n"));
540
578
    unireg_abort(1);
541
579
  }
542
 
 
543
 
  if (not strcmp(user, "root"))
 
580
  if (!strcmp(user,"root"))
544
581
    return NULL;                        // Avoid problem with dynamic libraries
545
582
 
546
583
  if (!(tmp_user_info= getpwnam(user)))
547
584
  {
548
585
    // Allow a numeric uid to be used
549
586
    const char *pos;
550
 
    for (pos= user; my_isdigit(&my_charset_utf8_general_ci,*pos); pos++) ;
 
587
    for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
551
588
    if (*pos)                                   // Not numeric id
552
589
      goto err;
553
590
    if (!(tmp_user_info= getpwuid(atoi(user))))
556
593
  return tmp_user_info;
557
594
 
558
595
err:
559
 
  errmsg_printf(error::ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
 
596
  errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
560
597
                    "Please check that the user exists!\n"),user);
561
598
  unireg_abort(1);
562
599
 
563
600
#ifdef PR_SET_DUMPABLE
564
 
  if (getDebug().test(debug::CORE_ON_SIGNAL))
 
601
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
565
602
  {
566
603
    /* inform kernel that process is dumpable */
567
604
    (void) prctl(PR_SET_DUMPABLE, 1);
578
615
void set_user(const char *user, passwd *user_info_arg)
579
616
{
580
617
  assert(user_info_arg != 0);
 
618
  /*
 
619
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
 
620
    is configured to use LDAP and the server is statically linked.  We set
 
621
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
 
622
    output a specific message to help the user resolve this problem.
 
623
  */
 
624
  calling_initgroups= true;
581
625
  initgroups((char*) user, user_info_arg->pw_gid);
 
626
  calling_initgroups= false;
582
627
  if (setgid(user_info_arg->pw_gid) == -1)
583
628
  {
584
 
    sql_perror(_("Set process group ID failed"));
 
629
    sql_perror("setgid");
585
630
    unireg_abort(1);
586
631
  }
587
632
  if (setuid(user_info_arg->pw_uid) == -1)
588
633
  {
589
 
    sql_perror(_("Set process user ID failed"));
 
634
    sql_perror("setuid");
590
635
    unireg_abort(1);
591
636
  }
592
637
}
598
643
{
599
644
  if ((chroot(path) == -1) || !chdir("/"))
600
645
  {
601
 
    sql_perror(_("Process chroot failed"));
 
646
    sql_perror("chroot");
602
647
    unireg_abort(1);
603
648
  }
604
649
}
610
655
  SYNOPSIS
611
656
    Session::unlink()
612
657
    session              Thread handler
613
 
*/
614
 
 
615
 
void drizzled::Session::unlink(session_id_t &session_id)
616
 
{
617
 
  Session::shared_ptr session= session::Cache::singleton().find(session_id);
618
 
 
 
658
 
 
659
  NOTES
 
660
    LOCK_thread_count is locked and left locked
 
661
*/
 
662
 
 
663
void Session::unlink(Session *session)
 
664
{
 
665
  connection_count.decrement();
 
666
 
 
667
  session->cleanup();
 
668
 
 
669
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
670
  pthread_mutex_lock(&session->LOCK_delete);
 
671
 
 
672
  getSessionList().erase(remove(getSessionList().begin(),
 
673
                         getSessionList().end(),
 
674
                         session));
 
675
 
 
676
  delete session;
 
677
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
678
 
 
679
  return;
 
680
}
 
681
 
 
682
 
 
683
#ifdef THREAD_SPECIFIC_SIGPIPE
 
684
/**
 
685
 
 
686
  @todo
 
687
    One should have to fix that thr_alarm know about this thread too.
 
688
*/
 
689
extern "C" void abort_thread(int )
 
690
{
 
691
  Session *session=current_session;
619
692
  if (session)
620
 
    unlink(session);
621
 
}
622
 
 
623
 
void drizzled::Session::unlink(Session::shared_ptr &session)
624
 
{
625
 
  --connection_count;
626
 
 
627
 
  session->cleanup();
628
 
 
629
 
  boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
630
 
 
631
 
  if (unlikely(plugin::EventObserver::disconnectSession(*session)))
632
 
  {
633
 
    // We should do something about an error...
634
 
  }
635
 
  session::Cache::singleton().erase(session);
636
 
}
 
693
    session->killed= Session::KILL_CONNECTION;
 
694
  return;;
 
695
}
 
696
#endif
637
697
 
638
698
 
639
699
#ifndef SA_RESETHAND
651
711
  DRIZZLE_CONFIG_NAME, "server", 0, 0
652
712
};
653
713
 
654
 
static void find_plugin_dir(string progname)
655
 
{
656
 
  if (progname[0] != FN_LIBCHAR)
657
 
  {
658
 
    /* We have a relative path and need to find the absolute */
659
 
    char working_dir[FN_REFLEN];
660
 
    char *working_dir_ptr= working_dir;
661
 
    working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
662
 
    string new_path(working_dir);
663
 
    if (*(new_path.end()-1) != '/')
664
 
      new_path.push_back('/');
665
 
    if (progname[0] == '.' && progname[1] == '/')
666
 
      new_path.append(progname.substr(2));
667
 
    else
668
 
      new_path.append(progname);
669
 
    progname.swap(new_path);
670
 
  }
671
 
 
672
 
  /* Now, trim off the exe name */
673
 
  string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
674
 
  if (progdir.rfind(".libs/") != string::npos)
675
 
  {
676
 
    progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
677
 
  }
678
 
  string testlofile(progdir);
679
 
  testlofile.append("drizzled.lo");
680
 
  string testofile(progdir);
681
 
  testofile.append("drizzled.o");
682
 
  struct stat testfile_stat;
683
 
  if (not (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat)))
684
 
  {
685
 
    /* We are in a source dir! Plugin dir is ../plugin/.libs */
686
 
    size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
687
 
    base_plugin_dir= progdir.substr(0,last_libchar_pos);
688
 
    base_plugin_dir /= "plugin";
689
 
    base_plugin_dir /= ".libs";
690
 
  }
691
 
 
692
 
  if (plugin_dir.root_directory() == "")
693
 
  {
694
 
    fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
695
 
    full_plugin_dir /= plugin_dir;
696
 
    plugin_dir= full_plugin_dir;
697
 
  }
698
 
}
699
 
 
700
 
static void notify_plugin_dir(fs::path in_plugin_dir)
701
 
{
702
 
  plugin_dir= in_plugin_dir;
703
 
  if (plugin_dir.root_directory() == "")
704
 
  {
705
 
    fs::path full_plugin_dir(fs::system_complete(basedir));
706
 
    full_plugin_dir /= plugin_dir;
707
 
    plugin_dir= full_plugin_dir;
708
 
  }
709
 
}
710
 
 
711
 
static void expand_secure_file_priv(fs::path in_secure_file_priv)
712
 
{
713
 
  secure_file_priv= fs::system_complete(in_secure_file_priv);
714
 
}
715
 
 
716
 
static void check_limits_aii(uint64_t in_auto_increment_increment)
717
 
{
718
 
  global_system_variables.auto_increment_increment= 1;
719
 
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
720
 
  {
721
 
    cout << _("Error: Invalid Value for auto_increment_increment");
722
 
    exit(-1);
723
 
  }
724
 
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
725
 
}
726
 
 
727
 
static void check_limits_aio(uint64_t in_auto_increment_offset)
728
 
{
729
 
  global_system_variables.auto_increment_offset= 1;
730
 
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
731
 
  {
732
 
    cout << _("Error: Invalid Value for auto_increment_offset");
733
 
    exit(-1);
734
 
  }
735
 
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
736
 
}
737
 
 
738
 
static void check_limits_completion_type(uint32_t in_completion_type)
739
 
{
740
 
  global_system_variables.completion_type= 0;
741
 
  if (in_completion_type > 2)
742
 
  {
743
 
    cout << _("Error: Invalid Value for completion_type");
744
 
    exit(-1);
745
 
  }
746
 
  global_system_variables.completion_type= in_completion_type;
747
 
}
748
 
 
749
 
 
750
 
static void check_limits_dpi(uint32_t in_div_precincrement)
751
 
{
752
 
  global_system_variables.div_precincrement= 4;
753
 
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
754
 
  {
755
 
    cout << _("Error: Invalid Value for div-precision-increment");
756
 
    exit(-1);
757
 
  }
758
 
  global_system_variables.div_precincrement= in_div_precincrement;
759
 
}
760
 
 
761
 
static void check_limits_gcml(uint64_t in_group_concat_max_len)
762
 
{
763
 
  global_system_variables.group_concat_max_len= 1024;
764
 
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
765
 
  {
766
 
    cout << _("Error: Invalid Value for group_concat_max_len");
767
 
    exit(-1);
768
 
  }
769
 
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
770
 
}
771
 
 
772
 
static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
773
 
{
774
 
  global_system_variables.join_buff_size= (128*1024L);
775
 
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
776
 
  {
777
 
    cout << _("Error: Invalid Value for join_buffer_size");
778
 
    exit(-1);
779
 
  }
780
 
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
781
 
  global_system_variables.join_buff_size= in_join_buffer_size;
782
 
}
783
 
 
784
 
static void check_limits_map(uint32_t in_max_allowed_packet)
785
 
{
786
 
  global_system_variables.max_allowed_packet= (64*1024*1024L);
787
 
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
788
 
  {
789
 
    cout << _("Error: Invalid Value for max_allowed_packet");
790
 
    exit(-1);
791
 
  }
792
 
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
793
 
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
794
 
}
795
 
 
796
 
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
797
 
{
798
 
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
799
 
  if (in_max_error_count > 65535)
800
 
  {
801
 
    cout << _("Error: Invalid Value for max_error_count");
802
 
    exit(-1);
803
 
  }
804
 
  global_system_variables.max_error_count= in_max_error_count;
805
 
}
806
 
 
807
 
static void check_limits_mhts(uint64_t in_max_heap_table_size)
808
 
{
809
 
  global_system_variables.max_heap_table_size= (16*1024*1024L);
810
 
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
811
 
  {
812
 
    cout << _("Error: Invalid Value for max_heap_table_size");
813
 
    exit(-1);
814
 
  }
815
 
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
816
 
  global_system_variables.max_heap_table_size= in_max_heap_table_size;
817
 
}
818
 
 
819
 
static void check_limits_merl(uint64_t in_min_examined_row_limit)
820
 
{
821
 
  global_system_variables.min_examined_row_limit= 0;
822
 
  if (in_min_examined_row_limit > ULONG_MAX)
823
 
  {
824
 
    cout << _("Error: Invalid Value for min_examined_row_limit");
825
 
    exit(-1);
826
 
  }
827
 
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
828
 
}
829
 
 
830
 
static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
831
 
{
832
 
  global_system_variables.max_join_size= INT32_MAX;
833
 
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
834
 
  {
835
 
    cout << _("Error: Invalid Value for max_join_size");
836
 
    exit(-1);
837
 
  }
838
 
  global_system_variables.max_join_size= in_max_join_size;
839
 
}
840
 
 
841
 
static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
842
 
{
843
 
  global_system_variables.max_length_for_sort_data= 1024;
844
 
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
845
 
  {
846
 
    cout << _("Error: Invalid Value for max_length_for_sort_data");
847
 
    exit(-1);
848
 
  }
849
 
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
850
 
}
851
 
 
852
 
static void check_limits_msfk(uint64_t in_max_seeks_for_key)
853
 
{
854
 
  global_system_variables.max_seeks_for_key= ULONG_MAX;
855
 
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
856
 
  {
857
 
    cout << _("Error: Invalid Value for max_seeks_for_key");
858
 
    exit(-1);
859
 
  }
860
 
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
861
 
}
862
 
 
863
 
static void check_limits_max_sort_length(size_t in_max_sort_length)
864
 
{
865
 
  global_system_variables.max_sort_length= 1024;
866
 
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
867
 
  {
868
 
    cout << _("Error: Invalid Value for max_sort_length");
869
 
    exit(-1);
870
 
  }
871
 
  global_system_variables.max_sort_length= in_max_sort_length;
872
 
}
873
 
 
874
 
static void check_limits_osd(uint32_t in_optimizer_search_depth)
875
 
{
876
 
  global_system_variables.optimizer_search_depth= 0;
877
 
  if (in_optimizer_search_depth > MAX_TABLES + 2)
878
 
  {
879
 
    cout << _("Error: Invalid Value for optimizer_search_depth");
880
 
    exit(-1);
881
 
  }
882
 
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
883
 
}
884
 
 
885
 
static void check_limits_pbs(uint64_t in_preload_buff_size)
886
 
{
887
 
  global_system_variables.preload_buff_size= (32*1024L);
888
 
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
889
 
  {
890
 
    cout << _("Error: Invalid Value for preload_buff_size");
891
 
    exit(-1);
892
 
  }
893
 
  global_system_variables.preload_buff_size= in_preload_buff_size;
894
 
}
895
 
 
896
 
static void check_limits_qabs(uint32_t in_query_alloc_block_size)
897
 
{
898
 
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
899
 
  if (in_query_alloc_block_size < 1024)
900
 
  {
901
 
    cout << _("Error: Invalid Value for query_alloc_block_size");
902
 
    exit(-1);
903
 
  }
904
 
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
905
 
  global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
906
 
}
907
 
 
908
 
static void check_limits_qps(uint32_t in_query_prealloc_size)
909
 
{
910
 
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
911
 
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
912
 
  {
913
 
    cout << _("Error: Invalid Value for query_prealloc_size");
914
 
    exit(-1);
915
 
  }
916
 
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
917
 
  global_system_variables.query_prealloc_size= in_query_prealloc_size;
918
 
}
919
 
 
920
 
static void check_limits_rabs(size_t in_range_alloc_block_size)
921
 
{
922
 
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
923
 
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
924
 
  {
925
 
    cout << _("Error: Invalid Value for range_alloc_block_size");
926
 
    exit(-1);
927
 
  }
928
 
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
929
 
  global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
930
 
}
931
 
 
932
 
static void check_limits_read_buffer_size(int32_t in_read_buff_size)
933
 
{
934
 
  global_system_variables.read_buff_size= (128*1024L);
935
 
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
936
 
  {
937
 
    cout << _("Error: Invalid Value for read_buff_size");
938
 
    exit(-1);
939
 
  }
940
 
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
941
 
  global_system_variables.read_buff_size= in_read_buff_size;
942
 
}
943
 
 
944
 
static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
945
 
{
946
 
  global_system_variables.read_rnd_buff_size= (256*1024L);
947
 
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
948
 
  {
949
 
    cout << _("Error: Invalid Value for read_rnd_buff_size");
950
 
    exit(-1);
951
 
  }
952
 
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
953
 
}
954
 
 
955
 
static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
956
 
{
957
 
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
958
 
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
959
 
  {
960
 
    cout << _("Error: Invalid Value for sort_buff_size");
961
 
    exit(-1);
962
 
  }
963
 
  global_system_variables.sortbuff_size= in_sortbuff_size;
964
 
}
965
 
 
966
 
static void check_limits_tdc(uint32_t in_table_def_size)
967
 
{
968
 
  table_def_size= 128;
969
 
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
970
 
  {
971
 
    cout << _("Error: Invalid Value for table_def_size");
972
 
    exit(-1);
973
 
  }
974
 
  table_def_size= in_table_def_size;
975
 
}
976
 
 
977
 
static void check_limits_toc(uint32_t in_table_cache_size)
978
 
{
979
 
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
980
 
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
981
 
  {
982
 
    cout << _("Error: Invalid Value for table_cache_size");
983
 
    exit(-1);
984
 
  }
985
 
  table_cache_size= in_table_cache_size;
986
 
}
987
 
 
988
 
static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
989
 
{
990
 
  table_lock_wait_timeout= 50;
991
 
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
992
 
  {
993
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
994
 
    exit(-1);
995
 
  }
996
 
  table_lock_wait_timeout= in_table_lock_wait_timeout;
997
 
}
998
 
 
999
 
static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
1000
 
{
1001
 
  my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
1002
 
}
1003
 
 
1004
 
static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
1005
 
{
1006
 
  global_system_variables.tmp_table_size= 16*1024*1024L;
1007
 
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
1008
 
  {
1009
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
1010
 
    exit(-1);
1011
 
  }
1012
 
  global_system_variables.tmp_table_size= in_tmp_table_size;
1013
 
}
1014
 
 
1015
 
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1016
 
{
1017
 
  transaction_message_threshold= 1024*1024;
1018
 
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1019
 
  {
1020
 
    cout << _("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1021
 
    exit(-1);
1022
 
  }
1023
 
  transaction_message_threshold= in_transaction_message_threshold;
1024
 
}
1025
 
 
1026
 
static void process_defaults_files()
1027
 
{
1028
 
  for (vector<string>::iterator iter= defaults_file_list.begin();
1029
 
       iter != defaults_file_list.end();
1030
 
       ++iter)
1031
 
  {
1032
 
    fs::path file_location= *iter;
1033
 
 
1034
 
    ifstream input_defaults_file(file_location.file_string().c_str());
1035
 
    
1036
 
    po::parsed_options file_parsed=
1037
 
      dpo::parse_config_file(input_defaults_file, full_options, true);
1038
 
    vector<string> file_unknown= 
1039
 
      po::collect_unrecognized(file_parsed.options, po::include_positional);
1040
 
 
1041
 
    for (vector<string>::iterator it= file_unknown.begin();
1042
 
         it != file_unknown.end();
1043
 
         ++it)
1044
 
    {
1045
 
      string new_unknown_opt("--");
1046
 
      new_unknown_opt.append(*it);
1047
 
      ++it;
1048
 
      if (it != file_unknown.end())
1049
 
      {
1050
 
        if ((*it) != "true")
1051
 
        {
1052
 
          new_unknown_opt.push_back('=');
1053
 
          new_unknown_opt.append(*it);
1054
 
        }
1055
 
      }
1056
 
      else
1057
 
      {
1058
 
        break;
1059
 
      }
1060
 
      unknown_options.push_back(new_unknown_opt);
1061
 
    }
1062
 
    store(file_parsed, vm);
1063
 
  }
1064
 
}
1065
 
 
1066
 
static void compose_defaults_file_list(vector<string> in_options)
1067
 
{
1068
 
  for (vector<string>::iterator it= in_options.begin();
1069
 
       it != in_options.end();
1070
 
       ++it)
1071
 
  {
1072
 
    fs::path p(*it);
1073
 
    if (fs::is_regular_file(p))
1074
 
      defaults_file_list.push_back(*it);
1075
 
    else
1076
 
    {
1077
 
      errmsg_printf(error::ERROR,
1078
 
                  _("Defaults file '%s' not found\n"), (*it).c_str());
1079
 
      unireg_abort(1);
1080
 
    }
1081
 
 
1082
 
  }
1083
 
}
1084
 
 
1085
 
int init_basic_variables(int argc, char **argv)
 
714
static int show_starttime(drizzle_show_var *var, char *buff)
 
715
{
 
716
  var->type= SHOW_LONG;
 
717
  var->value= buff;
 
718
  *((long *)buff)= (long) (time(NULL) - server_start_time);
 
719
  return 0;
 
720
}
 
721
 
 
722
static int show_flushstatustime(drizzle_show_var *var, char *buff)
 
723
{
 
724
  var->type= SHOW_LONG;
 
725
  var->value= buff;
 
726
  *((long *)buff)= (long) (time(NULL) - flush_status_time);
 
727
  return 0;
 
728
}
 
729
 
 
730
static st_show_var_func_container show_starttime_cont= { &show_starttime };
 
731
 
 
732
static st_show_var_func_container show_flushstatustime_cont= { &show_flushstatustime };
 
733
 
 
734
/*
 
735
  Variables shown by SHOW STATUS in alphabetical order
 
736
*/
 
737
static drizzle_show_var com_status_vars[]= {
 
738
  {"admin_commands",       (char*) offsetof(system_status_var, com_other), SHOW_LONG_STATUS},
 
739
  {"alter_db",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
 
740
  {"alter_table",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
 
741
  {"analyze",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
 
742
  {"begin",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
 
743
  {"change_db",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
 
744
  {"check",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
 
745
  {"checksum",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
 
746
  {"commit",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
 
747
  {"create_db",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
 
748
  {"create_index",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
 
749
  {"create_table",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
 
750
  {"delete",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
 
751
  {"drop_db",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
 
752
  {"drop_index",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
 
753
  {"drop_table",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
 
754
  {"empty_query",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
 
755
  {"flush",                (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
 
756
  {"insert",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
 
757
  {"insert_select",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
 
758
  {"kill",                 (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
 
759
  {"load",                 (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
 
760
  {"release_savepoint",    (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
 
761
  {"rename_table",         (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
 
762
  {"replace",              (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
 
763
  {"replace_select",       (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
 
764
  {"rollback",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
 
765
  {"rollback_to_savepoint",(char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
 
766
  {"savepoint",            (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
 
767
  {"select",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
 
768
  {"set_option",           (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
 
769
  {"show_create_db",       (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
 
770
  {"show_create_table",    (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
 
771
  {"show_errors",          (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
 
772
  {"show_warnings",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
 
773
  {"truncate",             (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
 
774
  {"unlock_tables",        (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
 
775
  {"update",               (char*) offsetof(system_status_var, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
 
776
  {NULL, NULL, SHOW_LONGLONG}
 
777
};
 
778
 
 
779
static drizzle_show_var status_vars[]= {
 
780
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONGLONG},
 
781
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONGLONG},
 
782
  {"Bytes_received",           (char*) offsetof(system_status_var, bytes_received), SHOW_LONGLONG_STATUS},
 
783
  {"Bytes_sent",               (char*) offsetof(system_status_var, bytes_sent), SHOW_LONGLONG_STATUS},
 
784
  {"Connections",              (char*) &global_thread_id, SHOW_INT_NOFLUSH},
 
785
  {"Created_tmp_disk_tables",  (char*) offsetof(system_status_var, created_tmp_disk_tables), SHOW_LONG_STATUS},
 
786
  {"Created_tmp_tables",       (char*) offsetof(system_status_var, created_tmp_tables), SHOW_LONG_STATUS},
 
787
  {"Flush_commands",           (char*) &refresh_version,    SHOW_INT_NOFLUSH},
 
788
  {"Handler_commit",           (char*) offsetof(system_status_var, ha_commit_count), SHOW_LONG_STATUS},
 
789
  {"Handler_delete",           (char*) offsetof(system_status_var, ha_delete_count), SHOW_LONG_STATUS},
 
790
  {"Handler_prepare",          (char*) offsetof(system_status_var, ha_prepare_count),  SHOW_LONG_STATUS},
 
791
  {"Handler_read_first",       (char*) offsetof(system_status_var, ha_read_first_count), SHOW_LONG_STATUS},
 
792
  {"Handler_read_key",         (char*) offsetof(system_status_var, ha_read_key_count), SHOW_LONG_STATUS},
 
793
  {"Handler_read_next",        (char*) offsetof(system_status_var, ha_read_next_count), SHOW_LONG_STATUS},
 
794
  {"Handler_read_prev",        (char*) offsetof(system_status_var, ha_read_prev_count), SHOW_LONG_STATUS},
 
795
  {"Handler_read_rnd",         (char*) offsetof(system_status_var, ha_read_rnd_count), SHOW_LONG_STATUS},
 
796
  {"Handler_read_rnd_next",    (char*) offsetof(system_status_var, ha_read_rnd_next_count), SHOW_LONG_STATUS},
 
797
  {"Handler_rollback",         (char*) offsetof(system_status_var, ha_rollback_count), SHOW_LONG_STATUS},
 
798
  {"Handler_savepoint",        (char*) offsetof(system_status_var, ha_savepoint_count), SHOW_LONG_STATUS},
 
799
  {"Handler_savepoint_rollback",(char*) offsetof(system_status_var, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
 
800
  {"Handler_update",           (char*) offsetof(system_status_var, ha_update_count), SHOW_LONG_STATUS},
 
801
  {"Handler_write",            (char*) offsetof(system_status_var, ha_write_count), SHOW_LONG_STATUS},
 
802
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
 
803
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
 
804
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
 
805
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
 
806
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
 
807
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
 
808
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
 
809
  {"Last_query_cost",          (char*) offsetof(system_status_var, last_query_cost), SHOW_DOUBLE_STATUS},
 
810
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_INT},
 
811
  {"Questions",                (char*) offsetof(system_status_var, questions), SHOW_LONG_STATUS},
 
812
  {"Select_full_join",         (char*) offsetof(system_status_var, select_full_join_count), SHOW_LONG_STATUS},
 
813
  {"Select_full_range_join",   (char*) offsetof(system_status_var, select_full_range_join_count), SHOW_LONG_STATUS},
 
814
  {"Select_range",             (char*) offsetof(system_status_var, select_range_count), SHOW_LONG_STATUS},
 
815
  {"Select_range_check",       (char*) offsetof(system_status_var, select_range_check_count), SHOW_LONG_STATUS},
 
816
  {"Select_scan",              (char*) offsetof(system_status_var, select_scan_count), SHOW_LONG_STATUS},
 
817
  {"Slow_queries",             (char*) offsetof(system_status_var, long_query_count), SHOW_LONG_STATUS},
 
818
  {"Sort_merge_passes",        (char*) offsetof(system_status_var, filesort_merge_passes), SHOW_LONG_STATUS},
 
819
  {"Sort_range",               (char*) offsetof(system_status_var, filesort_range_count), SHOW_LONG_STATUS},
 
820
  {"Sort_rows",                (char*) offsetof(system_status_var, filesort_rows), SHOW_LONG_STATUS},
 
821
  {"Sort_scan",                (char*) offsetof(system_status_var, filesort_scan_count), SHOW_LONG_STATUS},
 
822
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_INT},
 
823
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_INT},
 
824
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
 
825
  {"Uptime",                   (char*) &show_starttime_cont,         SHOW_FUNC},
 
826
  {"Uptime_since_flush_status",(char*) &show_flushstatustime_cont,   SHOW_FUNC},
 
827
  {NULL, NULL, SHOW_LONGLONG}
 
828
};
 
829
 
 
830
int init_common_variables(const char *conf_file_name, int argc,
 
831
                          char **argv, const char **groups)
1086
832
{
1087
833
  time_t curr_time;
1088
834
  umask(((~internal::my_umask) & 0666));
1089
 
  decimal_zero.set_zero(); // set decimal_zero constant;
 
835
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1090
836
  tzset();                      // Set tzname
1091
837
 
1092
838
  curr_time= time(NULL);
1096
842
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1097
843
  server_start_time= flush_status_time= curr_time;
1098
844
 
 
845
  if (init_thread_environment())
 
846
    return 1;
1099
847
  drizzle_init_variables();
1100
848
 
1101
 
  find_plugin_dir(argv[0]);
1102
849
  {
1103
850
    struct tm tm_tmp;
1104
851
    localtime_r(&server_start_time,&tm_tmp);
1117
864
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
1118
865
  {
1119
866
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1120
 
    errmsg_printf(error::WARN, _("gethostname failed, using '%s' as hostname"),
 
867
    errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1121
868
                  glob_hostname);
1122
 
    pid_file= "drizzle";
 
869
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1123
870
  }
1124
871
  else
1125
 
  {
1126
 
    pid_file= glob_hostname;
1127
 
  }
1128
 
  pid_file.replace_extension(".pid");
1129
 
 
1130
 
  system_config_dir /= "drizzle";
1131
 
 
1132
 
  config_options.add_options()
1133
 
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1134
 
  _("Display this help and exit."))
1135
 
  ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
1136
 
  _("Run as a daemon."))
1137
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1138
 
  _("Configuration file defaults are not used if no-defaults is set"))
1139
 
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1140
 
  _("Configuration file to use"))
1141
 
  ("config-dir", po::value<fs::path>(&system_config_dir),
1142
 
  _("Base location for config files"))
1143
 
  ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(&notify_plugin_dir),
1144
 
  _("Directory for plugins."))
1145
 
  ;
1146
 
 
1147
 
  plugin_load_options.add_options()
1148
 
  ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1149
 
  _("Optional comma separated list of plugins to load at startup in addition "
1150
 
     "to the default list of plugins. "
1151
 
     "[for example: --plugin_add=crc32,logger_gearman]"))    
1152
 
  ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1153
 
  _("Optional comma separated list of plugins to not load at startup. Effectively "
1154
 
     "removes a plugin from the list of plugins to be loaded. "
1155
 
     "[for example: --plugin_remove=crc32,logger_gearman]"))
1156
 
  ("plugin-load", po::value<string>()->notifier(&notify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1157
 
  _("Optional comma separated list of plugins to load at starup instead of "
1158
 
     "the default plugin load list. "
1159
 
     "[for example: --plugin_load=crc32,logger_gearman]"))
1160
 
  ;
1161
 
 
1162
 
  long_options.add_options()
1163
 
  ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1164
 
  _("Auto-increment columns are incremented by this"))
1165
 
  ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1166
 
  _("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1167
 
  ("basedir,b", po::value<fs::path>(&basedir),
1168
 
  _("Path to installation directory. All paths are usually resolved "
1169
 
     "relative to this."))
1170
 
  ("chroot,r", po::value<string>(),
1171
 
  _("Chroot drizzled daemon during startup."))
1172
 
  ("collation-server", po::value<string>(),
1173
 
  _("Set the default collation."))      
1174
 
  ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1175
 
  _("Default completion type."))
1176
 
  ("core-file",  _("Write core on errors."))
1177
 
  ("datadir", po::value<fs::path>(&getDataHome()),
1178
 
  _("Path to the database root."))
1179
 
  ("default-storage-engine", po::value<string>(),
1180
 
  _("Set the default storage engine for tables."))
1181
 
  ("default-time-zone", po::value<string>(),
1182
 
  _("Set the default time zone."))
1183
 
  ("exit-info,T", po::value<long>(),
1184
 
  _("Used for debugging;  Use at your own risk!"))
1185
 
  ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1186
 
  _("Set up signals usable for debugging"))
1187
 
  ("lc-time-name", po::value<string>(),
1188
 
  _("Set the language used for the month names and the days of the week."))
1189
 
  ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1190
 
  _("Log some not critical warnings to the log file."))  
1191
 
  ("pid-file", po::value<fs::path>(&pid_file),
1192
 
  _("Pid file used by drizzled."))
1193
 
  ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1194
 
  _("Maximum time in seconds to wait for the port to become free. "))
1195
 
  ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1196
 
  _("Include the SQL query in replicated protobuf messages."))
1197
 
  ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1198
 
  _("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1199
 
     "within specified directory"))
1200
 
  ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1201
 
  _("Uniquely identifies the server instance in the community of "
1202
 
     "replication partners."))
1203
 
  ("skip-stack-trace",  
1204
 
  _("Don't print a stack trace on failure."))
1205
 
  ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1206
 
  _("Enable symbolic link support."))
1207
 
  ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1208
 
  _("Specify whether to time mutexes (only InnoDB mutexes are currently "
1209
 
     "supported)")) 
1210
 
  ("tmpdir,t", po::value<string>(),
1211
 
  _("Path for temporary files."))
1212
 
  ("transaction-isolation", po::value<string>(),
1213
 
  _("Default transaction isolation level."))
1214
 
  ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1215
 
  _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1216
 
  ("user,u", po::value<string>(),
1217
 
  _("Run drizzled daemon as user."))  
1218
 
  ("version,V", 
1219
 
  _("Output version information and exit."))
1220
 
  ("back-log", po::value<back_log_constraints>(&back_log),
1221
 
  _("The number of outstanding connection requests Drizzle can have. This "
1222
 
     "comes into play when the main Drizzle thread gets very many connection "
1223
 
     "requests in a very short time."))
1224
 
  ("bulk-insert-buffer-size", 
1225
 
  po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1226
 
  _("Size of tree cache used in bulk insert optimization. Note that this is "
1227
 
     "a limit per thread!"))
1228
 
  ("div-precision-increment",  po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1229
 
  _("Precision of the result of '/' operator will be increased on that "
1230
 
     "value."))
1231
 
  ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1232
 
  _("The maximum length of the result of function  group_concat."))
1233
 
  ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1234
 
  _("The size of the buffer that is used for full joins."))
1235
 
  ("join-heap-threshold",
1236
 
  po::value<uint64_t>()->default_value(0),
1237
 
  _("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1238
 
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1239
 
  _("Max packetlength to send/receive from to server."))
1240
 
  ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1241
 
  _("Max number of errors/warnings to store for a statement."))
1242
 
  ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1243
 
  _("Don't allow creation of heap tables bigger than this."))
1244
 
  ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1245
 
  _("Joins that are probably going to read more than max_join_size records "
1246
 
     "return an error."))
1247
 
  ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1248
 
  _("Max number of bytes in sorted records."))
1249
 
  ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1250
 
  _("Limit assumed max number of seeks when looking up rows based on a key"))
1251
 
  ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),  
1252
 
  _("The number of bytes to use when sorting BLOB or TEXT values "
1253
 
     "(only the first max_sort_length bytes of each value are used; the "
1254
 
     "rest are ignored)."))
1255
 
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1256
 
  _("After this many write locks, allow some read locks to run in between."))
1257
 
  ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1258
 
  _("Don't log queries which examine less than min_examined_row_limit "
1259
 
     "rows to file."))
1260
 
  ("disable-optimizer-prune",
1261
 
  _("Do not apply any heuristic(s) during query optimization to prune, "
1262
 
     "thus perform an exhaustive search from the optimizer search space."))
1263
 
  ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1264
 
  _("Maximum depth of search performed by the query optimizer. Values "
1265
 
     "larger than the number of relations in a query result in better query "
1266
 
     "plans, but take longer to compile a query. Smaller values than the "
1267
 
     "number of tables in a relation result in faster optimization, but may "
1268
 
     "produce very bad query plans. If set to 0, the system will "
1269
 
     "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1270
 
     "optimizer will switch to the original find_best (used for "
1271
 
     "testing/comparison)."))
1272
 
  ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1273
 
  _("The size of the buffer that is allocated when preloading indexes"))
1274
 
  ("query-alloc-block-size", 
1275
 
  po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1276
 
  _("Allocation block size for query parsing and execution"))
1277
 
  ("query-prealloc-size",
1278
 
  po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1279
 
  _("Persistent buffer for query parsing and execution"))
1280
 
  ("range-alloc-block-size",
1281
 
  po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1282
 
  _("Allocation block size for storing ranges during optimization"))
1283
 
  ("read-buffer-size",
1284
 
  po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1285
 
  _("Each thread that does a sequential scan allocates a buffer of this "
1286
 
      "size for each table it scans. If you do many sequential scans, you may "
1287
 
      "want to increase this value."))
1288
 
  ("read-buffer-threshold",
1289
 
  po::value<uint64_t>()->default_value(0),
1290
 
  _("A global cap on the size of read-buffer-size (0 means unlimited)"))
1291
 
  ("read-rnd-buffer-size",
1292
 
  po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1293
 
  _("When reading rows in sorted order after a sort, the rows are read "
1294
 
     "through this buffer to avoid a disk seeks. If not set, then it's set "
1295
 
     "to the value of record_buffer."))
1296
 
  ("read-rnd-threshold",
1297
 
  po::value<uint64_t>()->default_value(0),
1298
 
  _("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1299
 
  ("scheduler", po::value<string>(),
1300
 
  _("Select scheduler to be used (by default multi-thread)."))
1301
 
  ("sort-buffer-size",
1302
 
  po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1303
 
  _("Each thread that needs to do a sort allocates a buffer of this size."))
1304
 
  ("sort-heap-threshold",
1305
 
  po::value<uint64_t>()->default_value(0),
1306
 
  _("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
1307
 
  ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1308
 
  _("The number of cached table definitions."))
1309
 
  ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1310
 
  _("The number of cached open tables."))
1311
 
  ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1312
 
  _("Timeout in seconds to wait for a table level lock before returning an "
1313
 
     "error. Used only if the connection has active cursors."))
1314
 
  ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1315
 
  _("The stack size for each thread."))
1316
 
  ("tmp-table-size", 
1317
 
  po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1318
 
  _("If an internal in-memory temporary table exceeds this size, Drizzle will"
1319
 
     " automatically convert it to an on-disk MyISAM table."))
1320
 
  ;
1321
 
 
1322
 
  full_options.add(long_options);
1323
 
  full_options.add(plugin_load_options);
1324
 
 
1325
 
  initial_options.add(config_options);
1326
 
  initial_options.add(plugin_load_options);
1327
 
 
1328
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1329
 
  /* Get options about where config files and the like are */
1330
 
  po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1331
 
    options(initial_options).allow_unregistered().run();
1332
 
  unknown_options=
1333
 
    po::collect_unrecognized(parsed.options, po::include_positional);
1334
 
 
1335
 
  try
1336
 
  {
1337
 
    po::store(parsed, vm);
1338
 
  }
1339
 
  catch (std::exception&)
1340
 
  {
1341
 
    errmsg_printf(error::ERROR, _("Duplicate entry for command line option\n"));
1342
 
    unireg_abort(1);
1343
 
  }
1344
 
 
1345
 
  if (not vm["no-defaults"].as<bool>())
1346
 
  {
1347
 
    fs::path system_config_file_drizzle(system_config_dir);
1348
 
    system_config_file_drizzle /= "drizzled.cnf";
1349
 
    defaults_file_list.insert(defaults_file_list.begin(),
1350
 
                              system_config_file_drizzle.file_string());
1351
 
 
1352
 
    fs::path config_conf_d_location(system_config_dir);
1353
 
    config_conf_d_location /= "conf.d";
1354
 
 
1355
 
 
1356
 
    CachedDirectory config_conf_d(config_conf_d_location.file_string());
1357
 
    if (not config_conf_d.fail())
1358
 
    {
1359
 
 
1360
 
      for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1361
 
           iter != config_conf_d.getEntries().end();
1362
 
           ++iter)
1363
 
      {
1364
 
        string file_entry((*iter)->filename);
1365
 
 
1366
 
        if (not file_entry.empty()
1367
 
            && file_entry != "."
1368
 
            && file_entry != "..")
1369
 
        {
1370
 
          fs::path the_entry(config_conf_d_location);
1371
 
          the_entry /= file_entry;
1372
 
          defaults_file_list.push_back(the_entry.file_string());
1373
 
        }
1374
 
      }
1375
 
    }
1376
 
  }
1377
 
 
1378
 
  /* TODO: here is where we should add a process_env_vars */
1379
 
 
1380
 
  /* We need a notify here so that plugin_init will work properly */
1381
 
  try
1382
 
  {
1383
 
    po::notify(vm);
1384
 
  }
1385
 
  catch (po::validation_error &err)
1386
 
  {
1387
 
    errmsg_printf(error::ERROR,  
1388
 
                  _("%s: %s.\n"
1389
 
                    "Use --help to get a list of available options\n"),
1390
 
                  internal::my_progname, err.what());
1391
 
    unireg_abort(1);
1392
 
  }
1393
 
 
1394
 
  process_defaults_files();
1395
 
 
1396
 
  /* Process with notify a second time because a config file may contain
1397
 
     plugin loader options */
1398
 
 
1399
 
  try
1400
 
  {
1401
 
    po::notify(vm);
1402
 
  }
1403
 
  catch (po::validation_error &err)
1404
 
  {
1405
 
    errmsg_printf(error::ERROR,
1406
 
                  _("%s: %s.\n"
1407
 
                    "Use --help to get a list of available options\n"),
1408
 
                  internal::my_progname, err.what());
1409
 
    unireg_abort(1);
1410
 
  }
1411
 
 
1412
 
  return 0;
1413
 
}
1414
 
 
1415
 
int init_remaining_variables(module::Registry &plugins)
1416
 
{
1417
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
 
872
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
873
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
 
874
 
 
875
  /*
 
876
    Add server status variables to the dynamic list of
 
877
    status variables that is shown by SHOW STATUS.
 
878
    Later, in plugin_init, new entries could be added to that list.
 
879
  */
 
880
  if (add_com_status_vars(com_status_vars))
 
881
    return 1; // an error was already reported
 
882
 
 
883
  if (add_status_vars(status_vars))
 
884
    return 1; // an error was already reported
 
885
 
 
886
  internal::load_defaults(conf_file_name, groups, &argc, &argv);
 
887
  defaults_argv=argv;
 
888
  defaults_argc=argc;
 
889
  get_options(&defaults_argc, defaults_argv);
1418
890
 
1419
891
  current_pid= getpid();                /* Save for later ref */
1420
 
 
1421
 
  /* At this point, we've read all the options we need to read from files and
1422
 
     collected most of them into unknown options - now let's load everything
1423
 
  */
1424
 
 
1425
 
  if (plugin_init(plugins, plugin_options))
1426
 
  {
1427
 
    errmsg_printf(error::ERROR, _("Failed to initialize plugins\n"));
1428
 
    unireg_abort(1);
1429
 
  }
1430
 
 
1431
 
  full_options.add(plugin_options);
1432
 
 
1433
 
  vector<string> final_unknown_options;
1434
 
  try
1435
 
  {
1436
 
    po::parsed_options final_parsed=
1437
 
      po::command_line_parser(unknown_options).style(style).
1438
 
      options(full_options).extra_parser(dpo::parse_size_arg).run();
1439
 
 
1440
 
    final_unknown_options=
1441
 
      po::collect_unrecognized(final_parsed.options, po::include_positional);
1442
 
 
1443
 
    po::store(final_parsed, vm);
1444
 
 
1445
 
  }
1446
 
  catch (po::validation_error &err)
1447
 
  {
1448
 
    errmsg_printf(error::ERROR,
1449
 
                  _("%s: %s.\n"
1450
 
                    "Use --help to get a list of available options\n"),
1451
 
                  internal::my_progname, err.what());
1452
 
    unireg_abort(1);
1453
 
  }
1454
 
  catch (po::invalid_command_line_syntax &err)
1455
 
  {
1456
 
    errmsg_printf(error::ERROR,
1457
 
                  _("%s: %s.\n"
1458
 
                    "Use --help to get a list of available options\n"),
1459
 
                  internal::my_progname, err.what());
1460
 
    unireg_abort(1);
1461
 
  }
1462
 
  catch (po::unknown_option &err)
1463
 
  {
1464
 
    errmsg_printf(error::ERROR,
1465
 
                  _("%s\nUse --help to get a list of available options\n"),
1466
 
                  err.what());
1467
 
    unireg_abort(1);
1468
 
  }
1469
 
 
1470
 
  try
1471
 
  {
1472
 
    po::notify(vm);
1473
 
  }
1474
 
  catch (po::validation_error &err)
1475
 
  {
1476
 
    errmsg_printf(error::ERROR,  
1477
 
                  _("%s: %s.\n"
1478
 
                    "Use --help to get a list of available options\n"),
1479
 
                  internal::my_progname, err.what());
1480
 
    unireg_abort(1);
1481
 
  }
1482
 
 
1483
 
  get_options();
1484
 
 
1485
 
  /* Inverted Booleans */
1486
 
 
1487
 
  global_system_variables.optimizer_prune_level=
1488
 
    vm.count("disable-optimizer-prune") ? false : true;
1489
 
 
1490
 
  if (vm.count("help") == 0 && vm.count("help-extended") == 0)
1491
 
  {
1492
 
    if ((user_info= check_user(drizzled_user)))
1493
 
    {
1494
 
      set_user(drizzled_user, user_info);
1495
 
    }
1496
 
  }
1497
 
 
1498
 
  fix_paths();
1499
 
 
1500
892
  init_time();                          /* Init time-functions (read zone) */
1501
893
 
1502
894
  if (item_create_init())
1503
895
    return 1;
1504
 
  if (sys_var_init())
 
896
  if (set_var_init())
1505
897
    return 1;
1506
898
  /* Creates static regex matching for temporal values */
1507
899
  if (! init_temporal_formats())
1510
902
  if (!(default_charset_info=
1511
903
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1512
904
  {
1513
 
    errmsg_printf(error::ERROR, _("Error getting default charset"));
1514
905
    return 1;                           // Eof of the list
1515
906
  }
1516
907
 
1517
 
  if (vm.count("scheduler"))
1518
 
    opt_scheduler= vm["scheduler"].as<string>().c_str();
1519
 
 
1520
908
  if (default_collation_name)
1521
909
  {
1522
910
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1523
911
    if (not default_collation)
1524
912
    {
1525
 
      errmsg_printf(error::ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
 
913
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1526
914
      return 1;
1527
915
    }
1528
916
    if (not my_charset_same(default_charset_info, default_collation))
1529
917
    {
1530
 
      errmsg_printf(error::ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
 
918
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1531
919
                    default_collation_name,
1532
920
                    default_charset_info->csname);
1533
921
      return 1;
1539
927
 
1540
928
  if (not (character_set_filesystem=
1541
929
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1542
 
  {
1543
 
    errmsg_printf(error::ERROR, _("Error setting collation"));
1544
930
    return 1;
1545
 
  }
1546
931
  global_system_variables.character_set_filesystem= character_set_filesystem;
1547
932
 
1548
933
  if (!(my_default_lc_time_names=
1549
934
        my_locale_by_name(lc_time_names_name)))
1550
935
  {
1551
 
    errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
 
936
    errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1552
937
    return 1;
1553
938
  }
1554
939
  global_system_variables.lc_time_names= my_default_lc_time_names;
1560
945
}
1561
946
 
1562
947
 
1563
 
int init_server_components(module::Registry &plugins)
 
948
static int init_thread_environment()
 
949
{
 
950
   pthread_mutexattr_t attr; 
 
951
   pthread_mutexattr_init(&attr);
 
952
 
 
953
  (void) pthread_mutex_init(&LOCK_create_db, NULL);
 
954
  (void) pthread_mutex_init(&LOCK_open, NULL);
 
955
 
 
956
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 
 
957
  (void) pthread_mutex_init(&LOCK_thread_count, &attr);
 
958
  (void) pthread_mutex_init(&LOCK_global_system_variables, &attr);
 
959
 
 
960
  (void) pthread_mutex_init(&LOCK_status, MY_MUTEX_INIT_FAST);
 
961
  (void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
 
962
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
 
963
  (void) pthread_cond_init(&COND_thread_count,NULL);
 
964
  (void) pthread_cond_init(&COND_server_end,NULL);
 
965
  (void) pthread_cond_init(&COND_refresh,NULL);
 
966
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
 
967
 
 
968
  pthread_mutexattr_destroy(&attr);
 
969
 
 
970
  if (pthread_key_create(&THR_Session,NULL) ||
 
971
      pthread_key_create(&THR_Mem_root,NULL))
 
972
  {
 
973
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
 
974
    return 1;
 
975
  }
 
976
  return 0;
 
977
}
 
978
 
 
979
 
 
980
int init_server_components(plugin::Registry &plugins)
1564
981
{
1565
982
  /*
1566
983
    We need to call each of these following functions to ensure that
1567
984
    all things are initialized so that unireg_abort() doesn't fail
1568
985
  */
1569
986
  if (table_cache_init())
1570
 
  {
1571
 
    errmsg_printf(error::ERROR, _("Could not initialize table cache\n"));
1572
987
    unireg_abort(1);
1573
 
  }
1574
 
 
1575
 
  // Resize the definition Cache at startup
1576
 
  table::Cache::singleton().rehash(table_def_size);
1577
 
  definition::Cache::singleton().rehash(table_def_size);
1578
 
  message::Cache::singleton().rehash(table_def_size);
 
988
  TableShare::cacheStart();
1579
989
 
1580
990
  setup_fpu();
 
991
  init_thr_lock();
1581
992
 
1582
993
  /* Setup logs */
1583
994
 
1584
995
  if (xid_cache_init())
1585
996
  {
1586
 
    errmsg_printf(error::ERROR, _("XA cache initialization failed: Out of memory\n"));
 
997
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1587
998
    unireg_abort(1);
1588
999
  }
1589
1000
 
1590
1001
  /* Allow storage engine to give real error messages */
1591
1002
  ha_init_errors();
1592
1003
 
 
1004
  if (plugin_init(plugins, &defaults_argc, defaults_argv,
 
1005
                  ((opt_help) ? true : false)))
 
1006
  {
 
1007
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
 
1008
    unireg_abort(1);
 
1009
  }
1593
1010
 
1594
 
  if (opt_help)
 
1011
  if (opt_help || opt_help_extended)
1595
1012
    unireg_abort(0);
1596
1013
 
1597
 
  if (plugin_finalize(plugins))
 
1014
  /* we do want to exit if there are any other unknown options */
 
1015
  if (defaults_argc > 1)
1598
1016
  {
1599
 
    unireg_abort(1);
 
1017
    int ho_error;
 
1018
    char **tmp_argv= defaults_argv;
 
1019
    struct option no_opts[]=
 
1020
    {
 
1021
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1022
    };
 
1023
    /*
 
1024
      We need to eat any 'loose' arguments first before we conclude
 
1025
      that there are unprocessed options.
 
1026
      But we need to preserve defaults_argv pointer intact for
 
1027
      internal::free_defaults() to work. Thus we use a copy here.
 
1028
    */
 
1029
    my_getopt_skip_unknown= 0;
 
1030
 
 
1031
    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
 
1032
                                  drizzled_get_one_option)))
 
1033
      unireg_abort(ho_error);
 
1034
 
 
1035
    if (defaults_argc)
 
1036
    {
 
1037
      fprintf(stderr,
 
1038
              _("%s: Too many arguments (first extra is '%s').\n"
 
1039
                "Use --verbose --help to get a list of available options\n"),
 
1040
              internal::my_progname, *tmp_argv);
 
1041
      unireg_abort(1);
 
1042
    }
1600
1043
  }
1601
1044
 
1602
1045
  string scheduler_name;
1607
1050
  else
1608
1051
  {
1609
1052
    scheduler_name= opt_scheduler_default;
1610
 
    opt_scheduler= opt_scheduler_default; 
1611
1053
  }
1612
1054
 
1613
1055
  if (plugin::Scheduler::setPlugin(scheduler_name))
1614
1056
  {
1615
 
      errmsg_printf(error::ERROR,
 
1057
      errmsg_printf(ERRMSG_LVL_ERROR,
1616
1058
                   _("No scheduler found, cannot continue!\n"));
1617
1059
      unireg_abort(1);
1618
1060
  }
1637
1079
    engine= plugin::StorageEngine::findByName(name);
1638
1080
    if (engine == NULL)
1639
1081
    {
1640
 
      errmsg_printf(error::ERROR, _("Unknown/unsupported storage engine: %s\n"),
 
1082
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s"),
1641
1083
                    default_storage_engine_str);
1642
1084
      unireg_abort(1);
1643
1085
    }
1644
1086
    global_system_variables.storage_engine= engine;
1645
1087
  }
1646
1088
 
1647
 
  if (plugin::XaResourceManager::recoverAllXids())
 
1089
  if (plugin::XaResourceManager::recoverAllXids(0))
1648
1090
  {
1649
 
    /* This function alredy generates error messages */
1650
1091
    unireg_abort(1);
1651
1092
  }
1652
1093
 
1677
1118
  OPT_LOCAL_INFILE,
1678
1119
  OPT_BACK_LOG,
1679
1120
  OPT_JOIN_BUFF_SIZE,
 
1121
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
 
1122
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1680
1123
  OPT_MAX_ALLOWED_PACKET,
 
1124
  OPT_MAX_CONNECT_ERRORS,
1681
1125
  OPT_MAX_HEP_TABLE_SIZE,
1682
1126
  OPT_MAX_JOIN_SIZE,
1683
1127
  OPT_MAX_SORT_LENGTH,
1720
1164
  OPT_PLUGIN_DIR,
1721
1165
  OPT_PORT_OPEN_TIMEOUT,
1722
1166
  OPT_SECURE_FILE_PRIV,
1723
 
  OPT_MIN_EXAMINED_ROW_LIMIT,
1724
 
  OPT_PRINT_DEFAULTS
 
1167
  OPT_MIN_EXAMINED_ROW_LIMIT
1725
1168
};
1726
1169
 
1727
1170
 
1728
1171
struct option my_long_options[] =
1729
1172
{
1730
 
 
1731
1173
  {"help", '?', N_("Display this help and exit."),
1732
1174
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1733
1175
   0, 0},
1734
 
  {"daemon", 'd', N_("Run as daemon."),
1735
 
   (char**) &opt_daemon, (char**) &opt_daemon, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1736
 
   0, 0},
 
1176
  {"help-extended", '?',
 
1177
   N_("Display this help and exit after initializing plugins."),
 
1178
   (char**) &opt_help_extended, (char**) &opt_help_extended,
 
1179
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1737
1180
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1738
1181
   N_("Auto-increment columns are incremented by this"),
1739
1182
   (char**) &global_system_variables.auto_increment_increment,
1740
1183
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1741
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
 
1184
   OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1742
1185
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1743
1186
   N_("Offset added to Auto-increment columns. Used when "
1744
1187
      "auto-increment-increment != 1"),
1745
1188
   (char**) &global_system_variables.auto_increment_offset,
1746
1189
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1747
 
   1, 1, INT64_MAX, 0, 1, 0 },
 
1190
   1, 1, UINT64_MAX, 0, 1, 0 },
1748
1191
  {"basedir", 'b',
1749
1192
   N_("Path to installation directory. All paths are usually resolved "
1750
1193
      "relative to this."),
1751
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
 
1194
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1752
1195
   0, 0, 0, 0, 0, 0},
1753
1196
  {"chroot", 'r',
1754
1197
   N_("Chroot drizzled daemon during startup."),
1769
1212
   NO_ARG, 0, 0, 0, 0, 0, 0},
1770
1213
  {"datadir", 'h',
1771
1214
   N_("Path to the database root."),
1772
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1215
   (char**) &data_home,
 
1216
   (char**) &data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1217
  {"default-storage-engine", OPT_STORAGE_ENGINE,
 
1218
   N_("Set the default storage engine (table type) for tables."),
 
1219
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
 
1220
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1221
  {"default-time-zone", OPT_DEFAULT_TIME_ZONE,
 
1222
   N_("Set the default time zone."),
 
1223
   (char**) &default_tz_name, (char**) &default_tz_name,
 
1224
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1773
1225
  /* See how it's handled in get_one_option() */
1774
1226
  {"exit-info", 'T',
1775
1227
   N_("Used for debugging;  Use at your own risk!"),
1780
1232
   N_("Set up signals usable for debugging"),
1781
1233
   (char**) &opt_debugging, (char**) &opt_debugging,
1782
1234
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1235
  {"language", 'L',
 
1236
   N_("(IGNORED)"),
 
1237
   (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
 
1238
   0, 0, 0, 0, 0, 0},
 
1239
  {"lc-time-names", OPT_LC_TIME_NAMES,
 
1240
   N_("Set the language used for the month names and the days of the week."),
 
1241
   (char**) &lc_time_names_name,
 
1242
   (char**) &lc_time_names_name,
 
1243
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1783
1244
  {"log-warnings", 'W',
1784
1245
   N_("Log some not critical warnings to the log file."),
1785
1246
   (char**) &global_system_variables.log_warnings,
1786
1247
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1787
1248
   0, 0, 0},
1788
1249
  {"pid-file", OPT_PID_FILE,
1789
 
   N_("Pid file used by drizzled."),
1790
 
   NULL, NULL, 0, GET_STR,
 
1250
   N_("Pid file used by safe_mysqld."),
 
1251
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1791
1252
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1792
1253
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1793
1254
   N_("Maximum time in seconds to wait for the port to become free. "
1797
1258
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1798
1259
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1799
1260
      "within specified directory"),
1800
 
   NULL, NULL, 0,
 
1261
   (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1801
1262
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1802
1263
  {"server-id", OPT_SERVER_ID,
1803
1264
   N_("Uniquely identifies the server instance in the community of "
1822
1283
      "supported)"),
1823
1284
   (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1824
1285
    0, 0, 0, 0, 0},
 
1286
  {"tmpdir", 't',
 
1287
   N_("Path for temporary files."),
 
1288
   (char**) &opt_drizzle_tmpdir,
 
1289
   (char**) &opt_drizzle_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
1290
  {"transaction-isolation", OPT_TX_ISOLATION,
1826
1291
   N_("Default transaction isolation level."),
1827
1292
   0, 0, 0, GET_STR, REQUIRED_ARG, 0,
1830
1295
   N_("Run drizzled daemon as user."),
1831
1296
   0, 0, 0, GET_STR, REQUIRED_ARG,
1832
1297
   0, 0, 0, 0, 0, 0},
 
1298
  {"version", 'V',
 
1299
   N_("Output version information and exit."),
 
1300
   0, 0, 0, GET_NO_ARG,
 
1301
   NO_ARG, 0, 0, 0, 0, 0, 0},
1833
1302
  {"back_log", OPT_BACK_LOG,
1834
1303
   N_("The number of outstanding connection requests Drizzle can have. This "
1835
1304
      "comes into play when the main Drizzle thread gets very many connection "
1848
1317
   (char**) &global_system_variables.div_precincrement,
1849
1318
   (char**) &max_system_variables.div_precincrement, 0, GET_UINT,
1850
1319
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
 
1320
  { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
 
1321
    N_("The maximum length of the result of function  group_concat."),
 
1322
    (char**) &global_system_variables.group_concat_max_len,
 
1323
    (char**) &max_system_variables.group_concat_max_len, 0, GET_UINT64,
 
1324
    REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
1851
1325
  { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
1852
1326
    N_("The size of the buffer that is used for full joins."),
1853
1327
   (char**) &global_system_variables.join_buff_size,
1858
1332
   N_("Max packetlength to send/receive from to server."),
1859
1333
   (char**) &global_system_variables.max_allowed_packet,
1860
1334
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1861
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1335
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1336
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
 
1337
   N_("If there is more than this number of interrupted connections from a "
 
1338
      "host this host will be blocked from further connections."),
 
1339
   (char**) &max_connect_errors, (char**) &max_connect_errors, 0, GET_UINT64,
 
1340
   REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
 
1341
  {"max_error_count", OPT_MAX_ERROR_COUNT,
 
1342
   N_("Max number of errors/warnings to store for a statement."),
 
1343
   (char**) &global_system_variables.max_error_count,
 
1344
   (char**) &max_system_variables.max_error_count,
 
1345
   0, GET_UINT64, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
1862
1346
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
1863
1347
   N_("Don't allow creation of heap tables bigger than this."),
1864
1348
   (char**) &global_system_variables.max_heap_table_size,
1865
1349
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1866
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
 
1350
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1867
1351
   MALLOC_OVERHEAD, 1024, 0},
1868
1352
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1869
1353
   N_("Joins that are probably going to read more than max_join_size records "
1920
1404
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
1921
1405
  {"plugin_dir", OPT_PLUGIN_DIR,
1922
1406
   N_("Directory for plugins."),
1923
 
   NULL, NULL, 0,
 
1407
   (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
1924
1408
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1925
1409
  {"plugin_add", OPT_PLUGIN_ADD,
1926
1410
   N_("Optional comma separated list of plugins to load at startup in addition "
1927
1411
      "to the default list of plugins. "
1928
1412
      "[for example: --plugin_add=crc32,logger_gearman]"),
1929
 
   NULL, NULL, 0,
 
1413
   (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
1930
1414
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1931
1415
  {"plugin_remove", OPT_PLUGIN_ADD,
1932
1416
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
1933
1417
      "removes a plugin from the list of plugins to be loaded. "
1934
1418
      "[for example: --plugin_remove=crc32,logger_gearman]"),
1935
 
   NULL, NULL, 0,
 
1419
   (char**) &opt_plugin_remove, (char**) &opt_plugin_remove, 0,
1936
1420
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1937
1421
  {"plugin_load", OPT_PLUGIN_LOAD,
1938
1422
   N_("Optional comma separated list of plugins to load at starup instead of "
1939
1423
      "the default plugin load list. "
1940
1424
      "[for example: --plugin_load=crc32,logger_gearman]"),
1941
 
   NULL, NULL, 0,
 
1425
   (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
1942
1426
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1943
1427
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1944
1428
   N_("The size of the buffer that is allocated when preloading indexes"),
1960
1444
   N_("Allocation block size for storing ranges during optimization"),
1961
1445
   (char**) &global_system_variables.range_alloc_block_size,
1962
1446
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
1963
 
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
 
1447
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
1964
1448
   0, 1024, 0},
1965
1449
  {"read_buffer_size", OPT_RECORD_BUFFER,
1966
1450
    N_("Each thread that does a sequential scan allocates a buffer of this "
1978
1462
   (char**) &max_system_variables.read_rnd_buff_size, 0,
1979
1463
   GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
1980
1464
   UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
 
1465
  {"scheduler", OPT_SCHEDULER,
 
1466
   N_("Select scheduler to be used (by default multi-thread)."),
 
1467
   (char**)&opt_scheduler, (char**)&opt_scheduler,
 
1468
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1981
1469
  /* x8 compared to MySQL's x2. We have UTF8 to consider. */
1982
1470
  {"sort_buffer_size", OPT_SORT_BUFFER,
1983
1471
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
1984
1472
   (char**) &global_system_variables.sortbuff_size,
1985
1473
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
1986
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
 
1474
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, SIZE_MAX,
1987
1475
   MALLOC_OVERHEAD, 1, 0},
1988
1476
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
1989
1477
   N_("The number of cached table definitions."),
2003
1491
   (char**) &my_thread_stack_size,
2004
1492
   (char**) &my_thread_stack_size, 0, GET_SIZE,
2005
1493
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
2006
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
 
1494
   UINT32_C(1024*512), SIZE_MAX, 0, 1024, 0},
2007
1495
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
2008
1496
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2009
1497
      " automatically convert it to an on-disk MyISAM table."),
2010
1498
   (char**) &global_system_variables.tmp_table_size,
2011
1499
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2012
 
   REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
1500
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2013
1501
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2014
1502
};
2015
1503
 
2035
1523
         "This software comes with ABSOLUTELY NO WARRANTY. "
2036
1524
         "This is free software,\n"
2037
1525
         "and you are welcome to modify and redistribute it under the GPL "
2038
 
         "license\n\n"));
 
1526
         "license\n\n"
 
1527
         "Starts the Drizzle database server\n"));
2039
1528
 
2040
 
 
2041
1529
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
2042
 
 
2043
 
  po::options_description all_options("Drizzled Options");
2044
 
  all_options.add(config_options);
2045
 
  all_options.add(plugin_load_options);
2046
 
  all_options.add(long_options);
2047
 
  all_options.add(plugin_options);
2048
 
  cout << all_options << endl;
2049
 
 
 
1530
  {
 
1531
     internal::print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
1532
     puts("");
 
1533
 
 
1534
     /* Print out all the options including plugin supplied options */
 
1535
     my_print_help_inc_plugins(my_long_options);
 
1536
  }
2050
1537
}
2051
1538
 
 
1539
 
2052
1540
/**
2053
1541
  Initialize all Drizzle global variables to default values.
2054
1542
 
2068
1556
static void drizzle_init_variables(void)
2069
1557
{
2070
1558
  /* Things reset to zero */
 
1559
  drizzle_home[0]= pidfile_name[0]= 0;
2071
1560
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
1561
  opt_secure_file_priv= 0;
2072
1562
  cleanup_done= 0;
 
1563
  defaults_argc= 0;
 
1564
  defaults_argv= 0;
2073
1565
  dropping_tables= ha_open_options=0;
2074
 
  getDebug().reset();
 
1566
  test_flags.reset();
2075
1567
  wake_thread=0;
2076
1568
  abort_loop= select_thread_in_use= false;
2077
 
  shutdown_in_progress= 0;
 
1569
  ready_to_exit= shutdown_in_progress= 0;
 
1570
  aborted_threads= aborted_connects= 0;
 
1571
  max_used_connections= 0;
2078
1572
  drizzled_user= drizzled_chroot= 0;
2079
 
  memset(&current_global_counters, 0, sizeof(current_global_counters));
 
1573
  memset(&global_status_var, 0, sizeof(global_status_var));
2080
1574
  key_map_full.set();
2081
1575
 
2082
1576
  /* Character sets */
2086
1580
  character_set_filesystem= &my_charset_bin;
2087
1581
 
2088
1582
  /* Things with default values that are not zero */
 
1583
  drizzle_home_ptr= drizzle_home;
 
1584
  pidfile_name_ptr= pidfile_name;
 
1585
  language_ptr= language;
 
1586
  data_home= data_home_real;
2089
1587
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2090
1588
  refresh_version= 1L;  /* Increments on each reload */
2091
1589
  global_thread_id= 1UL;
2092
 
  session::Cache::singleton().getCache().clear();
 
1590
  getSessionList().clear();
 
1591
 
 
1592
  /* Set directory paths */
 
1593
  strncpy(language, LANGUAGE, sizeof(language)-1);
 
1594
  strncpy(data_home_real, get_relative_path(LOCALSTATEDIR),
 
1595
          sizeof(data_home_real)-1);
 
1596
  data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
1597
  data_home_buff[1]=0;
 
1598
  data_home_len= 2;
2093
1599
 
2094
1600
  /* Variables in libraries */
2095
1601
  default_character_set_name= "utf8";
2104
1610
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2105
1611
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2106
1612
  max_system_variables.max_join_size=   (uint64_t) HA_POS_ERROR;
2107
 
  max_system_variables.auto_increment_increment= UINT64_MAX;
2108
 
  max_system_variables.auto_increment_offset= UINT64_MAX;
2109
 
  max_system_variables.completion_type= 2;
2110
 
  max_system_variables.log_warnings= true;
2111
 
  max_system_variables.bulk_insert_buff_size= ULONG_MAX;
2112
 
  max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
2113
 
  max_system_variables.group_concat_max_len= ULONG_MAX;
2114
 
  max_system_variables.join_buff_size= ULONG_MAX;
2115
 
  max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
2116
 
  max_system_variables.max_error_count= 65535;
2117
 
  max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
2118
 
  max_system_variables.max_join_size= INT32_MAX;
2119
 
  max_system_variables.max_length_for_sort_data= 8192*1024L;
2120
 
  max_system_variables.max_seeks_for_key= ULONG_MAX;
2121
 
  max_system_variables.max_sort_length= 8192*1024L;
2122
 
  max_system_variables.min_examined_row_limit= ULONG_MAX;
2123
 
  max_system_variables.optimizer_prune_level= 1;
2124
 
  max_system_variables.optimizer_search_depth= MAX_TABLES+2;
2125
 
  max_system_variables.preload_buff_size= 1024*1024*1024L;
2126
 
  max_system_variables.query_alloc_block_size= UINT32_MAX;
2127
 
  max_system_variables.query_prealloc_size= UINT32_MAX;
2128
 
  max_system_variables.range_alloc_block_size= SIZE_MAX;
2129
 
  max_system_variables.read_buff_size= INT32_MAX;
2130
 
  max_system_variables.read_rnd_buff_size= UINT32_MAX;
2131
 
  max_system_variables.sortbuff_size= SIZE_MAX;
2132
 
  max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
2133
 
 
2134
 
  opt_scheduler_default= (char*) "multi_thread";
2135
1613
 
2136
1614
  /* Variables that depends on compile options */
2137
1615
#ifdef HAVE_BROKEN_REALPATH
2139
1617
#else
2140
1618
  have_symlink=SHOW_OPTION_YES;
2141
1619
#endif
 
1620
 
 
1621
  const char *tmpenv;
 
1622
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
1623
    tmpenv = PREFIX;
 
1624
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
 
1625
  
 
1626
  connection_count= 0;
2142
1627
}
2143
1628
 
2144
1629
 
2145
 
/**
2146
 
  @todo
2147
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2148
 
*/
2149
 
static void get_options()
 
1630
int drizzled_get_one_option(int optid, const struct option *opt,
 
1631
                             char *argument)
2150
1632
{
2151
 
 
2152
 
  fs::path &data_home_catalog= getDataHomeCatalog();
2153
 
  data_home_catalog= getDataHome();
2154
 
  data_home_catalog /= "local"; 
2155
 
 
2156
 
  if (vm.count("user"))
2157
 
  {
2158
 
    if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
2159
 
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2160
 
 
 
1633
  switch(optid) {
 
1634
  case 'a':
 
1635
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
 
1636
    break;
 
1637
  case 'b':
 
1638
    strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
 
1639
    break;
 
1640
  case 'C':
 
1641
    if (default_collation_name == compiled_default_collation_name)
 
1642
      default_collation_name= 0;
 
1643
    break;
 
1644
  case 'h':
 
1645
    strncpy(data_home_real,argument, sizeof(data_home_real)-1);
 
1646
    /* Correct pointer set by my_getopt (for embedded library) */
 
1647
    data_home= data_home_real;
 
1648
    data_home_len= strlen(data_home);
 
1649
    break;
 
1650
  case 'u':
 
1651
    if (!drizzled_user || !strcmp(drizzled_user, argument))
 
1652
      drizzled_user= argument;
2161
1653
    else
2162
 
      errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was "
2163
 
                                       "set to '%s' earlier on the command line\n"),
2164
 
                    vm["user"].as<string>().c_str(), drizzled_user);
2165
 
  }
2166
 
 
2167
 
  if (vm.count("version"))
2168
 
  {
 
1654
      errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
 
1655
                          "set to '%s' earlier on the command line\n"),
 
1656
                        argument, drizzled_user);
 
1657
    break;
 
1658
  case 'L':
 
1659
    strncpy(language, argument, sizeof(language)-1);
 
1660
    break;
 
1661
  case 'V':
2169
1662
    print_version();
2170
1663
    exit(0);
2171
 
  }
2172
 
 
2173
 
  if (vm.count("sort-heap-threshold"))
2174
 
  {
2175
 
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2176
 
      (vm["sort-heap-threshold"].as<uint64_t>() < 
2177
 
      global_system_variables.sortbuff_size))
2178
 
    {
2179
 
      cout << _("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2180
 
      exit(-1);
2181
 
    }
2182
 
 
2183
 
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2184
 
  }
2185
 
 
2186
 
  if (vm.count("join-heap-threshold"))
2187
 
  {
2188
 
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2189
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2190
 
      global_system_variables.join_buff_size))
2191
 
    {
2192
 
      cout << _("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2193
 
      exit(-1);
2194
 
    }
2195
 
 
2196
 
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2197
 
  }
2198
 
 
2199
 
  if (vm.count("read-rnd-threshold"))
2200
 
  {
2201
 
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2202
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2203
 
      global_system_variables.read_rnd_buff_size))
2204
 
    {
2205
 
      cout << _("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2206
 
      exit(-1);
2207
 
    }
2208
 
 
2209
 
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2210
 
  }
2211
 
 
2212
 
  if (vm.count("read-buffer-threshold"))
2213
 
  {
2214
 
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2215
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2216
 
      global_system_variables.read_buff_size))
2217
 
    {
2218
 
      cout << _("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2219
 
      exit(-1);
2220
 
    }
2221
 
 
2222
 
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2223
 
  }
2224
 
 
2225
 
  if (vm.count("exit-info"))
2226
 
  {
2227
 
    if (vm["exit-info"].as<long>())
2228
 
    {
2229
 
      getDebug().set((uint32_t) vm["exit-info"].as<long>());
2230
 
    }
2231
 
  }
2232
 
 
2233
 
  if (vm.count("want-core"))
2234
 
  {
2235
 
    getDebug().set(debug::CORE_ON_SIGNAL);
2236
 
  }
2237
 
 
2238
 
  if (vm.count("skip-stack-trace"))
2239
 
  {
2240
 
    getDebug().set(debug::NO_STACKTRACE);
2241
 
  }
2242
 
 
2243
 
  if (vm.count("skip-symlinks"))
2244
 
  {
 
1664
  case 'W':
 
1665
    if (!argument)
 
1666
      global_system_variables.log_warnings++;
 
1667
    else if (argument == disabled_my_option)
 
1668
      global_system_variables.log_warnings= 0L;
 
1669
    else
 
1670
      global_system_variables.log_warnings= atoi(argument);
 
1671
    break;
 
1672
  case 'T':
 
1673
    if (argument)
 
1674
    {
 
1675
      test_flags.set((uint32_t) atoi(argument));
 
1676
    }
 
1677
    break;
 
1678
  case (int) OPT_WANT_CORE:
 
1679
    test_flags.set(TEST_CORE_ON_SIGNAL);
 
1680
    break;
 
1681
  case (int) OPT_SKIP_STACK_TRACE:
 
1682
    test_flags.set(TEST_NO_STACKTRACE);
 
1683
    break;
 
1684
  case (int) OPT_SKIP_SYMLINKS:
2245
1685
    internal::my_use_symdir=0;
2246
 
  }
2247
 
 
2248
 
  if (vm.count("transaction-isolation"))
2249
 
  {
2250
 
    int type= tx_isolation_typelib.find_type_or_exit(vm["transaction-isolation"].as<string>().c_str(), "transaction-isolation");
2251
 
    global_system_variables.tx_isolation= type - 1;
2252
 
  }
2253
 
 
2254
 
  /* @TODO Make this all strings */
2255
 
  if (vm.count("default-storage-engine"))
2256
 
  {
2257
 
    default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
2258
 
  }
 
1686
    break;
 
1687
  case (int) OPT_BIND_ADDRESS:
 
1688
    {
 
1689
      struct addrinfo *res_lst, hints;
 
1690
 
 
1691
      memset(&hints, 0, sizeof(struct addrinfo));
 
1692
      hints.ai_socktype= SOCK_STREAM;
 
1693
      hints.ai_protocol= IPPROTO_TCP;
 
1694
 
 
1695
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
 
1696
      {
 
1697
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
 
1698
        return EXIT_ARGUMENT_INVALID;
 
1699
      }
 
1700
 
 
1701
      if (res_lst->ai_next)
 
1702
      {
 
1703
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
 
1704
                          "multiple interfaces!"));
 
1705
        return EXIT_ARGUMENT_INVALID;
 
1706
      }
 
1707
      freeaddrinfo(res_lst);
 
1708
    }
 
1709
    break;
 
1710
  case (int) OPT_PID_FILE:
 
1711
    strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
 
1712
    break;
 
1713
  case OPT_SERVER_ID:
 
1714
    break;
 
1715
  case OPT_TX_ISOLATION:
 
1716
    {
 
1717
      int type;
 
1718
      type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
 
1719
      global_system_variables.tx_isolation= (type-1);
 
1720
      break;
 
1721
    }
 
1722
  case OPT_TC_HEURISTIC_RECOVER:
 
1723
    tc_heuristic_recover= find_type_or_exit(argument,
 
1724
                                            &tc_heuristic_recover_typelib,
 
1725
                                            opt->name);
 
1726
    break;
 
1727
  }
 
1728
 
 
1729
  return 0;
 
1730
}
 
1731
 
 
1732
static void option_error_reporter(enum loglevel level, const char *format, ...)
 
1733
{
 
1734
  va_list args;
 
1735
  va_start(args, format);
 
1736
 
 
1737
  /* Don't print warnings for --loose options during bootstrap */
 
1738
  if (level == ERROR_LEVEL || global_system_variables.log_warnings)
 
1739
  {
 
1740
    plugin::ErrorMessage::vprintf(current_session, ERROR_LEVEL, format, args);
 
1741
  }
 
1742
  va_end(args);
 
1743
}
 
1744
 
 
1745
 
 
1746
/**
 
1747
  @todo
 
1748
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
 
1749
*/
 
1750
static void get_options(int *argc,char **argv)
 
1751
{
 
1752
  int ho_error;
 
1753
 
 
1754
  my_getopt_error_reporter= option_error_reporter;
 
1755
 
 
1756
  string progname(argv[0]);
2259
1757
 
2260
1758
  /* Skip unknown options so that they may be processed later by plugins */
2261
1759
  my_getopt_skip_unknown= true;
2262
1760
 
 
1761
  if ((ho_error= handle_options(argc, &argv, my_long_options,
 
1762
                                drizzled_get_one_option)))
 
1763
    exit(ho_error);
 
1764
  (*argc)++; /* add back one for the progname handle_options removes */
 
1765
             /* no need to do this for argv as we are discarding it. */
2263
1766
 
2264
1767
#if defined(HAVE_BROKEN_REALPATH)
2265
1768
  internal::my_use_symdir=0;
2275
1778
  if (opt_debugging)
2276
1779
  {
2277
1780
    /* Allow break with SIGINT, no core or stack trace */
2278
 
    getDebug().set(debug::ALLOW_SIGINT);
2279
 
    getDebug().set(debug::NO_STACKTRACE);
2280
 
    getDebug().reset(debug::CORE_ON_SIGNAL);
 
1781
    test_flags.set(TEST_SIGINT);
 
1782
    test_flags.set(TEST_NO_STACKTRACE);
 
1783
    test_flags.reset(TEST_CORE_ON_SIGNAL);
2281
1784
  }
2282
1785
 
2283
1786
  if (drizzled_chroot)
2284
1787
    set_root(drizzled_chroot);
 
1788
  fix_paths(progname);
2285
1789
 
2286
1790
  /*
2287
1791
    Set some global variables from the global_system_variables
2291
1795
}
2292
1796
 
2293
1797
 
2294
 
static void fix_paths()
2295
 
{
2296
 
  fs::path pid_file_path(pid_file);
2297
 
  if (pid_file_path.root_path().string() == "")
2298
 
  {
2299
 
    pid_file_path= getDataHome();
2300
 
    pid_file_path /= pid_file;
2301
 
  }
2302
 
  pid_file= fs::system_complete(pid_file_path);
2303
 
 
2304
 
  if (not opt_help)
2305
 
  {
2306
 
    const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
 
1798
static const char *get_relative_path(const char *path)
 
1799
{
 
1800
  if (internal::test_if_hard_path(path) &&
 
1801
      (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
 
1802
      strcmp(PREFIX,FN_ROOTDIR))
 
1803
  {
 
1804
    if (strlen(PREFIX) < strlen(path))
 
1805
      path+=(size_t) strlen(PREFIX);
 
1806
    while (*path == FN_LIBCHAR)
 
1807
      path++;
 
1808
  }
 
1809
  return path;
 
1810
}
 
1811
 
 
1812
 
 
1813
static void fix_paths(string &progname)
 
1814
{
 
1815
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
 
1816
  internal::convert_dirname(drizzle_home,drizzle_home,NULL);
 
1817
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
 
1818
#if defined(HAVE_BROKEN_REALPATH)
 
1819
   internal::my_load_path(drizzle_home, drizzle_home, NULL);
 
1820
#else
 
1821
  if (!realpath(drizzle_home,rp_buff))
 
1822
    internal::my_load_path(rp_buff, drizzle_home, NULL);
 
1823
  rp_buff[FN_REFLEN-1]= '\0';
 
1824
  strcpy(drizzle_home,rp_buff);
 
1825
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
 
1826
  pos= strchr(drizzle_home, '\0');
 
1827
#endif
 
1828
  if (pos[-1] != FN_LIBCHAR)
 
1829
  {
 
1830
    pos[0]= FN_LIBCHAR;
 
1831
    pos[1]= 0;
 
1832
  }
 
1833
  internal::convert_dirname(data_home_real,data_home_real,NULL);
 
1834
  (void) internal::fn_format(buff, data_home_real, "", "",
 
1835
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
1836
  (void) internal::unpack_dirname(data_home_real_unpacked, buff);
 
1837
  internal::convert_dirname(language,language,NULL);
 
1838
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
1839
  (void) internal::my_load_path(data_home_real, data_home_real,drizzle_home);
 
1840
  (void) internal::my_load_path(pidfile_name, pidfile_name,data_home_real);
 
1841
 
 
1842
  if (opt_plugin_dir_ptr == NULL)
 
1843
  {
 
1844
    /* No plugin dir has been specified. Figure out where the plugins are */
 
1845
    if (progname[0] != FN_LIBCHAR)
 
1846
    {
 
1847
      /* We have a relative path and need to find the absolute */
 
1848
      char working_dir[FN_REFLEN];
 
1849
      char *working_dir_ptr= working_dir;
 
1850
      working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
 
1851
      string new_path(working_dir);
 
1852
      if (*(new_path.end()-1) != '/')
 
1853
        new_path.push_back('/');
 
1854
      if (progname[0] == '.' && progname[1] == '/')
 
1855
        new_path.append(progname.substr(2));
 
1856
      else
 
1857
        new_path.append(progname);
 
1858
      progname.swap(new_path);
 
1859
    }
 
1860
 
 
1861
    /* Now, trim off the exe name */
 
1862
    string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
 
1863
    if (progdir.rfind(".libs/") != string::npos)
 
1864
    {
 
1865
      progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
 
1866
    }
 
1867
    string testfile(progdir);
 
1868
    testfile.append("drizzled.lo");
 
1869
    struct stat testfile_stat;
 
1870
    if (stat(testfile.c_str(), &testfile_stat))
 
1871
    {
 
1872
      /* drizzled.lo doesn't exist - we are not in a source dir.
 
1873
       * Go on as usual
 
1874
       */
 
1875
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
 
1876
                                          drizzle_home);
 
1877
    }
 
1878
    else
 
1879
    {
 
1880
      /* We are in a source dir! Plugin dir is ../plugin/.libs */
 
1881
      size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
 
1882
      string source_plugindir(progdir.substr(0,last_libchar_pos));
 
1883
      source_plugindir.append("plugin/.libs");
 
1884
      (void) internal::my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
 
1885
    }
 
1886
  }
 
1887
  else
 
1888
  {
 
1889
    (void) internal::my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
 
1890
  }
 
1891
  opt_plugin_dir_ptr= opt_plugin_dir;
 
1892
 
 
1893
  const char *sharedir= get_relative_path(PKGDATADIR);
 
1894
  if (internal::test_if_hard_path(sharedir))
 
1895
    strncpy(buff,sharedir,sizeof(buff)-1);
 
1896
  else
 
1897
  {
 
1898
    strcpy(buff, drizzle_home);
 
1899
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
 
1900
  }
 
1901
  internal::convert_dirname(buff,buff,NULL);
 
1902
  (void) internal::my_load_path(language,language,buff);
 
1903
 
 
1904
  {
 
1905
    char *tmp_string;
2307
1906
    struct stat buf;
2308
 
    drizzle_tmpdir.clear();
2309
 
 
2310
 
    if (vm.count("tmpdir"))
2311
 
    {
2312
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
2313
 
    }
 
1907
 
 
1908
    tmp_string= getenv("TMPDIR");
 
1909
 
 
1910
    if (opt_drizzle_tmpdir)
 
1911
      drizzle_tmpdir= strdup(opt_drizzle_tmpdir);
2314
1912
    else if (tmp_string == NULL)
2315
 
    {
2316
 
      drizzle_tmpdir.append(getDataHome().file_string());
2317
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2318
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2319
 
    }
 
1913
      drizzle_tmpdir= strdup(P_tmpdir);
2320
1914
    else
2321
 
    {
2322
 
      drizzle_tmpdir.append(tmp_string);
2323
 
    }
2324
 
 
2325
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2326
 
    assert(drizzle_tmpdir.size());
2327
 
 
2328
 
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2329
 
    {
2330
 
      if (errno != EEXIST)
2331
 
      {
2332
 
        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());
2333
 
        exit(1);
2334
 
      }
2335
 
    }
2336
 
 
2337
 
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
2338
 
    {
2339
 
      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());
2340
 
      exit(1);
2341
 
    }
2342
 
  }
2343
 
 
 
1915
      drizzle_tmpdir= strdup(tmp_string);
 
1916
 
 
1917
    assert(drizzle_tmpdir);
 
1918
 
 
1919
    if (stat(drizzle_tmpdir, &buf) || (S_ISDIR(buf.st_mode) == false))
 
1920
    {
 
1921
      exit(1);
 
1922
    }
 
1923
  }
 
1924
 
 
1925
  /*
 
1926
    Convert the secure-file-priv option to system format, allowing
 
1927
    a quick strcmp to check if read or write is in an allowed dir
 
1928
   */
 
1929
  if (opt_secure_file_priv)
 
1930
  {
 
1931
    internal::convert_dirname(buff, opt_secure_file_priv, NULL);
 
1932
    free(opt_secure_file_priv);
 
1933
    opt_secure_file_priv= strdup(buff);
 
1934
    if (opt_secure_file_priv == NULL)
 
1935
      exit(1);
 
1936
  }
2344
1937
}
2345
1938
 
2346
1939
} /* namespace drizzled */