~ubuntu-branches/ubuntu/vivid/drizzle/vivid

« back to all changes in this revision

Viewing changes to .pc/boost-1.49.patch/drizzled/drizzled.cc

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2013-05-20 01:01:26 UTC
  • mfrom: (18.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130520010126-0imtkm284p0f7t0s
Tags: 1:7.1.36-stable-3
* New patch boost-1.49.patch due to a boost problem showed with gcc >4.7
  (Closes: #701269)
* Adding Japanese (Closes: #692842) and Brazilian (Closes: #685770)
  translations
* Do not build undocumented commands drizzle_passwordhash and
  drizzlebackup.innobase (no man pages are available.) This is handled
  in the new patches donotbuild_drizzlepasswordhash.patch and
  donotbuild_drizzlebackup.innobase.patch
* Switch from hardening-wrapper to dpkg-buildflags
* Add patch ftbfs-bison-2.7.patch to fix a FTBS with recent bison.
  (cherry-picked from upstream)

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