~ubuntu-branches/ubuntu/saucy/drizzle/saucy

« back to all changes in this revision

Viewing changes to .pc/fix-user-option.patch/drizzled/drizzled.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.2.11) (2.1.16 sid)
  • Revision ID: package-import@ubuntu.com-20120619104649-9ij634mxm4x8pp4l
Tags: 1:7.1.36-stable-1ubuntu1
* Merge from Debian unstable. (LP: #987575)
  Remaining changes:
  - Added upstart script.
* debian/drizzle.upstart: dropped logger since upstart logs job
  output now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include <config.h>
21
 
 
22
 
#include <drizzled/configmake.h>
23
 
#include <drizzled/atomics.h>
24
 
#include <drizzled/data_home.h>
25
 
 
26
 
#include <netdb.h>
27
 
#include <sys/types.h>
28
 
#include <netinet/tcp.h>
29
 
#include <netinet/in.h>
30
 
#include <signal.h>
31
 
#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>
49
 
#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>
54
 
#include <drizzled/item/cmpfunc.h>
55
 
#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/plugin/client.h>
60
 
#include <drizzled/plugin/error_message.h>
61
 
#include <drizzled/plugin/event_observer.h>
62
 
#include <drizzled/plugin/listen.h>
63
 
#include <drizzled/plugin/monitored_in_transaction.h>
64
 
#include <drizzled/plugin/scheduler.h>
65
 
#include <drizzled/plugin/storage_engine.h>
66
 
#include <drizzled/plugin/xa_resource_manager.h>
67
 
#include <drizzled/probes.h>
68
 
#include <drizzled/replication_services.h> /* For ReplicationServices::evaluateRegisteredPlugins() */
69
 
#include <drizzled/session.h>
70
 
#include <drizzled/session/cache.h>
71
 
#include <drizzled/show.h>
72
 
#include <drizzled/sql_base.h>
73
 
#include <drizzled/sql_parse.h>
74
 
#include <drizzled/temporal_format.h> /* For init_temporal_formats() */
75
 
#include <drizzled/tztime.h>
76
 
#include <drizzled/unireg.h>
77
 
#include <plugin/myisam/myisam.h>
78
 
#include <drizzled/typelib.h>
79
 
#include <drizzled/visibility.h>
80
 
 
81
 
#include <google/protobuf/stubs/common.h>
82
 
 
83
 
#include <drizzled/refresh_version.h>
84
 
 
85
 
#if TIME_WITH_SYS_TIME
86
 
# include <sys/time.h>
87
 
# include <time.h>
88
 
#else
89
 
# if HAVE_SYS_TIME_H
90
 
#  include <sys/time.h>
91
 
# else
92
 
#  include <time.h>
93
 
# endif
94
 
#endif
95
 
 
96
 
#ifdef HAVE_SYS_PRCTL_H
97
 
#include <sys/prctl.h>
98
 
#endif
99
 
#include <sys/socket.h>
100
 
 
101
 
 
102
 
#include <errno.h>
103
 
#include <sys/stat.h>
104
 
#include <drizzled/option.h>
105
 
#ifdef HAVE_SYSENT_H
106
 
#include <sysent.h>
107
 
#endif
108
 
#include <pwd.h>                                // For getpwent
109
 
#include <grp.h>
110
 
 
111
 
#ifdef HAVE_SELECT_H
112
 
#  include <select.h>
113
 
#endif
114
 
 
115
 
#ifdef HAVE_SYS_SELECT_H
116
 
#include <sys/select.h>
117
 
#endif
118
 
 
119
 
#include <sys/utsname.h>
120
 
 
121
 
#ifdef HAVE_SYS_MMAN_H
122
 
#include <sys/mman.h>
123
 
#endif
124
 
 
125
 
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
126
 
#include <ieeefp.h>
127
 
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
128
 
 
129
 
#ifdef HAVE_FPU_CONTROL_H
130
 
#include <fpu_control.h>
131
 
#endif
132
 
 
133
 
#ifdef HAVE_SYS_FPU_H
134
 
/* for IRIX to use set_fpc_csr() */
135
 
#include <sys/fpu.h>
136
 
#endif
137
 
 
138
 
#include <drizzled/internal/my_pthread.h>                       // For thr_setconcurency()
139
 
#include <drizzled/constrained_value.h>
140
 
 
141
 
#include <drizzled/gettext.h>
142
 
 
143
 
 
144
 
#ifdef HAVE_VALGRIND
145
 
#define IF_PURIFY(A,B) (A)
146
 
#else
147
 
#define IF_PURIFY(A,B) (B)
148
 
#endif
149
 
 
150
 
#define MAX_MEM_TABLE_SIZE SIZE_MAX
151
 
#include <iostream>
152
 
#include <fstream>
153
 
 
154
 
 
155
 
using namespace std;
156
 
namespace fs=boost::filesystem;
157
 
namespace po=boost::program_options;
158
 
namespace dpo=drizzled::program_options;
159
 
 
160
 
bool opt_daemon= false;
161
 
 
162
 
namespace drizzled
163
 
{
164
 
 
165
 
inline void setup_fpu()
166
 
{
167
 
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
168
 
  /*
169
 
     We can't handle floating point exceptions with threads, so disable
170
 
     this on freebsd.
171
 
     Don't fall for overflow, underflow,divide-by-zero or loss of precision
172
 
  */
173
 
#if defined(__i386__)
174
 
  fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
175
 
              FP_X_IMP));
176
 
#else
177
 
  fpsetmask(~(FP_X_INV |             FP_X_OFL | FP_X_UFL | FP_X_DZ |
178
 
              FP_X_IMP));
179
 
#endif /* __i386__ */
180
 
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
181
 
 
182
 
  /*
183
 
    x86 (32-bit) requires FPU precision to be explicitly set to 64 bit for
184
 
    portable results of floating point operations
185
 
  */
186
 
#if defined(__i386__) && defined(HAVE_FPU_CONTROL_H) && defined(_FPU_DOUBLE)
187
 
  fpu_control_t cw;
188
 
  _FPU_GETCW(cw);
189
 
  cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
190
 
  _FPU_SETCW(cw);
191
 
#endif /* __i386__ && HAVE_FPU_CONTROL_H && _FPU_DOUBLE */
192
 
}
193
 
 
194
 
#ifdef SOLARIS
195
 
extern "C" int gethostname(char *name, int namelen);
196
 
#endif
197
 
 
198
 
const char *first_keyword= "first";
199
 
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
200
 
 
201
 
#define GET_HA_ROWS GET_ULL
202
 
 
203
 
const char *tx_isolation_names[] =
204
 
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
205
 
  NULL};
206
 
 
207
 
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
208
 
                               tx_isolation_names, NULL};
209
 
 
210
 
/*
211
 
  Used with --help for detailed option
212
 
*/
213
 
bool opt_help= false;
214
 
 
215
 
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
216
 
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
217
 
 {&Arg_comparator::compare_real,       &Arg_comparator::compare_e_real},
218
 
 {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
219
 
 {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
220
 
 {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
221
 
 
222
 
/* static variables */
223
 
 
224
 
static bool opt_debugging= false;
225
 
static uint32_t wake_thread;
226
 
static char *drizzled_chroot;
227
 
static const char *default_character_set_name;
228
 
static const char *character_set_filesystem_name;
229
 
static char *lc_time_names_name;
230
 
static char *default_collation_name;
231
 
static char *default_storage_engine_str;
232
 
static const char *compiled_default_collation_name= "utf8_general_ci";
233
 
 
234
 
/* Global variables */
235
 
 
236
 
char *drizzled_user;
237
 
bool volatile select_thread_in_use;
238
 
bool volatile abort_loop;
239
 
DRIZZLED_API bool volatile shutdown_in_progress;
240
 
char *opt_scheduler_default;
241
 
const char *opt_scheduler= NULL;
242
 
 
243
 
DRIZZLED_API size_t my_thread_stack_size= 0;
244
 
 
245
 
/*
246
 
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
247
 
*/
248
 
plugin::StorageEngine *heap_engine;
249
 
plugin::StorageEngine *myisam_engine;
250
 
 
251
 
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
252
 
 
253
 
uint32_t drizzled_bind_timeout;
254
 
uint32_t dropping_tables, ha_open_options;
255
 
uint32_t tc_heuristic_recover= 0;
256
 
uint64_t session_startup_options;
257
 
back_log_constraints back_log(50);
258
 
DRIZZLED_API uint32_t server_id;
259
 
uint64_t table_cache_size;
260
 
size_t table_def_size;
261
 
uint32_t global_thread_id= 1UL;
262
 
pid_t current_pid;
263
 
 
264
 
extern const double log_10[309];
265
 
 
266
 
const double log_10[] = {
267
 
  1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
268
 
  1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
269
 
  1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029,
270
 
  1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039,
271
 
  1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049,
272
 
  1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059,
273
 
  1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069,
274
 
  1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079,
275
 
  1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089,
276
 
  1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099,
277
 
  1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
278
 
  1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
279
 
  1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
280
 
  1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
281
 
  1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
282
 
  1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
283
 
  1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
284
 
  1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
285
 
  1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
286
 
  1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
287
 
  1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
288
 
  1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
289
 
  1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
290
 
  1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
291
 
  1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
292
 
  1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
293
 
  1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
294
 
  1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
295
 
  1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
296
 
  1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
297
 
  1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308
298
 
};
299
 
 
300
 
time_t server_start_time;
301
 
time_t flush_status_time;
302
 
 
303
 
fs::path basedir(PREFIX);
304
 
fs::path pid_file;
305
 
fs::path secure_file_priv("");
306
 
fs::path plugin_dir;
307
 
fs::path system_config_dir(SYSCONFDIR);
308
 
 
309
 
 
310
 
char *opt_tc_log_file;
311
 
const key_map key_map_empty(0);
312
 
key_map key_map_full(0);                        // Will be initialized later
313
 
 
314
 
std::string drizzle_tmpdir;
315
 
char *opt_drizzle_tmpdir= NULL;
316
 
 
317
 
/** name of reference on left espression in rewritten IN subquery */
318
 
const char *in_left_expr_name= "<left expr>";
319
 
/** name of additional condition */
320
 
const char *in_additional_cond= "<IN COND>";
321
 
const char *in_having_cond= "<IN HAVING>";
322
 
 
323
 
/* classes for comparation parsing/processing */
324
 
 
325
 
FILE *stderror_file=0;
326
 
 
327
 
drizzle_system_variables global_system_variables;
328
 
drizzle_system_variables max_system_variables;
329
 
global_counters current_global_counters;
330
 
 
331
 
DRIZZLED_API const CHARSET_INFO *system_charset_info;
332
 
const CHARSET_INFO *files_charset_info;
333
 
const CHARSET_INFO *table_alias_charset;
334
 
const CHARSET_INFO *character_set_filesystem;
335
 
 
336
 
MY_LOCALE *my_default_lc_time_names;
337
 
 
338
 
SHOW_COMP_OPTION have_symlink;
339
 
 
340
 
boost::condition_variable_any COND_refresh;
341
 
boost::condition_variable COND_thread_count;
342
 
pthread_t signal_thread;
343
 
 
344
 
/* Static variables */
345
 
 
346
 
int cleanup_done;
347
 
 
348
 
passwd *user_info;
349
 
 
350
 
boost::detail::atomic_count connection_count(0);
351
 
 
352
 
global_buffer_constraint<uint64_t> global_sort_buffer(0);
353
 
global_buffer_constraint<uint64_t> global_join_buffer(0);
354
 
global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
355
 
global_buffer_constraint<uint64_t> global_read_buffer(0);
356
 
 
357
 
DRIZZLED_API size_t transaction_message_threshold;
358
 
 
359
 
static void drizzle_init_variables(void);
360
 
static void get_options();
361
 
static void fix_paths();
362
 
 
363
 
static void usage(void);
364
 
void close_connections(void);
365
 
 
366
 
fs::path base_plugin_dir(PKGPLUGINDIR);
367
 
 
368
 
po::options_description config_options(_("Config File Options"));
369
 
po::options_description long_options(_("Kernel Options"));
370
 
po::options_description plugin_load_options(_("Plugin Loading Options"));
371
 
po::options_description plugin_options(_("Plugin Options"));
372
 
po::options_description initial_options(_("Config and Plugin Loading"));
373
 
po::options_description full_options(_("Kernel and Plugin Loading and Plugin"));
374
 
vector<string> unknown_options;
375
 
vector<string> defaults_file_list;
376
 
po::variables_map vm;
377
 
 
378
 
po::variables_map &getVariablesMap()
379
 
{
380
 
  return vm;
381
 
}
382
 
 
383
 
namespace
384
 
{
385
 
 
386
 
std::string &getGlobHostname()
387
 
{
388
 
  static std::string glob_hostname("localhost");
389
 
  return glob_hostname;
390
 
}
391
 
 
392
 
void setServerHostname(const std::string &hostname)
393
 
{
394
 
  getGlobHostname()= hostname;
395
 
}
396
 
}
397
 
 
398
 
const std::string &getServerHostname()
399
 
{
400
 
  return getGlobHostname();
401
 
}
402
 
 
403
 
/****************************************************************************
404
 
** Code to end drizzled
405
 
****************************************************************************/
406
 
 
407
 
void close_connections(void)
408
 
{
409
 
  /* Abort listening to new connections */
410
 
  plugin::Listen::shutdown();
411
 
 
412
 
  /* kill connection thread */
413
 
  {
414
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
415
 
 
416
 
    while (select_thread_in_use)
417
 
    {
418
 
      boost::xtime xt;
419
 
      xtime_get(&xt, boost::TIME_UTC);
420
 
      xt.sec += 2;
421
 
 
422
 
      for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
423
 
      {
424
 
        bool success= COND_thread_count.timed_wait(scopedLock, xt);
425
 
        if (not success)
426
 
          break;
427
 
      }
428
 
    }
429
 
  }
430
 
 
431
 
 
432
 
  /*
433
 
    First signal all threads that it's time to die
434
 
    This will give the threads some time to gracefully abort their
435
 
    statements and inform their clients that the server is about to die.
436
 
  */
437
 
 
438
 
  {
439
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
440
 
    session::Cache::list list= session::Cache::singleton().getCache();
441
 
 
442
 
    for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
443
 
    {
444
 
      Session::shared_ptr tmp(*it);
445
 
 
446
 
      tmp->setKilled(Session::KILL_CONNECTION);
447
 
      tmp->scheduler->killSession(tmp.get());
448
 
      DRIZZLE_CONNECTION_DONE(tmp->thread_id);
449
 
 
450
 
      tmp->lockOnSys();
451
 
    }
452
 
  }
453
 
 
454
 
  if (session::Cache::singleton().count())
455
 
    sleep(2);                                   // Give threads time to die
456
 
 
457
 
  /*
458
 
    Force remaining threads to die by closing the connection to the client
459
 
    This will ensure that threads that are waiting for a command from the
460
 
    client on a blocking read call are aborted.
461
 
  */
462
 
  for (;;)
463
 
  {
464
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
465
 
    session::Cache::list list= session::Cache::singleton().getCache();
466
 
 
467
 
    if (list.empty())
468
 
    {
469
 
      break;
470
 
    }
471
 
    /* Close before unlock, avoiding crash. See LP bug#436685 */
472
 
    list.front()->getClient()->close();
473
 
  }
474
 
}
475
 
 
476
 
 
477
 
void unireg_abort(int exit_code)
478
 
{
479
 
 
480
 
  if (exit_code)
481
 
  {
482
 
    errmsg_printf(error::ERROR, _("Aborting"));
483
 
  }
484
 
  else if (opt_help)
485
 
  {
486
 
    usage();
487
 
  }
488
 
 
489
 
  clean_up(!opt_help && (exit_code));
490
 
  internal::my_end();
491
 
  exit(exit_code);
492
 
}
493
 
 
494
 
 
495
 
void clean_up(bool print_message)
496
 
{
497
 
  if (cleanup_done++)
498
 
    return;
499
 
 
500
 
  table_cache_free();
501
 
  free_charsets();
502
 
  module::Registry &modules= module::Registry::singleton();
503
 
  modules.shutdownModules();
504
 
 
505
 
  deinit_temporal_formats();
506
 
 
507
 
#if GOOGLE_PROTOBUF_VERSION >= 2001000
508
 
  google::protobuf::ShutdownProtobufLibrary();
509
 
#endif
510
 
 
511
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
512
 
 
513
 
  if (print_message && server_start_time)
514
 
    errmsg_printf(drizzled::error::INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
515
 
 
516
 
  session::Cache::singleton().shutdownFirst();
517
 
 
518
 
  /*
519
 
    The following lines may never be executed as the main thread may have
520
 
    killed us
521
 
  */
522
 
} /* clean_up */
523
 
 
524
 
 
525
 
/* Change to run as another user if started with --user */
526
 
 
527
 
passwd *check_user(const char *user)
528
 
{
529
 
  passwd *tmp_user_info;
530
 
  uid_t user_id= geteuid();
531
 
 
532
 
  // Don't bother if we aren't superuser
533
 
  if (user_id)
534
 
  {
535
 
    if (user)
536
 
    {
537
 
      /* Don't give a warning, if real user is same as given with --user */
538
 
      tmp_user_info= getpwnam(user);
539
 
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
540
 
          global_system_variables.log_warnings)
541
 
            errmsg_printf(error::WARN, _("One can only use the --user switch "
542
 
                            "if running as root\n"));
543
 
    }
544
 
    return NULL;
545
 
  }
546
 
  if (not user)
547
 
  {
548
 
      errmsg_printf(error::ERROR, _("Fatal error: Please read \"Security\" section of "
549
 
                                    "the manual to find out how to run drizzled as root"));
550
 
    unireg_abort(1);
551
 
  }
552
 
 
553
 
  if (not strcmp(user, "root"))
554
 
    return NULL;                        // Avoid problem with dynamic libraries
555
 
 
556
 
  if (!(tmp_user_info= getpwnam(user)))
557
 
  {
558
 
    // Allow a numeric uid to be used
559
 
    const char *pos;
560
 
    for (pos= user; my_isdigit(&my_charset_utf8_general_ci,*pos); pos++) ;
561
 
    if (*pos)                                   // Not numeric id
562
 
      goto err;
563
 
    if (!(tmp_user_info= getpwuid(atoi(user))))
564
 
      goto err;
565
 
  }
566
 
  return tmp_user_info;
567
 
 
568
 
err:
569
 
  errmsg_printf(error::ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
570
 
                    "Please check that the user exists!\n"),user);
571
 
  unireg_abort(1);
572
 
 
573
 
#ifdef PR_SET_DUMPABLE
574
 
  if (getDebug().test(debug::CORE_ON_SIGNAL))
575
 
  {
576
 
    /* inform kernel that process is dumpable */
577
 
    (void) prctl(PR_SET_DUMPABLE, 1);
578
 
  }
579
 
#endif
580
 
 
581
 
/* Sun Studio 5.10 doesn't like this line.  5.9 requires it */
582
 
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590)
583
 
  return NULL;
584
 
#endif
585
 
 
586
 
}
587
 
 
588
 
void set_user(const char *user, passwd *user_info_arg)
589
 
{
590
 
  assert(user_info_arg != 0);
591
 
  initgroups((char*) user, user_info_arg->pw_gid);
592
 
  if (setgid(user_info_arg->pw_gid) == -1)
593
 
  {
594
 
    sql_perror(_("Set process group ID failed"));
595
 
    unireg_abort(1);
596
 
  }
597
 
  if (setuid(user_info_arg->pw_uid) == -1)
598
 
  {
599
 
    sql_perror(_("Set process user ID failed"));
600
 
    unireg_abort(1);
601
 
  }
602
 
}
603
 
 
604
 
 
605
 
 
606
 
/** Change root user if started with @c --chroot . */
607
 
static void set_root(const char *path)
608
 
{
609
 
  if ((chroot(path) == -1) || !chdir("/"))
610
 
  {
611
 
    sql_perror(_("Process chroot failed"));
612
 
    unireg_abort(1);
613
 
  }
614
 
}
615
 
 
616
 
 
617
 
/*
618
 
  Unlink session from global list of available connections and free session
619
 
 
620
 
  SYNOPSIS
621
 
    Session::unlink()
622
 
    session              Thread handler
623
 
*/
624
 
 
625
 
void drizzled::Session::unlink(session_id_t &session_id)
626
 
{
627
 
  Session::shared_ptr session= session::Cache::singleton().find(session_id);
628
 
 
629
 
  if (session)
630
 
    unlink(session);
631
 
}
632
 
 
633
 
void drizzled::Session::unlink(Session::shared_ptr &session)
634
 
{
635
 
  --connection_count;
636
 
 
637
 
  session->cleanup();
638
 
 
639
 
  boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
640
 
 
641
 
  if (unlikely(plugin::EventObserver::disconnectSession(*session)))
642
 
  {
643
 
    // We should do something about an error...
644
 
  }
645
 
  session::Cache::singleton().erase(session);
646
 
}
647
 
 
648
 
 
649
 
#ifndef SA_RESETHAND
650
 
#define SA_RESETHAND 0
651
 
#endif
652
 
#ifndef SA_NODEFER
653
 
#define SA_NODEFER 0
654
 
#endif
655
 
 
656
 
 
657
 
 
658
 
 
659
 
const char *load_default_groups[]=
660
 
{
661
 
  DRIZZLE_CONFIG_NAME, "server", 0, 0
662
 
};
663
 
 
664
 
static void find_plugin_dir(string progname)
665
 
{
666
 
  fs::path full_progname(fs::system_complete(progname));
667
 
 
668
 
  fs::path progdir(full_progname.parent_path());
669
 
  if (progdir.filename() == ".libs")
670
 
  {
671
 
    progdir= progdir.parent_path();
672
 
  }
673
 
 
674
 
  if (fs::exists(progdir / "drizzled.lo") || fs::exists(progdir / "drizzled.o"))
675
 
  {
676
 
    /* We are in a source dir! Plugin dir is ../plugin/.libs */
677
 
    base_plugin_dir= progdir.parent_path();
678
 
    base_plugin_dir /= "plugin";
679
 
    base_plugin_dir /= ".libs";
680
 
  }
681
 
 
682
 
  if (plugin_dir.root_directory() == "")
683
 
  {
684
 
    fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
685
 
    full_plugin_dir /= plugin_dir;
686
 
    plugin_dir= full_plugin_dir;
687
 
  }
688
 
}
689
 
 
690
 
static void notify_plugin_dir(fs::path in_plugin_dir)
691
 
{
692
 
  plugin_dir= in_plugin_dir;
693
 
  if (plugin_dir.root_directory() == "")
694
 
  {
695
 
    fs::path full_plugin_dir(fs::system_complete(basedir));
696
 
    full_plugin_dir /= plugin_dir;
697
 
    plugin_dir= full_plugin_dir;
698
 
  }
699
 
}
700
 
 
701
 
static void expand_secure_file_priv(fs::path in_secure_file_priv)
702
 
{
703
 
  secure_file_priv= fs::system_complete(in_secure_file_priv);
704
 
}
705
 
 
706
 
static void check_limits_aii(uint64_t in_auto_increment_increment)
707
 
{
708
 
  global_system_variables.auto_increment_increment= 1;
709
 
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
710
 
  {
711
 
    cout << _("Error: Invalid Value for auto_increment_increment");
712
 
    exit(-1);
713
 
  }
714
 
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
715
 
}
716
 
 
717
 
static void check_limits_aio(uint64_t in_auto_increment_offset)
718
 
{
719
 
  global_system_variables.auto_increment_offset= 1;
720
 
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
721
 
  {
722
 
    cout << _("Error: Invalid Value for auto_increment_offset");
723
 
    exit(-1);
724
 
  }
725
 
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
726
 
}
727
 
 
728
 
static void check_limits_completion_type(uint32_t in_completion_type)
729
 
{
730
 
  global_system_variables.completion_type= 0;
731
 
  if (in_completion_type > 2)
732
 
  {
733
 
    cout << _("Error: Invalid Value for completion_type");
734
 
    exit(-1);
735
 
  }
736
 
  global_system_variables.completion_type= in_completion_type;
737
 
}
738
 
 
739
 
 
740
 
static void check_limits_dpi(uint32_t in_div_precincrement)
741
 
{
742
 
  global_system_variables.div_precincrement= 4;
743
 
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
744
 
  {
745
 
    cout << _("Error: Invalid Value for div-precision-increment");
746
 
    exit(-1);
747
 
  }
748
 
  global_system_variables.div_precincrement= in_div_precincrement;
749
 
}
750
 
 
751
 
static void check_limits_gcml(uint64_t in_group_concat_max_len)
752
 
{
753
 
  global_system_variables.group_concat_max_len= 1024;
754
 
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
755
 
  {
756
 
    cout << _("Error: Invalid Value for group_concat_max_len");
757
 
    exit(-1);
758
 
  }
759
 
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
760
 
}
761
 
 
762
 
static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
763
 
{
764
 
  global_system_variables.join_buff_size= (128*1024L);
765
 
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
766
 
  {
767
 
    cout << _("Error: Invalid Value for join_buffer_size");
768
 
    exit(-1);
769
 
  }
770
 
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
771
 
  global_system_variables.join_buff_size= in_join_buffer_size;
772
 
}
773
 
 
774
 
static void check_limits_map(uint32_t in_max_allowed_packet)
775
 
{
776
 
  global_system_variables.max_allowed_packet= (64*1024*1024L);
777
 
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
778
 
  {
779
 
    cout << _("Error: Invalid Value for max_allowed_packet");
780
 
    exit(-1);
781
 
  }
782
 
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
783
 
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
784
 
}
785
 
 
786
 
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
787
 
{
788
 
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
789
 
  if (in_max_error_count > 65535)
790
 
  {
791
 
    cout << _("Error: Invalid Value for max_error_count");
792
 
    exit(-1);
793
 
  }
794
 
  global_system_variables.max_error_count= in_max_error_count;
795
 
}
796
 
 
797
 
static void check_limits_mhts(uint64_t in_max_heap_table_size)
798
 
{
799
 
  global_system_variables.max_heap_table_size= (16*1024*1024L);
800
 
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
801
 
  {
802
 
    cout << _("Error: Invalid Value for max_heap_table_size");
803
 
    exit(-1);
804
 
  }
805
 
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
806
 
  global_system_variables.max_heap_table_size= in_max_heap_table_size;
807
 
}
808
 
 
809
 
static void check_limits_merl(uint64_t in_min_examined_row_limit)
810
 
{
811
 
  global_system_variables.min_examined_row_limit= 0;
812
 
  if (in_min_examined_row_limit > ULONG_MAX)
813
 
  {
814
 
    cout << _("Error: Invalid Value for min_examined_row_limit");
815
 
    exit(-1);
816
 
  }
817
 
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
818
 
}
819
 
 
820
 
static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
821
 
{
822
 
  global_system_variables.max_join_size= INT32_MAX;
823
 
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
824
 
  {
825
 
    cout << _("Error: Invalid Value for max_join_size");
826
 
    exit(-1);
827
 
  }
828
 
  global_system_variables.max_join_size= in_max_join_size;
829
 
}
830
 
 
831
 
static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
832
 
{
833
 
  global_system_variables.max_length_for_sort_data= 1024;
834
 
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
835
 
  {
836
 
    cout << _("Error: Invalid Value for max_length_for_sort_data");
837
 
    exit(-1);
838
 
  }
839
 
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
840
 
}
841
 
 
842
 
static void check_limits_msfk(uint64_t in_max_seeks_for_key)
843
 
{
844
 
  global_system_variables.max_seeks_for_key= ULONG_MAX;
845
 
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
846
 
  {
847
 
    cout << _("Error: Invalid Value for max_seeks_for_key");
848
 
    exit(-1);
849
 
  }
850
 
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
851
 
}
852
 
 
853
 
static void check_limits_max_sort_length(size_t in_max_sort_length)
854
 
{
855
 
  global_system_variables.max_sort_length= 1024;
856
 
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
857
 
  {
858
 
    cout << _("Error: Invalid Value for max_sort_length");
859
 
    exit(-1);
860
 
  }
861
 
  global_system_variables.max_sort_length= in_max_sort_length;
862
 
}
863
 
 
864
 
static void check_limits_osd(uint32_t in_optimizer_search_depth)
865
 
{
866
 
  global_system_variables.optimizer_search_depth= 0;
867
 
  if (in_optimizer_search_depth > MAX_TABLES + 2)
868
 
  {
869
 
    cout << _("Error: Invalid Value for optimizer_search_depth");
870
 
    exit(-1);
871
 
  }
872
 
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
873
 
}
874
 
 
875
 
static void check_limits_pbs(uint64_t in_preload_buff_size)
876
 
{
877
 
  global_system_variables.preload_buff_size= (32*1024L);
878
 
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
879
 
  {
880
 
    cout << _("Error: Invalid Value for preload_buff_size");
881
 
    exit(-1);
882
 
  }
883
 
  global_system_variables.preload_buff_size= in_preload_buff_size;
884
 
}
885
 
 
886
 
static void check_limits_qabs(uint32_t in_query_alloc_block_size)
887
 
{
888
 
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
889
 
  if (in_query_alloc_block_size < 1024)
890
 
  {
891
 
    cout << _("Error: Invalid Value for query_alloc_block_size");
892
 
    exit(-1);
893
 
  }
894
 
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
895
 
  global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
896
 
}
897
 
 
898
 
static void check_limits_qps(uint32_t in_query_prealloc_size)
899
 
{
900
 
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
901
 
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
902
 
  {
903
 
    cout << _("Error: Invalid Value for query_prealloc_size");
904
 
    exit(-1);
905
 
  }
906
 
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
907
 
  global_system_variables.query_prealloc_size= in_query_prealloc_size;
908
 
}
909
 
 
910
 
static void check_limits_rabs(size_t in_range_alloc_block_size)
911
 
{
912
 
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
913
 
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
914
 
  {
915
 
    cout << _("Error: Invalid Value for range_alloc_block_size");
916
 
    exit(-1);
917
 
  }
918
 
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
919
 
  global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
920
 
}
921
 
 
922
 
static void check_limits_read_buffer_size(int32_t in_read_buff_size)
923
 
{
924
 
  global_system_variables.read_buff_size= (128*1024L);
925
 
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
926
 
  {
927
 
    cout << _("Error: Invalid Value for read_buff_size");
928
 
    exit(-1);
929
 
  }
930
 
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
931
 
  global_system_variables.read_buff_size= in_read_buff_size;
932
 
}
933
 
 
934
 
static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
935
 
{
936
 
  global_system_variables.read_rnd_buff_size= (256*1024L);
937
 
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
938
 
  {
939
 
    cout << _("Error: Invalid Value for read_rnd_buff_size");
940
 
    exit(-1);
941
 
  }
942
 
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
943
 
}
944
 
 
945
 
static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
946
 
{
947
 
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
948
 
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
949
 
  {
950
 
    cout << _("Error: Invalid Value for sort_buff_size");
951
 
    exit(-1);
952
 
  }
953
 
  global_system_variables.sortbuff_size= in_sortbuff_size;
954
 
}
955
 
 
956
 
static void check_limits_tdc(uint32_t in_table_def_size)
957
 
{
958
 
  table_def_size= 128;
959
 
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
960
 
  {
961
 
    cout << _("Error: Invalid Value for table_def_size");
962
 
    exit(-1);
963
 
  }
964
 
  table_def_size= in_table_def_size;
965
 
}
966
 
 
967
 
static void check_limits_toc(uint32_t in_table_cache_size)
968
 
{
969
 
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
970
 
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
971
 
  {
972
 
    cout << _("Error: Invalid Value for table_cache_size");
973
 
    exit(-1);
974
 
  }
975
 
  table_cache_size= in_table_cache_size;
976
 
}
977
 
 
978
 
static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
979
 
{
980
 
  table_lock_wait_timeout= 50;
981
 
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
982
 
  {
983
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
984
 
    exit(-1);
985
 
  }
986
 
  table_lock_wait_timeout= in_table_lock_wait_timeout;
987
 
}
988
 
 
989
 
static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
990
 
{
991
 
  my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
992
 
}
993
 
 
994
 
static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
995
 
{
996
 
  global_system_variables.tmp_table_size= 16*1024*1024L;
997
 
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
998
 
  {
999
 
    cout << _("Error: Invalid Value for table_lock_wait_timeout");
1000
 
    exit(-1);
1001
 
  }
1002
 
  global_system_variables.tmp_table_size= in_tmp_table_size;
1003
 
}
1004
 
 
1005
 
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1006
 
{
1007
 
  transaction_message_threshold= 1024*1024;
1008
 
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1009
 
  {
1010
 
    cout << _("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1011
 
    exit(-1);
1012
 
  }
1013
 
  transaction_message_threshold= in_transaction_message_threshold;
1014
 
}
1015
 
 
1016
 
static void process_defaults_files()
1017
 
{
1018
 
  for (vector<string>::iterator iter= defaults_file_list.begin();
1019
 
       iter != defaults_file_list.end();
1020
 
       ++iter)
1021
 
  {
1022
 
    fs::path file_location= *iter;
1023
 
 
1024
 
    ifstream input_defaults_file(file_location.file_string().c_str());
1025
 
 
1026
 
    po::parsed_options file_parsed=
1027
 
      dpo::parse_config_file(input_defaults_file, full_options, true);
1028
 
    vector<string> file_unknown=
1029
 
      po::collect_unrecognized(file_parsed.options, po::include_positional);
1030
 
 
1031
 
    for (vector<string>::iterator it= file_unknown.begin();
1032
 
         it != file_unknown.end();
1033
 
         ++it)
1034
 
    {
1035
 
      string new_unknown_opt("--");
1036
 
      new_unknown_opt.append(*it);
1037
 
      ++it;
1038
 
      if (it != file_unknown.end())
1039
 
      {
1040
 
        if ((*it) != "true")
1041
 
        {
1042
 
          new_unknown_opt.push_back('=');
1043
 
          new_unknown_opt.append(*it);
1044
 
        }
1045
 
      }
1046
 
      else
1047
 
      {
1048
 
        break;
1049
 
      }
1050
 
      unknown_options.push_back(new_unknown_opt);
1051
 
    }
1052
 
    store(file_parsed, vm);
1053
 
  }
1054
 
}
1055
 
 
1056
 
static void compose_defaults_file_list(vector<string> in_options)
1057
 
{
1058
 
  for (vector<string>::iterator it= in_options.begin();
1059
 
       it != in_options.end();
1060
 
       ++it)
1061
 
  {
1062
 
    fs::path p(*it);
1063
 
    if (fs::is_regular_file(p))
1064
 
      defaults_file_list.push_back(*it);
1065
 
    else
1066
 
    {
1067
 
      errmsg_printf(error::ERROR,
1068
 
                  _("Defaults file '%s' not found\n"), (*it).c_str());
1069
 
      unireg_abort(1);
1070
 
    }
1071
 
 
1072
 
  }
1073
 
}
1074
 
 
1075
 
int init_basic_variables(int argc, char **argv)
1076
 
{
1077
 
  time_t curr_time;
1078
 
  umask(((~internal::my_umask) & 0666));
1079
 
  decimal_zero.set_zero(); // set decimal_zero constant;
1080
 
  tzset();                      // Set tzname
1081
 
 
1082
 
  curr_time= time(NULL);
1083
 
  if (curr_time == (time_t)-1)
1084
 
    return 1;
1085
 
 
1086
 
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1087
 
  server_start_time= flush_status_time= curr_time;
1088
 
 
1089
 
  drizzle_init_variables();
1090
 
 
1091
 
  find_plugin_dir(argv[0]);
1092
 
 
1093
 
  /*
1094
 
    We set SYSTEM time zone as reasonable default and
1095
 
    also for failure of my_tz_init() and bootstrap mode.
1096
 
    If user explicitly set time zone with --default-time-zone
1097
 
    option we will change this value in my_tz_init().
1098
 
  */
1099
 
  global_system_variables.time_zone= my_tz_SYSTEM;
1100
 
 
1101
 
  char ret_hostname[FN_REFLEN];
1102
 
  if (gethostname(ret_hostname,sizeof(ret_hostname)) < 0)
1103
 
  {
1104
 
    errmsg_printf(error::WARN,
1105
 
                  _("gethostname failed, using '%s' as hostname"),
1106
 
                  getServerHostname().c_str());
1107
 
    pid_file= "drizzle";
1108
 
  }
1109
 
  else
1110
 
  {
1111
 
    setServerHostname(ret_hostname);
1112
 
    pid_file= getServerHostname();
1113
 
  }
1114
 
  pid_file.replace_extension(".pid");
1115
 
 
1116
 
  system_config_dir /= "drizzle";
1117
 
 
1118
 
  config_options.add_options()
1119
 
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1120
 
  _("Display this help and exit."))
1121
 
  ("daemon,d", po::value<bool>(&opt_daemon)->default_value(false)->zero_tokens(),
1122
 
  _("Run as a daemon."))
1123
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1124
 
  _("Configuration file defaults are not used if no-defaults is set"))
1125
 
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1126
 
  _("Configuration file to use"))
1127
 
  ("config-dir", po::value<fs::path>(&system_config_dir),
1128
 
  _("Base location for config files"))
1129
 
  ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(&notify_plugin_dir),
1130
 
  _("Directory for plugins."))
1131
 
  ;
1132
 
 
1133
 
  plugin_load_options.add_options()
1134
 
  ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1135
 
  _("Optional comma separated list of plugins to load at startup in addition "
1136
 
     "to the default list of plugins. "
1137
 
     "[for example: --plugin_add=crc32,logger_gearman]"))
1138
 
  ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1139
 
  _("Optional comma separated list of plugins to not load at startup. Effectively "
1140
 
     "removes a plugin from the list of plugins to be loaded. "
1141
 
     "[for example: --plugin_remove=crc32,logger_gearman]"))
1142
 
  ("plugin-load", po::value<string>()->notifier(&notify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1143
 
  _("Optional comma separated list of plugins to load at starup instead of "
1144
 
     "the default plugin load list. "
1145
 
     "[for example: --plugin_load=crc32,logger_gearman]"))
1146
 
  ;
1147
 
 
1148
 
  long_options.add_options()
1149
 
  ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1150
 
  _("Auto-increment columns are incremented by this"))
1151
 
  ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1152
 
  _("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1153
 
  ("basedir,b", po::value<fs::path>(&basedir),
1154
 
  _("Path to installation directory. All paths are usually resolved "
1155
 
     "relative to this."))
1156
 
  ("chroot,r", po::value<string>(),
1157
 
  _("Chroot drizzled daemon during startup."))
1158
 
  ("collation-server", po::value<string>(),
1159
 
  _("Set the default collation."))
1160
 
  ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1161
 
  _("Default completion type."))
1162
 
  ("core-file",  _("Write core on errors."))
1163
 
  ("datadir", po::value<fs::path>(&getDataHome()),
1164
 
  _("Path to the database root."))
1165
 
  ("default-storage-engine", po::value<string>(),
1166
 
  _("Set the default storage engine for tables."))
1167
 
  ("default-time-zone", po::value<string>(),
1168
 
  _("Set the default time zone."))
1169
 
  ("exit-info,T", po::value<long>(),
1170
 
  _("Used for debugging;  Use at your own risk!"))
1171
 
  ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1172
 
  _("Set up signals usable for debugging"))
1173
 
  ("lc-time-name", po::value<string>(),
1174
 
  _("Set the language used for the month names and the days of the week."))
1175
 
  ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1176
 
  _("Log some not critical warnings to the log file."))
1177
 
  ("pid-file", po::value<fs::path>(&pid_file),
1178
 
  _("Pid file used by drizzled."))
1179
 
  ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1180
 
  _("Maximum time in seconds to wait for the port to become free. "))
1181
 
  ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1182
 
  _("Include the SQL query in replicated protobuf messages."))
1183
 
  ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1184
 
  _("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1185
 
     "within specified directory"))
1186
 
  ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1187
 
  _("Uniquely identifies the server instance in the community of "
1188
 
     "replication partners."))
1189
 
  ("skip-stack-trace",
1190
 
  _("Don't print a stack trace on failure."))
1191
 
  ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1192
 
  _("Enable symbolic link support."))
1193
 
  ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1194
 
  _("Specify whether to time mutexes (only InnoDB mutexes are currently "
1195
 
     "supported)"))
1196
 
  ("tmpdir,t", po::value<string>(),
1197
 
  _("Path for temporary files."))
1198
 
  ("transaction-isolation", po::value<string>(),
1199
 
  _("Default transaction isolation level."))
1200
 
  ("transaction-message-threshold", po::value<size_t>(&transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1201
 
  _("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1202
 
  ("user,u", po::value<string>(),
1203
 
  _("Run drizzled daemon as user."))
1204
 
  ("version,V",
1205
 
  _("Output version information and exit."))
1206
 
  ("back-log", po::value<back_log_constraints>(&back_log),
1207
 
  _("The number of outstanding connection requests Drizzle can have. This "
1208
 
     "comes into play when the main Drizzle thread gets very many connection "
1209
 
     "requests in a very short time."))
1210
 
  ("bulk-insert-buffer-size",
1211
 
  po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1212
 
  _("Size of tree cache used in bulk insert optimization. Note that this is "
1213
 
     "a limit per thread!"))
1214
 
  ("div-precision-increment",  po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1215
 
  _("Precision of the result of '/' operator will be increased on that "
1216
 
     "value."))
1217
 
  ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1218
 
  _("The maximum length of the result of function  group_concat."))
1219
 
  ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1220
 
  _("The size of the buffer that is used for full joins."))
1221
 
  ("join-heap-threshold",
1222
 
  po::value<uint64_t>()->default_value(0),
1223
 
  _("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1224
 
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1225
 
  _("Max packetlength to send/receive from to server."))
1226
 
  ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1227
 
  _("Max number of errors/warnings to store for a statement."))
1228
 
  ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1229
 
  _("Don't allow creation of heap tables bigger than this."))
1230
 
  ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1231
 
  _("Joins that are probably going to read more than max_join_size records "
1232
 
     "return an error."))
1233
 
  ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1234
 
  _("Max number of bytes in sorted records."))
1235
 
  ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1236
 
  _("Limit assumed max number of seeks when looking up rows based on a key"))
1237
 
  ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),
1238
 
  _("The number of bytes to use when sorting BLOB or TEXT values "
1239
 
     "(only the first max_sort_length bytes of each value are used; the "
1240
 
     "rest are ignored)."))
1241
 
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1242
 
  _("After this many write locks, allow some read locks to run in between."))
1243
 
  ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1244
 
  _("Don't log queries which examine less than min_examined_row_limit "
1245
 
     "rows to file."))
1246
 
  ("disable-optimizer-prune",
1247
 
  _("Do not apply any heuristic(s) during query optimization to prune, "
1248
 
     "thus perform an exhaustive search from the optimizer search space."))
1249
 
  ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1250
 
  _("Maximum depth of search performed by the query optimizer. Values "
1251
 
     "larger than the number of relations in a query result in better query "
1252
 
     "plans, but take longer to compile a query. Smaller values than the "
1253
 
     "number of tables in a relation result in faster optimization, but may "
1254
 
     "produce very bad query plans. If set to 0, the system will "
1255
 
     "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1256
 
     "optimizer will switch to the original find_best (used for "
1257
 
     "testing/comparison)."))
1258
 
  ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1259
 
  _("The size of the buffer that is allocated when preloading indexes"))
1260
 
  ("query-alloc-block-size",
1261
 
  po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1262
 
  _("Allocation block size for query parsing and execution"))
1263
 
  ("query-prealloc-size",
1264
 
  po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1265
 
  _("Persistent buffer for query parsing and execution"))
1266
 
  ("range-alloc-block-size",
1267
 
  po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1268
 
  _("Allocation block size for storing ranges during optimization"))
1269
 
  ("read-buffer-size",
1270
 
  po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1271
 
  _("Each thread that does a sequential scan allocates a buffer of this "
1272
 
      "size for each table it scans. If you do many sequential scans, you may "
1273
 
      "want to increase this value."))
1274
 
  ("read-buffer-threshold",
1275
 
  po::value<uint64_t>()->default_value(0),
1276
 
  _("A global cap on the size of read-buffer-size (0 means unlimited)"))
1277
 
  ("read-rnd-buffer-size",
1278
 
  po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1279
 
  _("When reading rows in sorted order after a sort, the rows are read "
1280
 
     "through this buffer to avoid a disk seeks. If not set, then it's set "
1281
 
     "to the value of record_buffer."))
1282
 
  ("read-rnd-threshold",
1283
 
  po::value<uint64_t>()->default_value(0),
1284
 
  _("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1285
 
  ("scheduler", po::value<string>(),
1286
 
  _("Select scheduler to be used (by default multi-thread)."))
1287
 
  ("sort-buffer-size",
1288
 
  po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1289
 
  _("Each thread that needs to do a sort allocates a buffer of this size."))
1290
 
  ("sort-heap-threshold",
1291
 
  po::value<uint64_t>()->default_value(0),
1292
 
  _("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
1293
 
  ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1294
 
  _("The number of cached table definitions."))
1295
 
  ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1296
 
  _("The number of cached open tables."))
1297
 
  ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1298
 
  _("Timeout in seconds to wait for a table level lock before returning an "
1299
 
     "error. Used only if the connection has active cursors."))
1300
 
  ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1301
 
  _("The stack size for each thread."))
1302
 
  ("tmp-table-size",
1303
 
  po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1304
 
  _("If an internal in-memory temporary table exceeds this size, Drizzle will"
1305
 
     " automatically convert it to an on-disk MyISAM table."))
1306
 
  ("verbose", po::value<std::string>()->default_value(error::verbose_string())->notifier(&error::check_verbosity),
1307
 
  _("The verbosity of messages from drizzled.  Possible values are INSPECT, INFO, WARN or ERROR"))
1308
 
  ;
1309
 
 
1310
 
  full_options.add(long_options);
1311
 
  full_options.add(plugin_load_options);
1312
 
 
1313
 
  initial_options.add(config_options);
1314
 
  initial_options.add(plugin_load_options);
1315
 
 
1316
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1317
 
  /* Get options about where config files and the like are */
1318
 
  po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1319
 
    options(initial_options).allow_unregistered().run();
1320
 
  unknown_options=
1321
 
    po::collect_unrecognized(parsed.options, po::include_positional);
1322
 
 
1323
 
  try
1324
 
  {
1325
 
    po::store(parsed, vm);
1326
 
  }
1327
 
  catch (std::exception&)
1328
 
  {
1329
 
    errmsg_printf(error::ERROR, _("Duplicate entry for command line option\n"));
1330
 
    unireg_abort(1);
1331
 
  }
1332
 
 
1333
 
  if (not vm["no-defaults"].as<bool>())
1334
 
  {
1335
 
    fs::path system_config_file_drizzle(system_config_dir);
1336
 
    system_config_file_drizzle /= "drizzled.cnf";
1337
 
    defaults_file_list.insert(defaults_file_list.begin(),
1338
 
                              system_config_file_drizzle.file_string());
1339
 
 
1340
 
    fs::path config_conf_d_location(system_config_dir);
1341
 
    config_conf_d_location /= "conf.d";
1342
 
 
1343
 
 
1344
 
    CachedDirectory config_conf_d(config_conf_d_location.file_string());
1345
 
    if (not config_conf_d.fail())
1346
 
    {
1347
 
 
1348
 
      for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1349
 
           iter != config_conf_d.getEntries().end();
1350
 
           ++iter)
1351
 
      {
1352
 
        string file_entry((*iter)->filename);
1353
 
 
1354
 
        if (not file_entry.empty()
1355
 
            && file_entry != "."
1356
 
            && file_entry != "..")
1357
 
        {
1358
 
          fs::path the_entry(config_conf_d_location);
1359
 
          the_entry /= file_entry;
1360
 
          defaults_file_list.push_back(the_entry.file_string());
1361
 
        }
1362
 
      }
1363
 
    }
1364
 
  }
1365
 
 
1366
 
  /* TODO: here is where we should add a process_env_vars */
1367
 
 
1368
 
  /* We need a notify here so that plugin_init will work properly */
1369
 
  try
1370
 
  {
1371
 
    po::notify(vm);
1372
 
  }
1373
 
  catch (po::validation_error &err)
1374
 
  {
1375
 
    errmsg_printf(error::ERROR,
1376
 
                  _("%s: %s.\n"
1377
 
                    "Use --help to get a list of available options\n"),
1378
 
                  internal::my_progname, err.what());
1379
 
    unireg_abort(1);
1380
 
  }
1381
 
 
1382
 
  process_defaults_files();
1383
 
 
1384
 
  /* Process with notify a second time because a config file may contain
1385
 
     plugin loader options */
1386
 
 
1387
 
  try
1388
 
  {
1389
 
    po::notify(vm);
1390
 
  }
1391
 
  catch (po::validation_error &err)
1392
 
  {
1393
 
    errmsg_printf(error::ERROR,
1394
 
                  _("%s: %s.\n"
1395
 
                    "Use --help to get a list of available options\n"),
1396
 
                  internal::my_progname, err.what());
1397
 
    unireg_abort(1);
1398
 
  }
1399
 
 
1400
 
  return 0;
1401
 
}
1402
 
 
1403
 
int init_remaining_variables(module::Registry &plugins)
1404
 
{
1405
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1406
 
 
1407
 
  current_pid= getpid();                /* Save for later ref */
1408
 
 
1409
 
  /* At this point, we've read all the options we need to read from files and
1410
 
     collected most of them into unknown options - now let's load everything
1411
 
  */
1412
 
 
1413
 
  if (plugin_init(plugins, plugin_options))
1414
 
  {
1415
 
    errmsg_printf(error::ERROR, _("Failed to initialize plugins\n"));
1416
 
    unireg_abort(1);
1417
 
  }
1418
 
 
1419
 
  full_options.add(plugin_options);
1420
 
 
1421
 
  vector<string> final_unknown_options;
1422
 
  try
1423
 
  {
1424
 
    po::parsed_options final_parsed=
1425
 
      po::command_line_parser(unknown_options).style(style).
1426
 
      options(full_options).extra_parser(dpo::parse_size_arg).run();
1427
 
 
1428
 
    final_unknown_options=
1429
 
      po::collect_unrecognized(final_parsed.options, po::include_positional);
1430
 
 
1431
 
    po::store(final_parsed, vm);
1432
 
 
1433
 
  }
1434
 
  catch (po::validation_error &err)
1435
 
  {
1436
 
    errmsg_printf(error::ERROR,
1437
 
                  _("%s: %s.\n"
1438
 
                    "Use --help to get a list of available options\n"),
1439
 
                  internal::my_progname, err.what());
1440
 
    unireg_abort(1);
1441
 
  }
1442
 
  catch (po::invalid_command_line_syntax &err)
1443
 
  {
1444
 
    errmsg_printf(error::ERROR,
1445
 
                  _("%s: %s.\n"
1446
 
                    "Use --help to get a list of available options\n"),
1447
 
                  internal::my_progname, err.what());
1448
 
    unireg_abort(1);
1449
 
  }
1450
 
  catch (po::unknown_option &err)
1451
 
  {
1452
 
    errmsg_printf(error::ERROR,
1453
 
                  _("%s\nUse --help to get a list of available options\n"),
1454
 
                  err.what());
1455
 
    unireg_abort(1);
1456
 
  }
1457
 
 
1458
 
  try
1459
 
  {
1460
 
    po::notify(vm);
1461
 
  }
1462
 
  catch (po::validation_error &err)
1463
 
  {
1464
 
    errmsg_printf(error::ERROR,
1465
 
                  _("%s: %s.\n"
1466
 
                    "Use --help to get a list of available options\n"),
1467
 
                  internal::my_progname, err.what());
1468
 
    unireg_abort(1);
1469
 
  }
1470
 
 
1471
 
  get_options();
1472
 
 
1473
 
  /* Inverted Booleans */
1474
 
 
1475
 
  global_system_variables.optimizer_prune_level=
1476
 
    vm.count("disable-optimizer-prune") ? false : true;
1477
 
 
1478
 
  if (vm.count("help") == 0 && vm.count("help-extended") == 0)
1479
 
  {
1480
 
    if ((user_info= check_user(drizzled_user)))
1481
 
    {
1482
 
      set_user(drizzled_user, user_info);
1483
 
    }
1484
 
  }
1485
 
 
1486
 
  fix_paths();
1487
 
 
1488
 
  init_time();                          /* Init time-functions (read zone) */
1489
 
 
1490
 
  if (item_create_init())
1491
 
    return 1;
1492
 
  if (sys_var_init())
1493
 
    return 1;
1494
 
  /* Creates static regex matching for temporal values */
1495
 
  if (! init_temporal_formats())
1496
 
    return 1;
1497
 
 
1498
 
  if (!(default_charset_info=
1499
 
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
1500
 
  {
1501
 
    errmsg_printf(error::ERROR, _("Error getting default charset"));
1502
 
    return 1;                           // Eof of the list
1503
 
  }
1504
 
 
1505
 
  if (vm.count("scheduler"))
1506
 
    opt_scheduler= vm["scheduler"].as<string>().c_str();
1507
 
 
1508
 
  if (default_collation_name)
1509
 
  {
1510
 
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1511
 
    if (not default_collation)
1512
 
    {
1513
 
      errmsg_printf(error::ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1514
 
      return 1;
1515
 
    }
1516
 
    if (not my_charset_same(default_charset_info, default_collation))
1517
 
    {
1518
 
      errmsg_printf(error::ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1519
 
                    default_collation_name,
1520
 
                    default_charset_info->csname);
1521
 
      return 1;
1522
 
    }
1523
 
    default_charset_info= default_collation;
1524
 
  }
1525
 
  /* Set collactions that depends on the default collation */
1526
 
  global_system_variables.collation_server=      default_charset_info;
1527
 
 
1528
 
  if (not (character_set_filesystem=
1529
 
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1530
 
  {
1531
 
    errmsg_printf(error::ERROR, _("Error setting collation"));
1532
 
    return 1;
1533
 
  }
1534
 
  global_system_variables.character_set_filesystem= character_set_filesystem;
1535
 
 
1536
 
  if (!(my_default_lc_time_names=
1537
 
        my_locale_by_name(lc_time_names_name)))
1538
 
  {
1539
 
    errmsg_printf(error::ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1540
 
    return 1;
1541
 
  }
1542
 
  global_system_variables.lc_time_names= my_default_lc_time_names;
1543
 
 
1544
 
  /* Reset table_alias_charset */
1545
 
  table_alias_charset= files_charset_info;
1546
 
 
1547
 
  return 0;
1548
 
}
1549
 
 
1550
 
 
1551
 
int init_server_components(module::Registry &plugins)
1552
 
{
1553
 
  /*
1554
 
    We need to call each of these following functions to ensure that
1555
 
    all things are initialized so that unireg_abort() doesn't fail
1556
 
  */
1557
 
  if (table_cache_init())
1558
 
  {
1559
 
    errmsg_printf(error::ERROR, _("Could not initialize table cache\n"));
1560
 
    unireg_abort(1);
1561
 
  }
1562
 
 
1563
 
  // Resize the definition Cache at startup
1564
 
  table::Cache::singleton().rehash(table_def_size);
1565
 
  definition::Cache::singleton().rehash(table_def_size);
1566
 
  message::Cache::singleton().rehash(table_def_size);
1567
 
 
1568
 
  setup_fpu();
1569
 
 
1570
 
  /* Allow storage engine to give real error messages */
1571
 
  ha_init_errors();
1572
 
 
1573
 
 
1574
 
  if (opt_help)
1575
 
    unireg_abort(0);
1576
 
 
1577
 
  if (plugin_finalize(plugins))
1578
 
  {
1579
 
    unireg_abort(1);
1580
 
  }
1581
 
 
1582
 
  string scheduler_name;
1583
 
  if (opt_scheduler)
1584
 
  {
1585
 
    scheduler_name= opt_scheduler;
1586
 
  }
1587
 
  else
1588
 
  {
1589
 
    scheduler_name= opt_scheduler_default;
1590
 
    opt_scheduler= opt_scheduler_default;
1591
 
  }
1592
 
 
1593
 
  if (plugin::Scheduler::setPlugin(scheduler_name))
1594
 
  {
1595
 
      errmsg_printf(error::ERROR,
1596
 
                   _("No scheduler found, cannot continue!\n"));
1597
 
      unireg_abort(1);
1598
 
  }
1599
 
 
1600
 
  /*
1601
 
    This is entirely for legacy. We will create a new "disk based" engine and a
1602
 
    "memory" engine which will be configurable longterm.
1603
 
  */
1604
 
  const std::string myisam_engine_name("MyISAM");
1605
 
  const std::string heap_engine_name("MEMORY");
1606
 
  myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
1607
 
  heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
1608
 
 
1609
 
  /*
1610
 
    Check that the default storage engine is actually available.
1611
 
  */
1612
 
  if (default_storage_engine_str)
1613
 
  {
1614
 
    const std::string name(default_storage_engine_str);
1615
 
    plugin::StorageEngine *engine;
1616
 
 
1617
 
    engine= plugin::StorageEngine::findByName(name);
1618
 
    if (engine == NULL)
1619
 
    {
1620
 
      errmsg_printf(error::ERROR, _("Unknown/unsupported storage engine: %s\n"),
1621
 
                    default_storage_engine_str);
1622
 
      unireg_abort(1);
1623
 
    }
1624
 
    global_system_variables.storage_engine= engine;
1625
 
  }
1626
 
 
1627
 
  if (plugin::XaResourceManager::recoverAllXids())
1628
 
  {
1629
 
    /* This function alredy generates error messages */
1630
 
    unireg_abort(1);
1631
 
  }
1632
 
 
1633
 
  init_update_queries();
1634
 
 
1635
 
  return(0);
1636
 
}
1637
 
 
1638
 
 
1639
 
/****************************************************************************
1640
 
  Handle start options
1641
 
******************************************************************************/
1642
 
 
1643
 
enum options_drizzled
1644
 
{
1645
 
  OPT_SOCKET=256,
1646
 
  OPT_BIND_ADDRESS,
1647
 
  OPT_PID_FILE,
1648
 
  OPT_STORAGE_ENGINE,
1649
 
  OPT_INIT_FILE,
1650
 
  OPT_WANT_CORE,
1651
 
  OPT_MEMLOCK,
1652
 
  OPT_SERVER_ID,
1653
 
  OPT_TC_HEURISTIC_RECOVER,
1654
 
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
1655
 
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
1656
 
  OPT_DO_PSTACK,
1657
 
  OPT_LOCAL_INFILE,
1658
 
  OPT_BACK_LOG,
1659
 
  OPT_JOIN_BUFF_SIZE,
1660
 
  OPT_MAX_ALLOWED_PACKET,
1661
 
  OPT_MAX_HEP_TABLE_SIZE,
1662
 
  OPT_MAX_JOIN_SIZE,
1663
 
  OPT_MAX_SORT_LENGTH,
1664
 
  OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
1665
 
  OPT_MAX_LENGTH_FOR_SORT_DATA,
1666
 
  OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
1667
 
  OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
1668
 
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
1669
 
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
1670
 
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
1671
 
  OPT_NET_BUFFER_LENGTH,
1672
 
  OPT_PRELOAD_BUFFER_SIZE,
1673
 
  OPT_RECORD_BUFFER,
1674
 
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
1675
 
  OPT_DEBUGGING,
1676
 
  OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
1677
 
  OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
1678
 
  OPT_WAIT_TIMEOUT,
1679
 
  OPT_RANGE_ALLOC_BLOCK_SIZE,
1680
 
  OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
1681
 
  OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
1682
 
  OPT_OLD_ALTER_TABLE,
1683
 
  OPT_GROUP_CONCAT_MAX_LEN,
1684
 
  OPT_DEFAULT_COLLATION,
1685
 
  OPT_CHARACTER_SET_FILESYSTEM,
1686
 
  OPT_LC_TIME_NAMES,
1687
 
  OPT_INIT_CONNECT,
1688
 
  OPT_DEFAULT_TIME_ZONE,
1689
 
  OPT_OPTIMIZER_SEARCH_DEPTH,
1690
 
  OPT_SCHEDULER,
1691
 
  OPT_PROTOCOL,
1692
 
  OPT_OPTIMIZER_PRUNE_LEVEL,
1693
 
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
1694
 
  OPT_ENABLE_LARGE_PAGES,
1695
 
  OPT_TIMED_MUTEXES,
1696
 
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
1697
 
  OPT_PLUGIN_ADD,
1698
 
  OPT_PLUGIN_REMOVE,
1699
 
  OPT_PLUGIN_LOAD,
1700
 
  OPT_PLUGIN_DIR,
1701
 
  OPT_PORT_OPEN_TIMEOUT,
1702
 
  OPT_SECURE_FILE_PRIV,
1703
 
  OPT_MIN_EXAMINED_ROW_LIMIT,
1704
 
  OPT_PRINT_DEFAULTS
1705
 
};
1706
 
 
1707
 
 
1708
 
struct option my_long_options[] =
1709
 
{
1710
 
 
1711
 
  {"help", '?', N_("Display this help and exit."),
1712
 
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1713
 
   0, 0},
1714
 
  {"daemon", 'd', N_("Run as daemon."),
1715
 
   (char**) &opt_daemon, (char**) &opt_daemon, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1716
 
   0, 0},
1717
 
  {"auto-increment-increment", OPT_AUTO_INCREMENT,
1718
 
   N_("Auto-increment columns are incremented by this"),
1719
 
   (char**) &global_system_variables.auto_increment_increment,
1720
 
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1721
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
1722
 
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1723
 
   N_("Offset added to Auto-increment columns. Used when "
1724
 
      "auto-increment-increment != 1"),
1725
 
   (char**) &global_system_variables.auto_increment_offset,
1726
 
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1727
 
   1, 1, INT64_MAX, 0, 1, 0 },
1728
 
  {"basedir", 'b',
1729
 
   N_("Path to installation directory. All paths are usually resolved "
1730
 
      "relative to this."),
1731
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
1732
 
   0, 0, 0, 0, 0, 0},
1733
 
  {"chroot", 'r',
1734
 
   N_("Chroot drizzled daemon during startup."),
1735
 
   (char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
1736
 
   0, 0, 0, 0, 0, 0},
1737
 
  {"collation-server", OPT_DEFAULT_COLLATION,
1738
 
   N_("Set the default collation."),
1739
 
   (char**) &default_collation_name, (char**) &default_collation_name,
1740
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1741
 
  {"completion-type", OPT_COMPLETION_TYPE,
1742
 
   N_("Default completion type."),
1743
 
   (char**) &global_system_variables.completion_type,
1744
 
   (char**) &max_system_variables.completion_type, 0, GET_UINT,
1745
 
   REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
1746
 
  {"core-file", OPT_WANT_CORE,
1747
 
   N_("Write core on errors."),
1748
 
   0, 0, 0, GET_NO_ARG,
1749
 
   NO_ARG, 0, 0, 0, 0, 0, 0},
1750
 
  {"datadir", 'h',
1751
 
   N_("Path to the database root."),
1752
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1753
 
  /* See how it's handled in get_one_option() */
1754
 
  {"exit-info", 'T',
1755
 
   N_("Used for debugging;  Use at your own risk!"),
1756
 
   0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
1757
 
  /* We must always support the next option to make scripts like mysqltest
1758
 
     easier to do */
1759
 
  {"gdb", OPT_DEBUGGING,
1760
 
   N_("Set up signals usable for debugging"),
1761
 
   (char**) &opt_debugging, (char**) &opt_debugging,
1762
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1763
 
  {"log-warnings", 'W',
1764
 
   N_("Log some not critical warnings to the log file."),
1765
 
   (char**) &global_system_variables.log_warnings,
1766
 
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1767
 
   0, 0, 0},
1768
 
  {"pid-file", OPT_PID_FILE,
1769
 
   N_("Pid file used by drizzled."),
1770
 
   NULL, NULL, 0, GET_STR,
1771
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1772
 
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1773
 
   N_("Maximum time in seconds to wait for the port to become free. "
1774
 
      "(Default: no wait)"),
1775
 
   (char**) &drizzled_bind_timeout,
1776
 
   (char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1777
 
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1778
 
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1779
 
      "within specified directory"),
1780
 
   NULL, NULL, 0,
1781
 
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1782
 
  {"server-id", OPT_SERVER_ID,
1783
 
   N_("Uniquely identifies the server instance in the community of "
1784
 
      "replication partners."),
1785
 
   (char**) &server_id, (char**) &server_id, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 0,
1786
 
   0, 0, 0},
1787
 
  {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
1788
 
   N_("Don't print a stack trace on failure."),
1789
 
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
1790
 
   0, 0, 0, 0},
1791
 
  {"symbolic-links", 's',
1792
 
   N_("Enable symbolic link support."),
1793
 
   (char**) &internal::my_use_symdir, (char**) &internal::my_use_symdir, 0, GET_BOOL, NO_ARG,
1794
 
   /*
1795
 
     The system call realpath() produces warnings under valgrind and
1796
 
     purify. These are not suppressed: instead we disable symlinks
1797
 
     option if compiled with valgrind support.
1798
 
   */
1799
 
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
1800
 
  {"timed_mutexes", OPT_TIMED_MUTEXES,
1801
 
   N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1802
 
      "supported)"),
1803
 
   (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1804
 
    0, 0, 0, 0, 0},
1805
 
  {"transaction-isolation", OPT_TX_ISOLATION,
1806
 
   N_("Default transaction isolation level."),
1807
 
   0, 0, 0, GET_STR, REQUIRED_ARG, 0,
1808
 
   0, 0, 0, 0, 0},
1809
 
  {"user", 'u',
1810
 
   N_("Run drizzled daemon as user."),
1811
 
   0, 0, 0, GET_STR, REQUIRED_ARG,
1812
 
   0, 0, 0, 0, 0, 0},
1813
 
  {"back_log", OPT_BACK_LOG,
1814
 
   N_("The number of outstanding connection requests Drizzle can have. This "
1815
 
      "comes into play when the main Drizzle thread gets very many connection "
1816
 
      "requests in a very short time."),
1817
 
    (char**) &back_log, (char**) &back_log, 0, GET_UINT,
1818
 
    REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
1819
 
  { "bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
1820
 
    N_("Size of tree cache used in bulk insert optimization. Note that this is "
1821
 
       "a limit per thread!"),
1822
 
    (char**) &global_system_variables.bulk_insert_buff_size,
1823
 
    (char**) &max_system_variables.bulk_insert_buff_size,
1824
 
    0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
1825
 
  { "div_precision_increment", OPT_DIV_PRECINCREMENT,
1826
 
   N_("Precision of the result of '/' operator will be increased on that "
1827
 
      "value."),
1828
 
   (char**) &global_system_variables.div_precincrement,
1829
 
   (char**) &max_system_variables.div_precincrement, 0, GET_UINT,
1830
 
   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
1831
 
  { "join_buffer_size", OPT_JOIN_BUFF_SIZE,
1832
 
    N_("The size of the buffer that is used for full joins."),
1833
 
   (char**) &global_system_variables.join_buff_size,
1834
 
   (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
1835
 
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
1836
 
   MALLOC_OVERHEAD, IO_SIZE, 0},
1837
 
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1838
 
   N_("Max packetlength to send/receive from to server."),
1839
 
   (char**) &global_system_variables.max_allowed_packet,
1840
 
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1841
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1842
 
  {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
1843
 
   N_("Don't allow creation of heap tables bigger than this."),
1844
 
   (char**) &global_system_variables.max_heap_table_size,
1845
 
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1846
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
1847
 
   MALLOC_OVERHEAD, 1024, 0},
1848
 
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1849
 
   N_("Joins that are probably going to read more than max_join_size records "
1850
 
      "return an error."),
1851
 
   (char**) &global_system_variables.max_join_size,
1852
 
   (char**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
1853
 
   INT32_MAX, 1, INT32_MAX, 0, 1, 0},
1854
 
  {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
1855
 
   N_("Max number of bytes in sorted records."),
1856
 
   (char**) &global_system_variables.max_length_for_sort_data,
1857
 
   (char**) &max_system_variables.max_length_for_sort_data, 0, GET_ULL,
1858
 
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
1859
 
  { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
1860
 
    N_("Limit assumed max number of seeks when looking up rows based on a key"),
1861
 
    (char**) &global_system_variables.max_seeks_for_key,
1862
 
    (char**) &max_system_variables.max_seeks_for_key, 0, GET_UINT64,
1863
 
    REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
1864
 
  {"max_sort_length", OPT_MAX_SORT_LENGTH,
1865
 
   N_("The number of bytes to use when sorting BLOB or TEXT values "
1866
 
      "(only the first max_sort_length bytes of each value are used; the "
1867
 
      "rest are ignored)."),
1868
 
   (char**) &global_system_variables.max_sort_length,
1869
 
   (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
1870
 
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
1871
 
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
1872
 
   N_("After this many write locks, allow some read locks to run in between."),
1873
 
   (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
1874
 
   REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
1875
 
  {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
1876
 
   N_("Don't log queries which examine less than min_examined_row_limit "
1877
 
      "rows to file."),
1878
 
   (char**) &global_system_variables.min_examined_row_limit,
1879
 
   (char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
1880
 
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
1881
 
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
1882
 
    N_("Controls the heuristic(s) applied during query optimization to prune "
1883
 
       "less-promising partial plans from the optimizer search space. Meaning: "
1884
 
       "false - do not apply any heuristic, thus perform exhaustive search; "
1885
 
       "true - prune plans based on number of retrieved rows."),
1886
 
    (char**) &global_system_variables.optimizer_prune_level,
1887
 
    (char**) &max_system_variables.optimizer_prune_level,
1888
 
    0, GET_BOOL, OPT_ARG, 1, 0, 1, 0, 1, 0},
1889
 
  {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
1890
 
   N_("Maximum depth of search performed by the query optimizer. Values "
1891
 
      "larger than the number of relations in a query result in better query "
1892
 
      "plans, but take longer to compile a query. Smaller values than the "
1893
 
      "number of tables in a relation result in faster optimization, but may "
1894
 
      "produce very bad query plans. If set to 0, the system will "
1895
 
      "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1896
 
      "optimizer will switch to the original find_best (used for "
1897
 
      "testing/comparison)."),
1898
 
   (char**) &global_system_variables.optimizer_search_depth,
1899
 
   (char**) &max_system_variables.optimizer_search_depth,
1900
 
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
1901
 
  {"plugin_dir", OPT_PLUGIN_DIR,
1902
 
   N_("Directory for plugins."),
1903
 
   NULL, NULL, 0,
1904
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1905
 
  {"plugin_add", OPT_PLUGIN_ADD,
1906
 
   N_("Optional comma separated list of plugins to load at startup in addition "
1907
 
      "to the default list of plugins. "
1908
 
      "[for example: --plugin_add=crc32,logger_gearman]"),
1909
 
   NULL, NULL, 0,
1910
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1911
 
  {"plugin_remove", OPT_PLUGIN_ADD,
1912
 
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
1913
 
      "removes a plugin from the list of plugins to be loaded. "
1914
 
      "[for example: --plugin_remove=crc32,logger_gearman]"),
1915
 
   NULL, NULL, 0,
1916
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1917
 
  {"plugin_load", OPT_PLUGIN_LOAD,
1918
 
   N_("Optional comma separated list of plugins to load at starup instead of "
1919
 
      "the default plugin load list. "
1920
 
      "[for example: --plugin_load=crc32,logger_gearman]"),
1921
 
   NULL, NULL, 0,
1922
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1923
 
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1924
 
   N_("The size of the buffer that is allocated when preloading indexes"),
1925
 
   (char**) &global_system_variables.preload_buff_size,
1926
 
   (char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
1927
 
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
1928
 
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
1929
 
   N_("Allocation block size for query parsing and execution"),
1930
 
   (char**) &global_system_variables.query_alloc_block_size,
1931
 
   (char**) &max_system_variables.query_alloc_block_size, 0, GET_UINT,
1932
 
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
1933
 
  {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
1934
 
   N_("Persistent buffer for query parsing and execution"),
1935
 
   (char**) &global_system_variables.query_prealloc_size,
1936
 
   (char**) &max_system_variables.query_prealloc_size, 0, GET_UINT,
1937
 
   REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
1938
 
   ULONG_MAX, 0, 1024, 0},
1939
 
  {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
1940
 
   N_("Allocation block size for storing ranges during optimization"),
1941
 
   (char**) &global_system_variables.range_alloc_block_size,
1942
 
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
1943
 
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
1944
 
   0, 1024, 0},
1945
 
  {"read_buffer_size", OPT_RECORD_BUFFER,
1946
 
    N_("Each thread that does a sequential scan allocates a buffer of this "
1947
 
       "size for each table it scans. If you do many sequential scans, you may "
1948
 
       "want to increase this value."),
1949
 
    (char**) &global_system_variables.read_buff_size,
1950
 
    (char**) &max_system_variables.read_buff_size,0, GET_UINT, REQUIRED_ARG,
1951
 
    128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT32_MAX, MALLOC_OVERHEAD, IO_SIZE,
1952
 
    0},
1953
 
  {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
1954
 
   N_("When reading rows in sorted order after a sort, the rows are read "
1955
 
      "through this buffer to avoid a disk seeks. If not set, then it's set "
1956
 
      "to the value of record_buffer."),
1957
 
   (char**) &global_system_variables.read_rnd_buff_size,
1958
 
   (char**) &max_system_variables.read_rnd_buff_size, 0,
1959
 
   GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
1960
 
   UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
1961
 
  /* x8 compared to MySQL's x2. We have UTF8 to consider. */
1962
 
  {"sort_buffer_size", OPT_SORT_BUFFER,
1963
 
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
1964
 
   (char**) &global_system_variables.sortbuff_size,
1965
 
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
1966
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
1967
 
   MALLOC_OVERHEAD, 1, 0},
1968
 
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
1969
 
   N_("The number of cached table definitions."),
1970
 
   (char**) &table_def_size, (char**) &table_def_size,
1971
 
   0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
1972
 
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
1973
 
   N_("The number of cached open tables."),
1974
 
   (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
1975
 
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, TABLE_OPEN_CACHE_MIN, 512*1024L, 0, 1, 0},
1976
 
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
1977
 
   N_("Timeout in seconds to wait for a table level lock before returning an "
1978
 
      "error. Used only if the connection has active cursors."),
1979
 
   (char**) &table_lock_wait_timeout, (char**) &table_lock_wait_timeout,
1980
 
   0, GET_ULL, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
1981
 
  {"thread_stack", OPT_THREAD_STACK,
1982
 
   N_("The stack size for each thread."),
1983
 
   (char**) &my_thread_stack_size,
1984
 
   (char**) &my_thread_stack_size, 0, GET_SIZE,
1985
 
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
1986
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
1987
 
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
1988
 
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1989
 
      " automatically convert it to an on-disk MyISAM table."),
1990
 
   (char**) &global_system_variables.tmp_table_size,
1991
 
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
1992
 
   REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
1993
 
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1994
 
};
1995
 
 
1996
 
static void print_version(void)
1997
 
{
1998
 
  /*
1999
 
    Note: the instance manager keys off the string 'Ver' so it can find the
2000
 
    version from the output of 'drizzled --version', so don't change it!
2001
 
  */
2002
 
  printf("%s  Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
2003
 
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
2004
 
         COMPILATION_COMMENT);
2005
 
}
2006
 
 
2007
 
static void usage(void)
2008
 
{
2009
 
  if (!(default_charset_info= get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
2010
 
    exit(1);
2011
 
  if (!default_collation_name)
2012
 
    default_collation_name= (char*) default_charset_info->name;
2013
 
  print_version();
2014
 
  puts(_("Copyright (C) 2008 Sun Microsystems\n"
2015
 
         "This software comes with ABSOLUTELY NO WARRANTY. "
2016
 
         "This is free software,\n"
2017
 
         "and you are welcome to modify and redistribute it under the GPL "
2018
 
         "license\n\n"));
2019
 
 
2020
 
 
2021
 
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
2022
 
 
2023
 
  po::options_description all_options("Drizzled Options");
2024
 
  all_options.add(config_options);
2025
 
  all_options.add(plugin_load_options);
2026
 
  all_options.add(long_options);
2027
 
  all_options.add(plugin_options);
2028
 
  cout << all_options << endl;
2029
 
 
2030
 
}
2031
 
 
2032
 
/**
2033
 
  Initialize all Drizzle global variables to default values.
2034
 
 
2035
 
  We don't need to set numeric variables refered to in my_long_options
2036
 
  as these are initialized by my_getopt.
2037
 
 
2038
 
  @note
2039
 
    The reason to set a lot of global variables to zero is to allow one to
2040
 
    restart the embedded server with a clean environment
2041
 
    It's also needed on some exotic platforms where global variables are
2042
 
    not set to 0 when a program starts.
2043
 
 
2044
 
    We don't need to set numeric variables refered to in my_long_options
2045
 
    as these are initialized by my_getopt.
2046
 
*/
2047
 
 
2048
 
static void drizzle_init_variables(void)
2049
 
{
2050
 
  /* Things reset to zero */
2051
 
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
2052
 
  cleanup_done= 0;
2053
 
  dropping_tables= ha_open_options=0;
2054
 
  getDebug().reset();
2055
 
  wake_thread=0;
2056
 
  abort_loop= select_thread_in_use= false;
2057
 
  shutdown_in_progress= 0;
2058
 
  drizzled_user= drizzled_chroot= 0;
2059
 
  memset(&current_global_counters, 0, sizeof(current_global_counters));
2060
 
  key_map_full.set();
2061
 
 
2062
 
  /* Character sets */
2063
 
  system_charset_info= &my_charset_utf8_general_ci;
2064
 
  files_charset_info= &my_charset_utf8_general_ci;
2065
 
  table_alias_charset= &my_charset_bin;
2066
 
  character_set_filesystem= &my_charset_bin;
2067
 
 
2068
 
  /* Things with default values that are not zero */
2069
 
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2070
 
  refresh_version= 1L;  /* Increments on each reload */
2071
 
  global_thread_id= 1UL;
2072
 
  session::Cache::singleton().getCache().clear();
2073
 
 
2074
 
  /* Variables in libraries */
2075
 
  default_character_set_name= "utf8";
2076
 
  default_collation_name= (char *)compiled_default_collation_name;
2077
 
  character_set_filesystem_name= "binary";
2078
 
  lc_time_names_name= (char*) "en_US";
2079
 
  /* Set default values for some option variables */
2080
 
  default_storage_engine_str= (char*) "innodb";
2081
 
  global_system_variables.storage_engine= NULL;
2082
 
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
2083
 
  global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
2084
 
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2085
 
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2086
 
  max_system_variables.max_join_size=   (uint64_t) HA_POS_ERROR;
2087
 
  max_system_variables.auto_increment_increment= UINT64_MAX;
2088
 
  max_system_variables.auto_increment_offset= UINT64_MAX;
2089
 
  max_system_variables.completion_type= 2;
2090
 
  max_system_variables.log_warnings= true;
2091
 
  max_system_variables.bulk_insert_buff_size= ULONG_MAX;
2092
 
  max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
2093
 
  max_system_variables.group_concat_max_len= ULONG_MAX;
2094
 
  max_system_variables.join_buff_size= ULONG_MAX;
2095
 
  max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
2096
 
  max_system_variables.max_error_count= 65535;
2097
 
  max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
2098
 
  max_system_variables.max_join_size= INT32_MAX;
2099
 
  max_system_variables.max_length_for_sort_data= 8192*1024L;
2100
 
  max_system_variables.max_seeks_for_key= ULONG_MAX;
2101
 
  max_system_variables.max_sort_length= 8192*1024L;
2102
 
  max_system_variables.min_examined_row_limit= ULONG_MAX;
2103
 
  max_system_variables.optimizer_prune_level= 1;
2104
 
  max_system_variables.optimizer_search_depth= MAX_TABLES+2;
2105
 
  max_system_variables.preload_buff_size= 1024*1024*1024L;
2106
 
  max_system_variables.query_alloc_block_size= UINT32_MAX;
2107
 
  max_system_variables.query_prealloc_size= UINT32_MAX;
2108
 
  max_system_variables.range_alloc_block_size= SIZE_MAX;
2109
 
  max_system_variables.read_buff_size= INT32_MAX;
2110
 
  max_system_variables.read_rnd_buff_size= UINT32_MAX;
2111
 
  max_system_variables.sortbuff_size= SIZE_MAX;
2112
 
  max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
2113
 
 
2114
 
  opt_scheduler_default= (char*) "multi_thread";
2115
 
 
2116
 
  /* Variables that depends on compile options */
2117
 
#ifdef HAVE_BROKEN_REALPATH
2118
 
  have_symlink=SHOW_OPTION_NO;
2119
 
#else
2120
 
  have_symlink=SHOW_OPTION_YES;
2121
 
#endif
2122
 
}
2123
 
 
2124
 
 
2125
 
/**
2126
 
  @todo
2127
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2128
 
*/
2129
 
static void get_options()
2130
 
{
2131
 
 
2132
 
  fs::path &data_home_catalog= getDataHomeCatalog();
2133
 
  data_home_catalog= getDataHome();
2134
 
  data_home_catalog /= "local";
2135
 
 
2136
 
  if (vm.count("user"))
2137
 
  {
2138
 
    if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
2139
 
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2140
 
 
2141
 
    else
2142
 
      errmsg_printf(error::WARN, _("Ignoring user change to '%s' because the user was "
2143
 
                                       "set to '%s' earlier on the command line\n"),
2144
 
                    vm["user"].as<string>().c_str(), drizzled_user);
2145
 
  }
2146
 
 
2147
 
  if (vm.count("version"))
2148
 
  {
2149
 
    print_version();
2150
 
    exit(0);
2151
 
  }
2152
 
 
2153
 
  if (vm.count("sort-heap-threshold"))
2154
 
  {
2155
 
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2156
 
      (vm["sort-heap-threshold"].as<uint64_t>() <
2157
 
      global_system_variables.sortbuff_size))
2158
 
    {
2159
 
      cout << _("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2160
 
      exit(-1);
2161
 
    }
2162
 
 
2163
 
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2164
 
  }
2165
 
 
2166
 
  if (vm.count("join-heap-threshold"))
2167
 
  {
2168
 
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2169
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2170
 
      global_system_variables.join_buff_size))
2171
 
    {
2172
 
      cout << _("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2173
 
      exit(-1);
2174
 
    }
2175
 
 
2176
 
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2177
 
  }
2178
 
 
2179
 
  if (vm.count("read-rnd-threshold"))
2180
 
  {
2181
 
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2182
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2183
 
      global_system_variables.read_rnd_buff_size))
2184
 
    {
2185
 
      cout << _("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2186
 
      exit(-1);
2187
 
    }
2188
 
 
2189
 
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2190
 
  }
2191
 
 
2192
 
  if (vm.count("read-buffer-threshold"))
2193
 
  {
2194
 
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2195
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2196
 
      global_system_variables.read_buff_size))
2197
 
    {
2198
 
      cout << _("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2199
 
      exit(-1);
2200
 
    }
2201
 
 
2202
 
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2203
 
  }
2204
 
 
2205
 
  if (vm.count("exit-info"))
2206
 
  {
2207
 
    if (vm["exit-info"].as<long>())
2208
 
    {
2209
 
      getDebug().set((uint32_t) vm["exit-info"].as<long>());
2210
 
    }
2211
 
  }
2212
 
 
2213
 
  if (vm.count("want-core"))
2214
 
  {
2215
 
    getDebug().set(debug::CORE_ON_SIGNAL);
2216
 
  }
2217
 
 
2218
 
  if (vm.count("skip-stack-trace"))
2219
 
  {
2220
 
    getDebug().set(debug::NO_STACKTRACE);
2221
 
  }
2222
 
 
2223
 
  if (vm.count("skip-symlinks"))
2224
 
  {
2225
 
    internal::my_use_symdir=0;
2226
 
  }
2227
 
 
2228
 
  if (vm.count("transaction-isolation"))
2229
 
  {
2230
 
    int type= tx_isolation_typelib.find_type_or_exit(vm["transaction-isolation"].as<string>().c_str(), "transaction-isolation");
2231
 
    global_system_variables.tx_isolation= type - 1;
2232
 
  }
2233
 
 
2234
 
  /* @TODO Make this all strings */
2235
 
  if (vm.count("default-storage-engine"))
2236
 
  {
2237
 
    default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
2238
 
  }
2239
 
 
2240
 
  /* Skip unknown options so that they may be processed later by plugins */
2241
 
  my_getopt_skip_unknown= true;
2242
 
 
2243
 
 
2244
 
#if defined(HAVE_BROKEN_REALPATH)
2245
 
  internal::my_use_symdir=0;
2246
 
  internal::my_disable_symlinks=1;
2247
 
  have_symlink=SHOW_OPTION_NO;
2248
 
#else
2249
 
  if (!internal::my_use_symdir)
2250
 
  {
2251
 
    internal::my_disable_symlinks=1;
2252
 
    have_symlink=SHOW_OPTION_DISABLED;
2253
 
  }
2254
 
#endif
2255
 
  if (opt_debugging)
2256
 
  {
2257
 
    /* Allow break with SIGINT, no core or stack trace */
2258
 
    getDebug().set(debug::ALLOW_SIGINT);
2259
 
    getDebug().set(debug::NO_STACKTRACE);
2260
 
    getDebug().reset(debug::CORE_ON_SIGNAL);
2261
 
  }
2262
 
 
2263
 
  if (drizzled_chroot)
2264
 
    set_root(drizzled_chroot);
2265
 
 
2266
 
  /*
2267
 
    Set some global variables from the global_system_variables
2268
 
    In most cases the global variables will not be used
2269
 
  */
2270
 
  internal::my_default_record_cache_size=global_system_variables.read_buff_size;
2271
 
}
2272
 
 
2273
 
 
2274
 
static void fix_paths()
2275
 
{
2276
 
  fs::path pid_file_path(pid_file);
2277
 
  if (pid_file_path.root_path().string() == "")
2278
 
  {
2279
 
    pid_file_path= getDataHome();
2280
 
    pid_file_path /= pid_file;
2281
 
  }
2282
 
  pid_file= fs::system_complete(pid_file_path);
2283
 
 
2284
 
  if (not opt_help)
2285
 
  {
2286
 
    const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
2287
 
    struct stat buf;
2288
 
    drizzle_tmpdir.clear();
2289
 
 
2290
 
    if (vm.count("tmpdir"))
2291
 
    {
2292
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
2293
 
    }
2294
 
    else if (tmp_string == NULL)
2295
 
    {
2296
 
      drizzle_tmpdir.append(getDataHome().file_string());
2297
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2298
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2299
 
    }
2300
 
    else
2301
 
    {
2302
 
      drizzle_tmpdir.append(tmp_string);
2303
 
    }
2304
 
 
2305
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2306
 
    assert(drizzle_tmpdir.size());
2307
 
 
2308
 
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2309
 
    {
2310
 
      if (errno != EEXIST)
2311
 
      {
2312
 
        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());
2313
 
        exit(1);
2314
 
      }
2315
 
    }
2316
 
 
2317
 
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
2318
 
    {
2319
 
      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());
2320
 
      exit(1);
2321
 
    }
2322
 
  }
2323
 
 
2324
 
}
2325
 
 
2326
 
} /* namespace drizzled */
2327