~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-03-21 01:02:23 UTC
  • mto: (960.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 961.
  • Revision ID: osullivan.padraig@gmail.com-20090321010223-j8cph7eeyt1u3xol
Fixed function object to ensure it correctly returns a boolean type since
memcmp returns an integer. Added some more comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
21
 
#include "drizzled/configmake.h"
22
 
#include "drizzled/atomics.h"
23
 
#include "drizzled/data_home.h"
 
20
 
 
21
#include <drizzled/configmake.h>
 
22
#include <drizzled/server_includes.h>
 
23
#include <drizzled/atomics.h>
24
24
 
25
25
#include <netdb.h>
26
 
#include <sys/types.h>
 
26
#include <sys/poll.h>
27
27
#include <netinet/tcp.h>
28
 
#include <netinet/in.h>
29
28
#include <signal.h>
30
 
#include <limits.h>
31
 
#include <stdexcept>
32
 
 
33
 
#include <boost/program_options.hpp>
34
 
#include "drizzled/program_options/config_file.h"
35
 
#include <boost/thread/recursive_mutex.hpp>
36
 
#include <boost/thread/mutex.hpp>
37
 
#include <boost/thread/shared_mutex.hpp>
38
 
#include <boost/thread/condition_variable.hpp>
39
 
#include <boost/filesystem.hpp>
40
 
 
41
 
#include "drizzled/internal/my_sys.h"
42
 
#include "drizzled/internal/my_bit.h"
43
 
#include <drizzled/my_hash.h>
 
29
 
 
30
#include <mysys/my_bit.h>
 
31
#include <libdrizzleclient/libdrizzle.h>
 
32
#include <mysys/hash.h>
 
33
#include <drizzled/stacktrace.h>
 
34
#include <mysys/mysys_err.h>
44
35
#include <drizzled/error.h>
45
36
#include <drizzled/errmsg_print.h>
46
37
#include <drizzled/tztime.h>
49
40
#include <drizzled/sql_parse.h>
50
41
#include <drizzled/item/cmpfunc.h>
51
42
#include <drizzled/session.h>
 
43
#include <drizzled/db.h>
52
44
#include <drizzled/item/create.h>
 
45
#include <drizzled/errmsg.h>
53
46
#include <drizzled/unireg.h>
 
47
#include <drizzled/plugin_scheduling.h>
54
48
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
55
 
#include "drizzled/plugin/listen.h"
56
 
#include "drizzled/plugin/error_message.h"
57
 
#include "drizzled/plugin/client.h"
58
 
#include "drizzled/plugin/scheduler.h"
59
 
#include "drizzled/plugin/xa_resource_manager.h"
60
 
#include "drizzled/plugin/monitored_in_transaction.h"
61
 
#include "drizzled/replication_services.h" /* For ReplicationServices::evaluateRegisteredPlugins() */
62
 
#include "drizzled/probes.h"
63
 
#include "drizzled/session/cache.h"
64
 
#include "drizzled/charset.h"
65
 
#include "plugin/myisam/myisam.h"
66
 
#include "drizzled/drizzled.h"
67
 
#include "drizzled/module/registry.h"
68
 
#include "drizzled/module/load_list.h"
69
 
#include "drizzled/global_buffer.h"
70
 
 
71
 
#include "drizzled/definition/cache.h"
72
 
 
73
 
#include "drizzled/plugin/event_observer.h"
74
 
 
75
 
#include "drizzled/message/cache.h"
76
 
 
77
 
#include <google/protobuf/stubs/common.h>
78
49
 
79
50
#if TIME_WITH_SYS_TIME
80
51
# include <sys/time.h>
87
58
# endif
88
59
#endif
89
60
 
 
61
#include <storage/myisam/ha_myisam.h>
 
62
 
90
63
#ifdef HAVE_SYS_PRCTL_H
91
64
#include <sys/prctl.h>
92
65
#endif
93
 
#include <sys/socket.h>
94
 
 
95
 
 
 
66
 
 
67
#include <libdrizzleclient/errmsg.h>
 
68
#include <locale.h>
 
69
 
 
70
#define mysqld_charset &my_charset_utf8_general_ci
 
71
 
 
72
#ifdef HAVE_purify
 
73
#define IF_PURIFY(A,B) (A)
 
74
#else
 
75
#define IF_PURIFY(A,B) (B)
 
76
#endif
 
77
 
 
78
#define MAX_MEM_TABLE_SIZE SIZE_MAX
 
79
 
 
80
extern "C" {                                    // Because of SCO 3.2V4.2
96
81
#include <errno.h>
97
82
#include <sys/stat.h>
98
 
#include "drizzled/option.h"
 
83
#include <mysys/my_getopt.h>
99
84
#ifdef HAVE_SYSENT_H
100
85
#include <sysent.h>
101
86
#endif
 
87
#ifdef HAVE_PWD_H
102
88
#include <pwd.h>                                // For getpwent
 
89
#endif
 
90
#ifdef HAVE_GRP_H
103
91
#include <grp.h>
 
92
#endif
 
93
 
 
94
#include <sys/resource.h>
104
95
 
105
96
#ifdef HAVE_SELECT_H
106
97
#  include <select.h>
116
107
#include <sys/mman.h>
117
108
#endif
118
109
 
 
110
#define SIGNAL_FMT "signal %d"
 
111
 
 
112
 
119
113
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
120
114
#include <ieeefp.h>
 
115
#ifdef HAVE_FP_EXCEPT                           // Fix type conflict
 
116
typedef fp_except fp_except_t;
 
117
#endif
121
118
#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
122
119
 
123
120
#ifdef HAVE_FPU_CONTROL_H
129
126
#include <sys/fpu.h>
130
127
#endif
131
128
 
132
 
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
133
 
#include "drizzled/constrained_value.h"
134
 
 
135
 
#include <drizzled/gettext.h>
136
 
 
137
 
 
138
 
#ifdef HAVE_VALGRIND
139
 
#define IF_PURIFY(A,B) (A)
140
 
#else
141
 
#define IF_PURIFY(A,B) (B)
142
 
#endif
143
 
 
144
 
#define MAX_MEM_TABLE_SIZE SIZE_MAX
145
 
#include <iostream>
146
 
#include <fstream>
147
 
 
148
 
 
149
 
using namespace std;
150
 
namespace fs=boost::filesystem;
151
 
namespace po=boost::program_options;
152
 
namespace dpo=drizzled::program_options;
153
 
 
154
 
 
155
 
namespace drizzled
156
 
{
157
 
 
158
 
#define mysqld_charset &my_charset_utf8_general_ci
 
129
 
159
130
inline void setup_fpu()
160
131
{
161
132
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
185
156
#endif /* __i386__ && HAVE_FPU_CONTROL_H && _FPU_DOUBLE */
186
157
}
187
158
 
 
159
} /* cplusplus */
 
160
 
 
161
#include <mysys/my_pthread.h>                   // For thr_setconcurency()
 
162
 
 
163
#include <drizzled/gettext.h>
 
164
 
188
165
#ifdef SOLARIS
189
166
extern "C" int gethostname(char *name, int namelen);
190
167
#endif
191
168
 
192
 
const char *first_keyword= "first";
 
169
extern "C" void handle_segfault(int sig);
 
170
 
 
171
using namespace std;
 
172
 
 
173
/* Constants */
 
174
 
 
175
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
 
176
/*
 
177
  WARNING: When adding new SQL modes don't forget to update the
 
178
           tables definitions that stores it's value.
 
179
           (ie: mysql.event, mysql.proc)
 
180
*/
 
181
static const char *optimizer_switch_names[]=
 
182
{
 
183
  "no_materialization", "no_semijoin",
 
184
  NULL
 
185
};
 
186
 
 
187
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
 
188
static const unsigned int optimizer_switch_names_len[]=
 
189
{
 
190
  /*no_materialization*/          19,
 
191
  /*no_semijoin*/                 11
 
192
};
 
193
 
 
194
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
 
195
                                    optimizer_switch_names,
 
196
                                    (unsigned int *)optimizer_switch_names_len };
 
197
 
 
198
static const char *tc_heuristic_recover_names[]=
 
199
{
 
200
  "COMMIT", "ROLLBACK", NULL
 
201
};
 
202
static TYPELIB tc_heuristic_recover_typelib=
 
203
{
 
204
  array_elements(tc_heuristic_recover_names)-1,"",
 
205
  tc_heuristic_recover_names, NULL
 
206
};
 
207
 
 
208
const char *first_keyword= "first", *binary_keyword= "BINARY";
 
209
const char *my_localhost= "localhost";
193
210
const char * const DRIZZLE_CONFIG_NAME= "drizzled";
194
 
 
195
211
#define GET_HA_ROWS GET_ULL
196
212
 
197
 
const char *tx_isolation_names[] =
198
 
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
199
 
  NULL};
200
 
 
201
 
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
202
 
                               tx_isolation_names, NULL};
203
 
 
204
213
/*
205
214
  Used with --help for detailed option
206
215
*/
207
 
bool opt_help= false;
 
216
static bool opt_help= false;
208
217
 
209
218
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
210
219
{{&Arg_comparator::compare_string,     &Arg_comparator::compare_e_string},
215
224
 
216
225
/* static variables */
217
226
 
218
 
static bool opt_debugging= false;
 
227
/* the default log output is log tables */
 
228
static bool volatile select_thread_in_use;
 
229
static bool volatile ready_to_exit;
 
230
static bool opt_debugging= 0;
219
231
static uint32_t wake_thread;
220
 
static char *drizzled_chroot;
221
 
static const char *default_character_set_name;
222
 
static const char *character_set_filesystem_name;
 
232
static uint32_t killed_threads;
 
233
static char *drizzled_user, *drizzled_chroot;
 
234
static char *language_ptr, *opt_init_connect;
 
235
static char *default_character_set_name;
 
236
static char *character_set_filesystem_name;
223
237
static char *lc_time_names_name;
 
238
static char *my_bind_addr_str;
224
239
static char *default_collation_name;
225
240
static char *default_storage_engine_str;
226
 
static const char *compiled_default_collation_name= "utf8_general_ci";
 
241
static char compiled_default_collation_name[]= DRIZZLE_DEFAULT_COLLATION_NAME;
 
242
static struct pollfd fds[UINT8_MAX];
 
243
static uint8_t pollfd_count= 0;
227
244
 
228
245
/* Global variables */
229
246
 
230
 
bool volatile ready_to_exit;
231
 
char *drizzled_user;
232
 
bool volatile select_thread_in_use;
 
247
bool server_id_supplied = 0;
 
248
bool opt_endinfo, using_udf_functions;
 
249
bool locked_in_memory;
233
250
bool volatile abort_loop;
234
251
bool volatile shutdown_in_progress;
235
 
char *opt_scheduler_default;
236
 
const char *opt_scheduler= NULL;
237
 
 
238
 
size_t my_thread_stack_size= 0;
239
 
 
240
 
/*
241
 
  Legacy global plugin::StorageEngine. These will be removed (please do not add more).
242
 
*/
243
 
plugin::StorageEngine *heap_engine;
244
 
plugin::StorageEngine *myisam_engine;
245
 
 
246
 
bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
247
 
 
248
 
uint32_t drizzled_bind_timeout;
249
 
std::bitset<12> test_flags;
250
 
uint32_t dropping_tables, ha_open_options;
 
252
uint32_t max_used_connections;
 
253
const char *opt_scheduler= "multi_thread";
 
254
 
 
255
size_t my_thread_stack_size= 65536;
 
256
 
 
257
/*
 
258
  Legacy global handlerton. These will be removed (please do not add more).
 
259
*/
 
260
handlerton *heap_hton;
 
261
handlerton *myisam_hton;
 
262
 
 
263
bool use_temp_pool;
 
264
char* opt_secure_file_priv= 0;
 
265
/*
 
266
  True if there is at least one per-hour limit for some user, so we should
 
267
  check them before each query (and possibly reset counters when hour is
 
268
  changed). False otherwise.
 
269
*/
 
270
bool opt_noacl;
 
271
 
 
272
#ifdef HAVE_INITGROUPS
 
273
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
 
274
#endif
 
275
uint32_t drizzled_port, test_flags, select_errors, dropping_tables, ha_open_options;
 
276
uint32_t drizzled_port_timeout;
 
277
uint32_t delay_key_write_options, protocol_version= PROTOCOL_VERSION;
 
278
uint32_t lower_case_table_names= 1;
251
279
uint32_t tc_heuristic_recover= 0;
252
280
uint64_t session_startup_options;
253
 
back_log_constraints back_log(50);
 
281
uint32_t back_log;
 
282
uint32_t connect_timeout;
254
283
uint32_t server_id;
255
284
uint64_t table_cache_size;
256
 
size_t table_def_size;
 
285
uint64_t table_def_size;
 
286
uint64_t slow_launch_time;
 
287
uint32_t refresh_version;  /* Increments on each reload */
 
288
uint64_t aborted_threads;
 
289
uint64_t aborted_connects;
257
290
uint64_t max_connect_errors;
258
 
uint32_t global_thread_id= 1UL;
 
291
uint32_t thread_id=1L;
259
292
pid_t current_pid;
260
 
 
261
 
extern const double log_10[309];
 
293
uint64_t slow_launch_threads= 0;
262
294
 
263
295
const double log_10[] = {
264
296
  1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
297
329
time_t server_start_time;
298
330
time_t flush_status_time;
299
331
 
300
 
fs::path basedir(PREFIX);
301
 
fs::path pid_file;
302
 
fs::path secure_file_priv("");
303
 
fs::path plugin_dir;
304
 
fs::path system_config_dir(SYSCONFDIR);
305
 
 
306
 
 
307
 
char system_time_zone[30];
 
332
/* FRM Junk */
 
333
const char *reg_ext= ".frm";
 
334
uint32_t reg_ext_length= 4;
 
335
 
 
336
char drizzle_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
308
337
char *default_tz_name;
309
338
char glob_hostname[FN_REFLEN];
310
 
 
311
 
char *opt_tc_log_file;
 
339
char drizzle_real_data_home[FN_REFLEN],
 
340
     language[FN_REFLEN], 
 
341
     *opt_init_file, 
 
342
     *opt_tc_log_file;
 
343
char drizzle_unpacked_real_data_home[FN_REFLEN];
312
344
const key_map key_map_empty(0);
313
345
key_map key_map_full(0);                        // Will be initialized later
314
346
 
315
 
std::string drizzle_tmpdir;
 
347
uint32_t drizzle_data_home_len;
 
348
char drizzle_data_home_buff[2], *drizzle_data_home=drizzle_real_data_home;
 
349
char server_version[SERVER_VERSION_LENGTH];
 
350
char *drizzle_tmpdir= NULL;
316
351
char *opt_drizzle_tmpdir= NULL;
 
352
const char *myisam_recover_options_str="OFF";
 
353
const char *myisam_stats_method_str="nulls_unequal";
317
354
 
318
355
/** name of reference on left espression in rewritten IN subquery */
319
356
const char *in_left_expr_name= "<left expr>";
326
363
 
327
364
FILE *stderror_file=0;
328
365
 
329
 
struct drizzle_system_variables global_system_variables;
330
 
struct drizzle_system_variables max_system_variables;
331
 
struct global_counters current_global_counters;
 
366
I_List<Session> session_list;
 
367
I_List<NAMED_LIST> key_caches;
 
368
 
 
369
struct system_variables global_system_variables;
 
370
struct system_variables max_system_variables;
 
371
struct system_status_var global_status_var;
 
372
 
 
373
MY_BITMAP temp_pool;
332
374
 
333
375
const CHARSET_INFO *system_charset_info, *files_charset_info ;
334
376
const CHARSET_INFO *table_alias_charset;
339
381
SHOW_COMP_OPTION have_symlink;
340
382
 
341
383
/* Thread specific variables */
342
 
boost::mutex LOCK_global_system_variables;
343
 
 
344
 
boost::condition_variable_any COND_refresh;
345
 
boost::condition_variable COND_thread_count;
 
384
 
 
385
pthread_key_t THR_Mem_root;
 
386
pthread_key_t THR_Session;
 
387
pthread_mutex_t LOCK_drizzleclient_create_db, 
 
388
                LOCK_open, 
 
389
                LOCK_thread_count,
 
390
                LOCK_status,
 
391
                LOCK_global_read_lock,
 
392
                LOCK_global_system_variables;
 
393
 
 
394
pthread_rwlock_t        LOCK_sys_init_connect;
 
395
pthread_rwlock_t        LOCK_system_variables_hash;
 
396
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
346
397
pthread_t signal_thread;
347
 
boost::condition_variable COND_server_end;
 
398
pthread_cond_t  COND_server_started;
 
399
 
 
400
/* replication parameters, if master_host is not NULL, we are a slave */
 
401
uint32_t report_port= DRIZZLE_PORT;
 
402
uint32_t master_retry_count= 0;
 
403
char *master_info_file;
 
404
char *report_host;
 
405
char *opt_logname;
348
406
 
349
407
/* Static variables */
350
408
 
 
409
static bool segfaulted;
 
410
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
411
static bool opt_do_pstack;
 
412
#endif /* HAVE_STACK_TRACE_ON_SEGV */
351
413
int cleanup_done;
352
 
 
353
 
passwd *user_info;
354
 
 
355
 
atomic<uint32_t> connection_count;
356
 
 
357
 
global_buffer_constraint<uint64_t> global_sort_buffer(0);
358
 
global_buffer_constraint<uint64_t> global_join_buffer(0);
359
 
global_buffer_constraint<uint64_t> global_read_rnd_buffer(0);
360
 
global_buffer_constraint<uint64_t> global_read_buffer(0);
361
 
 
362
 
/** 
363
 
  Refresh value. We use to test this to find out if a refresh even has happened recently.
 
414
static char *drizzle_home_ptr, *pidfile_name_ptr;
 
415
static int defaults_argc;
 
416
static char **defaults_argv;
 
417
 
 
418
struct rand_struct sql_rand; ///< used by sql_class.cc:Session::Session()
 
419
 
 
420
struct passwd *user_info;
 
421
static pthread_t select_thread;
 
422
static uint32_t thr_kill_signal;
 
423
 
 
424
extern scheduling_st thread_scheduler;
 
425
 
 
426
/**
 
427
  Number of currently active user connections. The variable is protected by
 
428
  LOCK_thread_count.
364
429
*/
365
 
uint64_t refresh_version;  /* Increments on each reload */
 
430
tbb::atomic<uint32_t> connection_count;
366
431
 
367
432
/* Function declarations */
368
 
bool drizzle_rm_tmp_tables();
369
433
 
 
434
extern "C" pthread_handler_t signal_hand(void *arg);
370
435
static void drizzle_init_variables(void);
371
 
static void get_options();
372
 
static void fix_paths();
 
436
static void get_options(int *argc,char **argv);
 
437
extern "C" bool drizzled_get_one_option(int, const struct my_option *, char *);
 
438
static void set_server_version(void);
 
439
static int init_thread_environment();
 
440
static const char *get_relative_path(const char *path);
 
441
static void fix_paths(void);
 
442
void handle_connections_sockets();
 
443
extern "C" pthread_handler_t handle_slave(void *arg);
 
444
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib);
 
445
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
446
                                   const char *option);
 
447
static void clean_up(bool print_message);
373
448
 
374
449
static void usage(void);
375
 
void close_connections(void);
376
 
 
377
 
fs::path base_plugin_dir(PKGPLUGINDIR);
378
 
 
379
 
po::options_description config_options("Config File Options");
380
 
po::options_description long_options("Kernel Options");
381
 
po::options_description plugin_load_options("Plugin Loading Options");
382
 
po::options_description plugin_options("Plugin Options");
383
 
po::options_description initial_options("Config and Plugin Loading");
384
 
po::options_description full_options("Kernel and Plugin Loading and Plugin");
385
 
vector<string> unknown_options;
386
 
vector<string> defaults_file_list;
387
 
po::variables_map vm;
388
 
 
389
 
fs::path data_home(LOCALSTATEDIR);
390
 
fs::path full_data_home(LOCALSTATEDIR);
391
 
 
392
 
po::variables_map &getVariablesMap()
393
 
{
394
 
  return vm;
395
 
}
396
 
 
397
 
fs::path& getDataHome()
398
 
{
399
 
  return data_home;
400
 
}
401
 
 
402
 
fs::path& getDataHomeCatalog()
403
 
{
404
 
  static fs::path data_home_catalog(getDataHome());
405
 
  return data_home_catalog;
406
 
}
407
 
 
408
 
 
 
450
static void clean_up_mutexes(void);
 
451
extern "C" bool safe_read_error_impl(NET *net);
 
452
 
409
453
/****************************************************************************
410
454
** Code to end drizzled
411
455
****************************************************************************/
412
456
 
413
457
void close_connections(void)
414
458
{
 
459
  int x;
 
460
 
415
461
  /* Abort listening to new connections */
416
 
  plugin::Listen::shutdown();
 
462
  for (x= 0; x < pollfd_count; x++)
 
463
  {
 
464
    if (fds[x].fd != -1)
 
465
    {
 
466
      (void) shutdown(fds[x].fd, SHUT_RDWR);
 
467
      (void) close(fds[x].fd);
 
468
      fds[x].fd= -1;
 
469
    }
 
470
  }
 
471
 
417
472
 
418
473
  /* kill connection thread */
 
474
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
475
 
 
476
  while (select_thread_in_use)
419
477
  {
420
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
478
    struct timespec abstime;
 
479
    int error;
421
480
 
422
 
    while (select_thread_in_use)
 
481
    set_timespec(abstime, 2);
 
482
    for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
423
483
    {
424
 
      boost::xtime xt; 
425
 
      xtime_get(&xt, boost::TIME_UTC); 
426
 
      xt.sec += 2; 
427
 
 
428
 
      for (uint32_t tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
429
 
      {
430
 
        bool success= COND_thread_count.timed_wait(scopedLock, xt);
431
 
        if (not success)
432
 
          break;
433
 
      }
 
484
      error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, &abstime);
 
485
      if (error != EINTR)
 
486
        break;
434
487
    }
435
488
  }
 
489
  (void) pthread_mutex_unlock(&LOCK_thread_count);
436
490
 
437
491
 
438
492
  /*
441
495
    statements and inform their clients that the server is about to die.
442
496
  */
443
497
 
 
498
  Session *tmp;
 
499
  (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
500
 
 
501
  I_List_iterator<Session> it(session_list);
 
502
  while ((tmp=it++))
444
503
  {
445
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
446
 
    session::Cache::list list= session::Cache::singleton().getCache();
447
 
 
448
 
    for (session::Cache::list::iterator it= list.begin(); it != list.end(); ++it )
 
504
    tmp->killed= Session::KILL_CONNECTION;
 
505
    thread_scheduler.post_kill_notification(tmp);
 
506
    if (tmp->mysys_var)
449
507
    {
450
 
      Session::shared_ptr tmp(*it);
451
 
 
452
 
      tmp->setKilled(Session::KILL_CONNECTION);
453
 
      tmp->scheduler->killSession(tmp.get());
454
 
      DRIZZLE_CONNECTION_DONE(tmp->thread_id);
455
 
 
456
 
      tmp->lockOnSys();
 
508
      tmp->mysys_var->abort=1;
 
509
      pthread_mutex_lock(&tmp->mysys_var->mutex);
 
510
      if (tmp->mysys_var->current_cond)
 
511
      {
 
512
        pthread_mutex_lock(tmp->mysys_var->current_mutex);
 
513
        pthread_cond_broadcast(tmp->mysys_var->current_cond);
 
514
        pthread_mutex_unlock(tmp->mysys_var->current_mutex);
 
515
      }
 
516
      pthread_mutex_unlock(&tmp->mysys_var->mutex);
457
517
    }
458
518
  }
 
519
  (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
459
520
 
460
 
  if (session::Cache::singleton().count())
 
521
  if (connection_count)
461
522
    sleep(2);                                   // Give threads time to die
462
523
 
463
524
  /*
467
528
  */
468
529
  for (;;)
469
530
  {
470
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
471
 
    session::Cache::list list= session::Cache::singleton().getCache();
472
 
 
473
 
    if (list.empty())
 
531
    (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
 
532
    if (!(tmp= session_list.get()))
474
533
    {
 
534
      (void) pthread_mutex_unlock(&LOCK_thread_count);
475
535
      break;
476
536
    }
477
 
    /* Close before unlock, avoiding crash. See LP bug#436685 */
478
 
    list.front()->client->close();
 
537
    (void) pthread_mutex_unlock(&LOCK_thread_count);
 
538
    unlink_session(tmp);
479
539
  }
480
 
}
481
 
 
482
 
 
483
 
void unireg_abort(int exit_code)
 
540
  assert(session_list.is_empty());
 
541
}
 
542
 
 
543
 
 
544
extern "C" void print_signal_warning(int sig)
 
545
{
 
546
  if (global_system_variables.log_warnings)
 
547
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64), sig,my_thread_id());
 
548
#ifndef HAVE_BSD_SIGNALS
 
549
  my_sigset(sig,print_signal_warning);          /* int. thread system calls */
 
550
#endif
 
551
  if (sig == SIGALRM)
 
552
    alarm(2);                                   /* reschedule alarm */
 
553
}
 
554
 
 
555
/**
 
556
  cleanup all memory and end program nicely.
 
557
 
 
558
    If SIGNALS_DONT_BREAK_READ is defined, this function is called
 
559
    by the main thread. To get Drizzle to shut down nicely in this case
 
560
    (Mac OS X) we have to call exit() instead if pthread_exit().
 
561
 
 
562
  @note
 
563
    This function never returns.
 
564
*/
 
565
extern "C" void unireg_end(void)
 
566
{
 
567
  clean_up(1);
 
568
  my_thread_end();
 
569
#if defined(SIGNALS_DONT_BREAK_READ)
 
570
  exit(0);
 
571
#else
 
572
  pthread_exit(0);                              // Exit is in main thread
 
573
#endif
 
574
}
 
575
 
 
576
 
 
577
extern "C" void unireg_abort(int exit_code)
484
578
{
485
579
 
486
580
  if (exit_code)
487
581
    errmsg_printf(ERRMSG_LVL_ERROR, _("Aborting\n"));
488
582
  else if (opt_help)
489
583
    usage();
490
 
  clean_up(!opt_help && (exit_code));
491
 
  internal::my_end();
492
 
  exit(exit_code);
 
584
  clean_up(!opt_help && (exit_code)); /* purecov: inspected */
 
585
  clean_up_mutexes();
 
586
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
587
  exit(exit_code); /* purecov: inspected */
493
588
}
494
589
 
495
590
 
496
 
void clean_up(bool print_message)
 
591
static void clean_up(bool print_message)
497
592
{
498
593
  if (cleanup_done++)
499
 
    return;
 
594
    return; /* purecov: inspected */
500
595
 
501
596
  table_cache_free();
 
597
  table_def_free();
 
598
  set_var_free();
502
599
  free_charsets();
503
 
  module::Registry &modules= module::Registry::singleton();
504
 
  modules.shutdownModules();
 
600
  udf_free();
 
601
  plugin_shutdown();
 
602
  ha_end();
505
603
  xid_cache_free();
506
 
 
507
 
  deinit_temporal_formats();
508
 
 
509
 
#if GOOGLE_PROTOBUF_VERSION >= 2001000
510
 
  google::protobuf::ShutdownProtobufLibrary();
511
 
#endif
512
 
 
513
 
  (void) unlink(pid_file.file_string().c_str());        // This may not always exist
 
604
  delete_elements(&key_caches, (void (*)(const char*, unsigned char*)) free_key_cache);
 
605
  multi_keycache_free();
 
606
  free_status_vars();
 
607
  my_free_open_file_info();
 
608
  if (defaults_argv)
 
609
    free_defaults(defaults_argv);
 
610
  free(sys_init_connect.value);
 
611
  free(drizzle_tmpdir);
 
612
  if (opt_secure_file_priv)
 
613
    free(opt_secure_file_priv);
 
614
  bitmap_free(&temp_pool);
 
615
 
 
616
  (void) unlink(pidfile_name);  // This may not always exist
514
617
 
515
618
  if (print_message && server_start_time)
516
 
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
517
 
  {
518
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
519
 
    ready_to_exit= true;
520
 
 
521
 
    /* do the broadcast inside the lock to ensure that my_end() is not called */
522
 
    COND_server_end.notify_all();
523
 
  }
 
619
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),my_progname);
 
620
  /* Returns NULL on globerrs, we don't want to try to free that */
 
621
  //void *freeme=
 
622
  (void *)my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
 
623
  // TODO!!!! EPIC FAIL!!!! This sefaults if uncommented.
 
624
/*  if (freeme != NULL)
 
625
    free(freeme);  */
 
626
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
627
  ready_to_exit=1;
 
628
  /* do the broadcast inside the lock to ensure that my_end() is not called */
 
629
  (void) pthread_cond_broadcast(&COND_thread_count);
 
630
  (void) pthread_mutex_unlock(&LOCK_thread_count);
524
631
 
525
632
  /*
526
633
    The following lines may never be executed as the main thread may have
529
636
} /* clean_up */
530
637
 
531
638
 
 
639
static void clean_up_mutexes()
 
640
{
 
641
  (void) pthread_mutex_destroy(&LOCK_drizzleclient_create_db);
 
642
  (void) pthread_mutex_destroy(&LOCK_lock_db);
 
643
  (void) pthread_mutex_destroy(&LOCK_open);
 
644
  (void) pthread_mutex_destroy(&LOCK_thread_count);
 
645
  (void) pthread_mutex_destroy(&LOCK_status);
 
646
  (void) pthread_rwlock_destroy(&LOCK_sys_init_connect);
 
647
  (void) pthread_mutex_destroy(&LOCK_global_system_variables);
 
648
  (void) pthread_rwlock_destroy(&LOCK_system_variables_hash);
 
649
  (void) pthread_mutex_destroy(&LOCK_global_read_lock);
 
650
  (void) pthread_cond_destroy(&COND_thread_count);
 
651
  (void) pthread_cond_destroy(&COND_refresh);
 
652
  (void) pthread_cond_destroy(&COND_global_read_lock);
 
653
}
 
654
 
 
655
 
 
656
/****************************************************************************
 
657
** Init IP and UNIX socket
 
658
****************************************************************************/
 
659
 
 
660
static void set_ports()
 
661
{
 
662
  char  *env;
 
663
  if (!drizzled_port)
 
664
  {                                     // Get port if not from commandline
 
665
    drizzled_port= DRIZZLE_PORT;
 
666
 
 
667
    /*
 
668
      if builder specifically requested a default port, use that
 
669
      (even if it coincides with our factory default).
 
670
      only if they didn't do we check /etc/services (and, failing
 
671
      on that, fall back to the factory default of 4427).
 
672
      either default can be overridden by the environment variable
 
673
      DRIZZLE_TCP_PORT, which in turn can be overridden with command
 
674
      line options.
 
675
    */
 
676
 
 
677
    struct  servent *serv_ptr;
 
678
    if ((serv_ptr= getservbyname("drizzle", "tcp")))
 
679
      drizzled_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
 
680
 
 
681
    if ((env = getenv("DRIZZLE_TCP_PORT")))
 
682
      drizzled_port= (uint32_t) atoi(env);              /* purecov: inspected */
 
683
 
 
684
    assert(drizzled_port);
 
685
  }
 
686
}
 
687
 
532
688
/* Change to run as another user if started with --user */
533
689
 
534
 
passwd *check_user(const char *user)
 
690
static struct passwd *check_user(const char *user)
535
691
{
536
 
  passwd *tmp_user_info;
 
692
  struct passwd *tmp_user_info;
537
693
  uid_t user_id= geteuid();
538
694
 
539
695
  // Don't bother if we aren't superuser
542
698
    if (user)
543
699
    {
544
700
      /* Don't give a warning, if real user is same as given with --user */
 
701
      /* purecov: begin tested */
545
702
      tmp_user_info= getpwnam(user);
546
703
      if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
547
704
          global_system_variables.log_warnings)
548
705
            errmsg_printf(ERRMSG_LVL_WARN, _("One can only use the --user switch "
549
706
                            "if running as root\n"));
 
707
      /* purecov: end */
550
708
    }
551
709
    return NULL;
552
710
  }
553
 
  if (not user)
 
711
  if (!user)
554
712
  {
555
713
      errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Please read \"Security\" section of "
556
714
                      "the manual to find out how to run drizzled as root!\n"));
557
715
    unireg_abort(1);
558
716
  }
 
717
  /* purecov: begin tested */
559
718
  if (!strcmp(user,"root"))
560
719
    return NULL;                        // Avoid problem with dynamic libraries
561
720
 
570
729
      goto err;
571
730
  }
572
731
  return tmp_user_info;
 
732
  /* purecov: end */
573
733
 
574
734
err:
575
735
  errmsg_printf(ERRMSG_LVL_ERROR, _("Fatal error: Can't change to run as user '%s' ;  "
577
737
  unireg_abort(1);
578
738
 
579
739
#ifdef PR_SET_DUMPABLE
580
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
740
  if (test_flags & TEST_CORE_ON_SIGNAL)
581
741
  {
582
742
    /* inform kernel that process is dumpable */
583
743
    (void) prctl(PR_SET_DUMPABLE, 1);
591
751
 
592
752
}
593
753
 
594
 
void set_user(const char *user, passwd *user_info_arg)
 
754
static void set_user(const char *user, struct passwd *user_info_arg)
595
755
{
 
756
  /* purecov: begin tested */
596
757
  assert(user_info_arg != 0);
 
758
#ifdef HAVE_INITGROUPS
 
759
  /*
 
760
    We can get a SIGSEGV when calling initgroups() on some systems when NSS
 
761
    is configured to use LDAP and the server is statically linked.  We set
 
762
    calling_initgroups as a flag to the SIGSEGV handler that is then used to
 
763
    output a specific message to help the user resolve this problem.
 
764
  */
 
765
  calling_initgroups= true;
597
766
  initgroups((char*) user, user_info_arg->pw_gid);
 
767
  calling_initgroups= false;
 
768
#endif
598
769
  if (setgid(user_info_arg->pw_gid) == -1)
599
770
  {
600
 
    sql_perror(N_("Set process group ID failed"));
 
771
    sql_perror("setgid");
601
772
    unireg_abort(1);
602
773
  }
603
774
  if (setuid(user_info_arg->pw_uid) == -1)
604
775
  {
605
 
    sql_perror(N_("Set process user ID failed"));
606
 
    unireg_abort(1);
607
 
  }
608
 
}
609
 
 
 
776
    sql_perror("setuid");
 
777
    unireg_abort(1);
 
778
  }
 
779
  /* purecov: end */
 
780
}
 
781
 
 
782
 
 
783
static void set_effective_user(struct passwd *user_info_arg)
 
784
{
 
785
  assert(user_info_arg != 0);
 
786
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
 
787
  {
 
788
    sql_perror("setregid");
 
789
    unireg_abort(1);
 
790
  }
 
791
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
 
792
  {
 
793
    sql_perror("setreuid");
 
794
    unireg_abort(1);
 
795
  }
 
796
}
610
797
 
611
798
 
612
799
/** Change root user if started with @c --chroot . */
614
801
{
615
802
  if ((chroot(path) == -1) || !chdir("/"))
616
803
  {
617
 
    sql_perror(N_("Process chroot failed"));
 
804
    sql_perror("chroot");
618
805
    unireg_abort(1);
619
806
  }
620
807
}
621
808
 
622
809
 
 
810
static void network_init(void)
 
811
{
 
812
  int   ret;
 
813
  uint32_t  waited;
 
814
  uint32_t  this_wait;
 
815
  uint32_t  retry;
 
816
  char port_buf[NI_MAXSERV];
 
817
  struct addrinfo *ai;
 
818
  struct addrinfo *next;
 
819
  struct addrinfo hints;
 
820
  int error;
 
821
 
 
822
  set_ports();
 
823
 
 
824
  memset(fds, 0, sizeof(struct pollfd) * UINT8_MAX);
 
825
  memset(&hints, 0, sizeof (hints));
 
826
  hints.ai_flags= AI_PASSIVE;
 
827
  hints.ai_socktype= SOCK_STREAM;
 
828
 
 
829
  snprintf(port_buf, NI_MAXSERV, "%d", drizzled_port);
 
830
  error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
 
831
  if (error != 0)
 
832
  {
 
833
    sql_perror(ER(ER_IPSOCK_ERROR));            /* purecov: tested */
 
834
    unireg_abort(1);                            /* purecov: tested */
 
835
  }
 
836
 
 
837
  for (next= ai, pollfd_count= 0; next; next= next->ai_next, pollfd_count++)
 
838
  {
 
839
    int ip_sock;
 
840
 
 
841
    ip_sock= socket(next->ai_family, next->ai_socktype, next->ai_protocol);
 
842
 
 
843
    if (ip_sock == -1)
 
844
    {
 
845
      sql_perror(ER(ER_IPSOCK_ERROR));          /* purecov: tested */
 
846
      unireg_abort(1);                          /* purecov: tested */
 
847
    }
 
848
 
 
849
    fds[pollfd_count].fd= ip_sock;
 
850
    fds[pollfd_count].events= POLLIN | POLLERR;
 
851
 
 
852
    /* Add options for our listening socket */
 
853
    {
 
854
      struct linger ling = {0, 0};
 
855
      int flags =1;
 
856
 
 
857
#ifdef IPV6_V6ONLY
 
858
      if (next->ai_family == AF_INET6)
 
859
      {
 
860
        error= setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
 
861
        if (error != 0)
 
862
        {
 
863
          perror("setsockopt");
 
864
          assert(error == 0);
 
865
        }
 
866
      }
 
867
#endif
 
868
      error= setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof(flags));
 
869
      if (error != 0)
 
870
      {
 
871
        perror("setsockopt");
 
872
        assert(error == 0);
 
873
      }
 
874
      error= setsockopt(ip_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
 
875
      if (error != 0)
 
876
      {
 
877
        perror("setsockopt");
 
878
        assert(error == 0);
 
879
      }
 
880
      error= setsockopt(ip_sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
 
881
      if (error != 0)
 
882
      {
 
883
        perror("setsockopt");
 
884
        assert(error == 0);
 
885
      }
 
886
      error= setsockopt(ip_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
 
887
      if (error != 0)
 
888
      {
 
889
        perror("setsockopt");
 
890
        assert(error == 0);
 
891
      }
 
892
    }
 
893
 
 
894
 
 
895
    /*
 
896
      Sometimes the port is not released fast enough when stopping and
 
897
      restarting the server. This happens quite often with the test suite
 
898
      on busy Linux systems. Retry to bind the address at these intervals:
 
899
      Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
 
900
      Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
 
901
      Limit the sequence by drizzled_port_timeout (set --port-open-timeout=#).
 
902
    */
 
903
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
 
904
    {
 
905
      if (((ret= ::bind(ip_sock, next->ai_addr, next->ai_addrlen)) >= 0 ) ||
 
906
          (errno != EADDRINUSE) ||
 
907
          (waited >= drizzled_port_timeout))
 
908
        break;
 
909
          errmsg_printf(ERRMSG_LVL_INFO, _("Retrying bind on TCP/IP port %u"), drizzled_port);
 
910
      this_wait= retry * retry / 3 + 1;
 
911
      sleep(this_wait);
 
912
    }
 
913
    if (ret < 0)
 
914
    {
 
915
      sql_perror(_("Can't start server: Bind on TCP/IP port"));
 
916
          errmsg_printf(ERRMSG_LVL_ERROR, _("Do you already have another drizzled server running "
 
917
                        "on port: %d ?"),drizzled_port);
 
918
      unireg_abort(1);
 
919
    }
 
920
    if (listen(ip_sock,(int) back_log) < 0)
 
921
    {
 
922
      sql_perror(_("Can't start server: listen() on TCP/IP port"));
 
923
          errmsg_printf(ERRMSG_LVL_ERROR, _("listen() on TCP/IP failed with error %d"),
 
924
                      errno);
 
925
      unireg_abort(1);
 
926
    }
 
927
  }
 
928
 
 
929
  freeaddrinfo(ai);
 
930
  return;
 
931
}
 
932
 
 
933
 
 
934
 
 
935
/** Called when a thread is aborted. */
 
936
/* ARGSUSED */
 
937
extern "C" void end_thread_signal(int )
 
938
{
 
939
  Session *session=current_session;
 
940
  if (session)
 
941
  {
 
942
    statistic_increment(killed_threads, &LOCK_status);
 
943
    (void)thread_scheduler.end_thread(session, 0);              /* purecov: inspected */
 
944
  }
 
945
  return;;                              /* purecov: deadcode */
 
946
}
 
947
 
 
948
 
623
949
/*
624
950
  Unlink session from global list of available connections and free session
625
951
 
626
952
  SYNOPSIS
627
 
    Session::unlink()
 
953
    unlink_session()
628
954
    session              Thread handler
 
955
 
 
956
  NOTES
 
957
    LOCK_thread_count is locked and left locked
629
958
*/
630
959
 
631
 
void drizzled::Session::unlink(Session::shared_ptr &session)
 
960
void unlink_session(Session *session)
632
961
{
633
 
  connection_count.decrement();
 
962
  connection_count--;
634
963
 
635
964
  session->cleanup();
636
965
 
637
 
  boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
638
 
 
639
 
  if (unlikely(plugin::EventObserver::disconnectSession(*session)))
640
 
  {
641
 
    // We should do something about an error...
642
 
  }
643
 
  session::Cache::singleton().erase(session);
644
 
}
645
 
 
 
966
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
967
  pthread_mutex_lock(&session->LOCK_delete);
 
968
  delete session;
 
969
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
970
 
 
971
  return;
 
972
}
 
973
 
 
974
 
 
975
#ifdef THREAD_SPECIFIC_SIGPIPE
 
976
/**
 
977
  Aborts a thread nicely. Comes here on SIGPIPE.
 
978
 
 
979
  @todo
 
980
    One should have to fix that thr_alarm know about this thread too.
 
981
*/
 
982
extern "C" void abort_thread(int )
 
983
{
 
984
  Session *session=current_session;
 
985
  if (session)
 
986
    session->killed= Session::KILL_CONNECTION;
 
987
  return;;
 
988
}
 
989
#endif
 
990
 
 
991
#if defined(BACKTRACE_DEMANGLE)
 
992
#include <cxxabi.h>
 
993
extern "C" char *my_demangle(const char *mangled_name, int *status)
 
994
{
 
995
  return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
 
996
}
 
997
#endif
 
998
 
 
999
 
 
1000
extern "C" void handle_segfault(int sig)
 
1001
{
 
1002
  time_t curr_time;
 
1003
  struct tm tm;
 
1004
 
 
1005
  /*
 
1006
    Strictly speaking, one needs a mutex here
 
1007
    but since we have got SIGSEGV already, things are a mess
 
1008
    so not having the mutex is not as bad as possibly using a buggy
 
1009
    mutex - so we keep things simple
 
1010
  */
 
1011
  if (segfaulted)
 
1012
  {
 
1013
    fprintf(stderr, _("Fatal " SIGNAL_FMT " while backtracing\n"), sig);
 
1014
    exit(1);
 
1015
  }
 
1016
 
 
1017
  segfaulted = 1;
 
1018
 
 
1019
  curr_time= time(NULL);
 
1020
  if(curr_time == (time_t)-1)
 
1021
  {
 
1022
    fprintf(stderr, "Fetal: time() call failed\n");
 
1023
    exit(1);
 
1024
  }
 
1025
 
 
1026
  localtime_r(&curr_time, &tm);
 
1027
 
 
1028
  fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d - drizzled got "
 
1029
          SIGNAL_FMT " ;\n"
 
1030
          "This could be because you hit a bug. It is also possible that "
 
1031
          "this binary\n or one of the libraries it was linked against is "
 
1032
          "corrupt, improperly built,\n or misconfigured. This error can "
 
1033
          "also be caused by malfunctioning hardware.\n",
 
1034
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
 
1035
          tm.tm_hour, tm.tm_min, tm.tm_sec,
 
1036
          sig);
 
1037
  fprintf(stderr, _("We will try our best to scrape up some info that "
 
1038
                    "will hopefully help diagnose\n"
 
1039
                    "the problem, but since we have already crashed, "
 
1040
                    "something is definitely wrong\nand this may fail.\n\n"));
 
1041
  fprintf(stderr, "key_buffer_size=%u\n",
 
1042
          (uint32_t) dflt_key_cache->key_cache_mem_size);
 
1043
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
 
1044
  fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
 
1045
  fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
 
1046
  fprintf(stderr, "thread_count=%u\n", thread_scheduler.count());
 
1047
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
 
1048
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
 
1049
                    "key_buffer_size + (read_buffer_size + "
 
1050
                    "sort_buffer_size)*max_threads = %"PRIu64" K\n"
 
1051
                    "bytes of memory\n"
 
1052
                    "Hope that's ok; if not, decrease some variables in the "
 
1053
                    "equation.\n\n"),
 
1054
          (uint64_t)(((uint32_t) dflt_key_cache->key_cache_mem_size +
 
1055
                     (global_system_variables.read_buff_size +
 
1056
                      global_system_variables.sortbuff_size) *
 
1057
                     thread_scheduler.max_threads) / 1024));
 
1058
 
 
1059
#ifdef HAVE_STACKTRACE
 
1060
  Session *session= current_session;
 
1061
 
 
1062
  if (!(test_flags & TEST_NO_STACKTRACE))
 
1063
  {
 
1064
    fprintf(stderr,"session: 0x%lx\n",(long) session);
 
1065
    fprintf(stderr,_("Attempting backtrace. You can use the following "
 
1066
                     "information to find out\n"
 
1067
                     "where drizzled died. If you see no messages after this, "
 
1068
                     "something went\n"
 
1069
                     "terribly wrong...\n"));
 
1070
    print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
 
1071
                     my_thread_stack_size);
 
1072
  }
 
1073
  if (session)
 
1074
  {
 
1075
    const char *kreason= "UNKNOWN";
 
1076
    switch (session->killed) {
 
1077
    case Session::NOT_KILLED:
 
1078
      kreason= "NOT_KILLED";
 
1079
      break;
 
1080
    case Session::KILL_BAD_DATA:
 
1081
      kreason= "KILL_BAD_DATA";
 
1082
      break;
 
1083
    case Session::KILL_CONNECTION:
 
1084
      kreason= "KILL_CONNECTION";
 
1085
      break;
 
1086
    case Session::KILL_QUERY:
 
1087
      kreason= "KILL_QUERY";
 
1088
      break;
 
1089
    case Session::KILLED_NO_VALUE:
 
1090
      kreason= "KILLED_NO_VALUE";
 
1091
      break;
 
1092
    }
 
1093
    fprintf(stderr, _("Trying to get some variables.\n"
 
1094
                      "Some pointers may be invalid and cause the "
 
1095
                      "dump to abort...\n"));
 
1096
    safe_print_str("session->query", session->query, 1024);
 
1097
    fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
 
1098
    fprintf(stderr, "session->killed=%s\n", kreason);
 
1099
  }
 
1100
  fflush(stderr);
 
1101
#endif /* HAVE_STACKTRACE */
 
1102
 
 
1103
#ifdef HAVE_INITGROUPS
 
1104
  if (calling_initgroups)
 
1105
    fprintf(stderr, _("\nThis crash occurred while the server was calling "
 
1106
                      "initgroups(). This is\n"
 
1107
                      "often due to the use of a drizzled that is statically "
 
1108
                      "linked against glibc\n"
 
1109
                      "and configured to use LDAP in /etc/nsswitch.conf. "
 
1110
                      "You will need to either\n"
 
1111
                      "upgrade to a version of glibc that does not have this "
 
1112
                      "problem (2.3.4 or\n"
 
1113
                      "later when used with nscd), disable LDAP in your "
 
1114
                      "nsswitch.conf, or use a\n"
 
1115
                      "drizzled that is not statically linked.\n"));
 
1116
#endif
 
1117
 
 
1118
  if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
 
1119
    fprintf(stderr,
 
1120
            _("\nYou are running a statically-linked LinuxThreads binary "
 
1121
              "on an NPTL system.\n"
 
1122
              "This can result in crashes on some distributions due "
 
1123
              "to LT/NPTL conflicts.\n"
 
1124
              "You should either build a dynamically-linked binary, or force "
 
1125
              "LinuxThreads\n"
 
1126
              "to be used with the LD_ASSUME_KERNEL environment variable. "
 
1127
              "Please consult\n"
 
1128
              "the documentation for your distribution on how to do that.\n"));
 
1129
 
 
1130
  if (locked_in_memory)
 
1131
  {
 
1132
    fprintf(stderr,
 
1133
            _("\nThe '--memlock' argument, which was enabled, uses system "
 
1134
              "calls that are\n"
 
1135
              "unreliable and unstable on some operating systems and "
 
1136
              "operating-system\n"
 
1137
              "versions (notably, some versions of Linux).  "
 
1138
              "This crash could be due to use\n"
 
1139
              "of those buggy OS calls.  You should consider whether you "
 
1140
              "really need the\n"
 
1141
              "'--memlock' parameter and/or consult the OS "
 
1142
              "distributor about 'mlockall'\n bugs.\n"));
 
1143
  }
 
1144
 
 
1145
#ifdef HAVE_WRITE_CORE
 
1146
  if (test_flags & TEST_CORE_ON_SIGNAL)
 
1147
  {
 
1148
    fprintf(stderr, _("Writing a core file\n"));
 
1149
    fflush(stderr);
 
1150
    write_core(sig);
 
1151
  }
 
1152
#endif
 
1153
 
 
1154
  exit(1);
 
1155
}
646
1156
 
647
1157
#ifndef SA_RESETHAND
648
1158
#define SA_RESETHAND 0
651
1161
#define SA_NODEFER 0
652
1162
#endif
653
1163
 
654
 
 
655
 
 
656
 
 
657
 
const char *load_default_groups[]= 
658
 
{
659
 
  DRIZZLE_CONFIG_NAME, "server", 0, 0
 
1164
static void init_signals(void)
 
1165
{
 
1166
  sigset_t set;
 
1167
  struct sigaction sa;
 
1168
 
 
1169
  if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
 
1170
  {
 
1171
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
 
1172
    sigemptyset(&sa.sa_mask);
 
1173
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
 
1174
 
 
1175
    init_stacktrace();
 
1176
    sa.sa_handler=handle_segfault;
 
1177
    sigaction(SIGSEGV, &sa, NULL);
 
1178
    sigaction(SIGABRT, &sa, NULL);
 
1179
#ifdef SIGBUS
 
1180
    sigaction(SIGBUS, &sa, NULL);
 
1181
#endif
 
1182
    sigaction(SIGILL, &sa, NULL);
 
1183
    sigaction(SIGFPE, &sa, NULL);
 
1184
  }
 
1185
 
 
1186
#ifdef HAVE_GETRLIMIT
 
1187
  if (test_flags & TEST_CORE_ON_SIGNAL)
 
1188
  {
 
1189
    /* Change limits so that we will get a core file */
 
1190
    struct rlimit rl;
 
1191
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
 
1192
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
 
1193
        errmsg_printf(ERRMSG_LVL_WARN, _("setrlimit could not change the size of core files "
 
1194
                          "to 'infinity';  We may not be able to generate a "
 
1195
                          "core file on signals"));
 
1196
  }
 
1197
#endif
 
1198
  (void) sigemptyset(&set);
 
1199
  my_sigset(SIGPIPE,SIG_IGN);
 
1200
  sigaddset(&set,SIGPIPE);
 
1201
#ifndef IGNORE_SIGHUP_SIGQUIT
 
1202
  sigaddset(&set,SIGQUIT);
 
1203
  sigaddset(&set,SIGHUP);
 
1204
#endif
 
1205
  sigaddset(&set,SIGTERM);
 
1206
 
 
1207
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
 
1208
  sigemptyset(&sa.sa_mask);
 
1209
  sa.sa_flags = 0;
 
1210
  sa.sa_handler = print_signal_warning;
 
1211
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
 
1212
  sa.sa_flags = 0;
 
1213
  sa.sa_handler = print_signal_warning;
 
1214
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
 
1215
#ifdef SIGTSTP
 
1216
  sigaddset(&set,SIGTSTP);
 
1217
#endif
 
1218
  if (test_flags & TEST_SIGINT)
 
1219
  {
 
1220
    my_sigset(thr_kill_signal, end_thread_signal);
 
1221
    // May be SIGINT
 
1222
    sigdelset(&set, thr_kill_signal);
 
1223
  }
 
1224
  else
 
1225
    sigaddset(&set,SIGINT);
 
1226
  sigprocmask(SIG_SETMASK,&set,NULL);
 
1227
  pthread_sigmask(SIG_SETMASK,&set,NULL);
 
1228
  return;;
 
1229
}
 
1230
 
 
1231
static void check_data_home(const char *)
 
1232
{}
 
1233
 
 
1234
 
 
1235
/**
 
1236
  All global error messages are sent here where the first one is stored
 
1237
  for the client.
 
1238
*/
 
1239
/* ARGSUSED */
 
1240
extern "C" void my_message_sql(uint32_t error, const char *str, myf MyFlags);
 
1241
 
 
1242
void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
1243
{
 
1244
  Session *session;
 
1245
  /*
 
1246
    Put here following assertion when situation with EE_* error codes
 
1247
    will be fixed
 
1248
  */
 
1249
  if ((session= current_session))
 
1250
  {
 
1251
    if (MyFlags & ME_FATALERROR)
 
1252
      session->is_fatal_error= 1;
 
1253
 
 
1254
    /*
 
1255
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
 
1256
      this could be improved by having a common stack of handlers.
 
1257
    */
 
1258
    if (session->handle_error(error, str,
 
1259
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
 
1260
      return;;
 
1261
 
 
1262
    /*
 
1263
      session->lex->current_select == 0 if lex structure is not inited
 
1264
      (not query command (COM_QUERY))
 
1265
    */
 
1266
    if (! (session->lex->current_select &&
 
1267
        session->lex->current_select->no_error && !session->is_fatal_error))
 
1268
    {
 
1269
      if (! session->main_da.is_error())            // Return only first message
 
1270
      {
 
1271
        if (error == 0)
 
1272
          error= ER_UNKNOWN_ERROR;
 
1273
        if (str == NULL)
 
1274
          str= ER(error);
 
1275
        session->main_da.set_error_status(session, error, str);
 
1276
      }
 
1277
    }
 
1278
 
 
1279
    if (!session->no_warnings_for_error && !session->is_fatal_error)
 
1280
    {
 
1281
      /*
 
1282
        Suppress infinite recursion if there a memory allocation error
 
1283
        inside push_warning.
 
1284
      */
 
1285
      session->no_warnings_for_error= true;
 
1286
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
 
1287
      session->no_warnings_for_error= false;
 
1288
    }
 
1289
  }
 
1290
  if (!session || MyFlags & ME_NOREFRESH)
 
1291
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str); /* purecov: inspected */
 
1292
  return;;
 
1293
}
 
1294
 
 
1295
 
 
1296
static const char *load_default_groups[]= {
 
1297
DRIZZLE_CONFIG_NAME,"server", DRIZZLE_BASE_VERSION, 0, 0};
 
1298
 
 
1299
SHOW_VAR com_status_vars[]= {
 
1300
  {"admin_commands",       (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
 
1301
  {"assign_to_keycache",   (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
 
1302
  {"alter_db",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
 
1303
  {"alter_table",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
 
1304
  {"analyze",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
 
1305
  {"begin",                (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
 
1306
  {"change_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
 
1307
  {"check",                (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECK]), SHOW_LONG_STATUS},
 
1308
  {"checksum",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
 
1309
  {"commit",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
 
1310
  {"create_db",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
 
1311
  {"create_index",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
 
1312
  {"create_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
 
1313
  {"delete",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE]), SHOW_LONG_STATUS},
 
1314
  {"delete_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
 
1315
  {"drop_db",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
 
1316
  {"drop_index",           (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
 
1317
  {"drop_table",           (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
 
1318
  {"empty_query",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
 
1319
  {"flush",                (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
 
1320
  {"insert",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT]), SHOW_LONG_STATUS},
 
1321
  {"insert_select",        (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
 
1322
  {"kill",                 (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_KILL]), SHOW_LONG_STATUS},
 
1323
  {"load",                 (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOAD]), SHOW_LONG_STATUS},
 
1324
  {"lock_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
 
1325
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
 
1326
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
 
1327
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
 
1328
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
 
1329
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
 
1330
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
 
1331
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
 
1332
  {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
 
1333
  {"savepoint",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
 
1334
  {"select",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SELECT]), SHOW_LONG_STATUS},
 
1335
  {"set_option",           (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
 
1336
  {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
 
1337
  {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
 
1338
  {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
 
1339
  {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
 
1340
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
 
1341
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
 
1342
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
 
1343
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
 
1344
  {"show_plugins",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
 
1345
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
 
1346
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
 
1347
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
 
1348
  {"show_tables",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
 
1349
  {"show_variables",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
 
1350
  {"show_warnings",        (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
 
1351
  {"truncate",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
 
1352
  {"unlock_tables",        (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
 
1353
  {"update",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
 
1354
  {"update_multi",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
 
1355
  {NULL, NULL, SHOW_LONGLONG}
660
1356
};
661
1357
 
662
 
static void find_plugin_dir(string progname)
663
 
{
664
 
  if (progname[0] != FN_LIBCHAR)
665
 
  {
666
 
    /* We have a relative path and need to find the absolute */
667
 
    char working_dir[FN_REFLEN];
668
 
    char *working_dir_ptr= working_dir;
669
 
    working_dir_ptr= getcwd(working_dir_ptr, FN_REFLEN);
670
 
    string new_path(working_dir);
671
 
    if (*(new_path.end()-1) != '/')
672
 
      new_path.push_back('/');
673
 
    if (progname[0] == '.' && progname[1] == '/')
674
 
      new_path.append(progname.substr(2));
675
 
    else
676
 
      new_path.append(progname);
677
 
    progname.swap(new_path);
678
 
  }
679
 
 
680
 
  /* Now, trim off the exe name */
681
 
  string progdir(progname.substr(0, progname.rfind(FN_LIBCHAR)+1));
682
 
  if (progdir.rfind(".libs/") != string::npos)
683
 
  {
684
 
    progdir.assign(progdir.substr(0, progdir.rfind(".libs/")));
685
 
  }
686
 
  string testlofile(progdir);
687
 
  testlofile.append("drizzled.lo");
688
 
  string testofile(progdir);
689
 
  testofile.append("drizzled.o");
690
 
  struct stat testfile_stat;
691
 
  if (not (stat(testlofile.c_str(), &testfile_stat) && stat(testofile.c_str(), &testfile_stat)))
692
 
  {
693
 
    /* We are in a source dir! Plugin dir is ../plugin/.libs */
694
 
    size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
695
 
    base_plugin_dir= progdir.substr(0,last_libchar_pos);
696
 
    base_plugin_dir /= "plugin";
697
 
    base_plugin_dir /= ".libs";
698
 
  }
699
 
 
700
 
  if (plugin_dir.root_directory() == "")
701
 
  {
702
 
    fs::path full_plugin_dir(fs::system_complete(base_plugin_dir));
703
 
    full_plugin_dir /= plugin_dir;
704
 
    plugin_dir= full_plugin_dir;
705
 
  }
706
 
}
707
 
 
708
 
static void notify_plugin_dir(fs::path in_plugin_dir)
709
 
{
710
 
  plugin_dir= in_plugin_dir;
711
 
  if (plugin_dir.root_directory() == "")
712
 
  {
713
 
    fs::path full_plugin_dir(fs::system_complete(basedir));
714
 
    full_plugin_dir /= plugin_dir;
715
 
    plugin_dir= full_plugin_dir;
716
 
  }
717
 
}
718
 
 
719
 
static void expand_secure_file_priv(fs::path in_secure_file_priv)
720
 
{
721
 
  secure_file_priv= fs::system_complete(in_secure_file_priv);
722
 
}
723
 
 
724
 
static void check_limits_aii(uint64_t in_auto_increment_increment)
725
 
{
726
 
  global_system_variables.auto_increment_increment= 1;
727
 
  if (in_auto_increment_increment < 1 || in_auto_increment_increment > UINT64_MAX)
728
 
  {
729
 
    cout << N_("Error: Invalid Value for auto_increment_increment");
730
 
    exit(-1);
731
 
  }
732
 
  global_system_variables.auto_increment_increment= in_auto_increment_increment;
733
 
}
734
 
 
735
 
static void check_limits_aio(uint64_t in_auto_increment_offset)
736
 
{
737
 
  global_system_variables.auto_increment_offset= 1;
738
 
  if (in_auto_increment_offset < 1 || in_auto_increment_offset > UINT64_MAX)
739
 
  {
740
 
    cout << N_("Error: Invalid Value for auto_increment_offset");
741
 
    exit(-1);
742
 
  }
743
 
  global_system_variables.auto_increment_offset= in_auto_increment_offset;
744
 
}
745
 
 
746
 
static void check_limits_completion_type(uint32_t in_completion_type)
747
 
{
748
 
  global_system_variables.completion_type= 0;
749
 
  if (in_completion_type > 2)
750
 
  {
751
 
    cout << N_("Error: Invalid Value for completion_type");
752
 
    exit(-1);
753
 
  }
754
 
  global_system_variables.completion_type= in_completion_type;
755
 
}
756
 
 
757
 
 
758
 
static void check_limits_dpi(uint32_t in_div_precincrement)
759
 
{
760
 
  global_system_variables.div_precincrement= 4;
761
 
  if (in_div_precincrement > DECIMAL_MAX_SCALE)
762
 
  {
763
 
    cout << N_("Error: Invalid Value for div-precision-increment");
764
 
    exit(-1);
765
 
  }
766
 
  global_system_variables.div_precincrement= in_div_precincrement;
767
 
}
768
 
 
769
 
static void check_limits_gcml(uint64_t in_group_concat_max_len)
770
 
{
771
 
  global_system_variables.group_concat_max_len= 1024;
772
 
  if (in_group_concat_max_len > ULONG_MAX || in_group_concat_max_len < 4)
773
 
  {
774
 
    cout << N_("Error: Invalid Value for group_concat_max_len");
775
 
    exit(-1);
776
 
  }
777
 
  global_system_variables.group_concat_max_len= in_group_concat_max_len;
778
 
}
779
 
 
780
 
static void check_limits_join_buffer_size(uint64_t in_join_buffer_size)
781
 
{
782
 
  global_system_variables.join_buff_size= (128*1024L);
783
 
  if (in_join_buffer_size < IO_SIZE*2 || in_join_buffer_size > ULONG_MAX)
784
 
  {
785
 
    cout << N_("Error: Invalid Value for join_buffer_size");
786
 
    exit(-1);
787
 
  }
788
 
  in_join_buffer_size-= in_join_buffer_size % IO_SIZE;
789
 
  global_system_variables.join_buff_size= in_join_buffer_size;
790
 
}
791
 
 
792
 
static void check_limits_map(uint32_t in_max_allowed_packet)
793
 
{
794
 
  global_system_variables.max_allowed_packet= (64*1024*1024L);
795
 
  if (in_max_allowed_packet < 1024 || in_max_allowed_packet > 1024*1024L*1024L)
796
 
  {
797
 
    cout << N_("Error: Invalid Value for max_allowed_packet");
798
 
    exit(-1);
799
 
  }
800
 
  in_max_allowed_packet-= in_max_allowed_packet % 1024;
801
 
  global_system_variables.max_allowed_packet= in_max_allowed_packet;
802
 
}
803
 
 
804
 
static void check_limits_mce(uint64_t in_max_connect_errors)
805
 
{
806
 
  max_connect_errors= MAX_CONNECT_ERRORS;
807
 
  if (in_max_connect_errors < 1 || in_max_connect_errors > ULONG_MAX)
808
 
  {
809
 
    cout << N_("Error: Invalid Value for max_connect_errors");
810
 
    exit(-1);
811
 
  }
812
 
  max_connect_errors= in_max_connect_errors;
813
 
}
814
 
 
815
 
static void check_limits_max_err_cnt(uint64_t in_max_error_count)
816
 
{
817
 
  global_system_variables.max_error_count= DEFAULT_ERROR_COUNT;
818
 
  if (in_max_error_count > 65535)
819
 
  {
820
 
    cout << N_("Error: Invalid Value for max_error_count");
821
 
    exit(-1);
822
 
  }
823
 
  global_system_variables.max_error_count= in_max_error_count;
824
 
}
825
 
 
826
 
static void check_limits_mhts(uint64_t in_max_heap_table_size)
827
 
{
828
 
  global_system_variables.max_heap_table_size= (16*1024*1024L);
829
 
  if (in_max_heap_table_size < 16384 || in_max_heap_table_size > MAX_MEM_TABLE_SIZE)
830
 
  {
831
 
    cout << N_("Error: Invalid Value for max_heap_table_size");
832
 
    exit(-1);
833
 
  }
834
 
  in_max_heap_table_size-= in_max_heap_table_size % 1024;
835
 
  global_system_variables.max_heap_table_size= in_max_heap_table_size;
836
 
}
837
 
 
838
 
static void check_limits_merl(uint64_t in_min_examined_row_limit)
839
 
{
840
 
  global_system_variables.min_examined_row_limit= 0;
841
 
  if (in_min_examined_row_limit > ULONG_MAX)
842
 
  {
843
 
    cout << N_("Error: Invalid Value for min_examined_row_limit");
844
 
    exit(-1);
845
 
  }
846
 
  global_system_variables.min_examined_row_limit= in_min_examined_row_limit;
847
 
}
848
 
 
849
 
static void check_limits_max_join_size(drizzled::ha_rows in_max_join_size)
850
 
{
851
 
  global_system_variables.max_join_size= INT32_MAX;
852
 
  if ((uint64_t)in_max_join_size < 1 || (uint64_t)in_max_join_size > INT32_MAX)
853
 
  {
854
 
    cout << N_("Error: Invalid Value for max_join_size");
855
 
    exit(-1);
856
 
  }
857
 
  global_system_variables.max_join_size= in_max_join_size;
858
 
}
859
 
 
860
 
static void check_limits_mlfsd(int64_t in_max_length_for_sort_data)
861
 
{
862
 
  global_system_variables.max_length_for_sort_data= 1024;
863
 
  if (in_max_length_for_sort_data < 4 || in_max_length_for_sort_data > 8192*1024L)
864
 
  {
865
 
    cout << N_("Error: Invalid Value for max_length_for_sort_data");
866
 
    exit(-1);
867
 
  }
868
 
  global_system_variables.max_length_for_sort_data= in_max_length_for_sort_data;
869
 
}
870
 
 
871
 
static void check_limits_msfk(uint64_t in_max_seeks_for_key)
872
 
{
873
 
  global_system_variables.max_seeks_for_key= ULONG_MAX;
874
 
  if (in_max_seeks_for_key < 1 || in_max_seeks_for_key > ULONG_MAX)
875
 
  {
876
 
    cout << N_("Error: Invalid Value for max_seeks_for_key");
877
 
    exit(-1);
878
 
  }
879
 
  global_system_variables.max_seeks_for_key= in_max_seeks_for_key;
880
 
}
881
 
 
882
 
static void check_limits_max_sort_length(size_t in_max_sort_length)
883
 
{
884
 
  global_system_variables.max_sort_length= 1024;
885
 
  if ((int64_t)in_max_sort_length < 4 || (int64_t)in_max_sort_length > 8192*1024L)
886
 
  {
887
 
    cout << N_("Error: Invalid Value for max_sort_length");
888
 
    exit(-1);
889
 
  }
890
 
  global_system_variables.max_sort_length= in_max_sort_length;
891
 
}
892
 
 
893
 
static void check_limits_osd(uint32_t in_optimizer_search_depth)
894
 
{
895
 
  global_system_variables.optimizer_search_depth= 0;
896
 
  if (in_optimizer_search_depth > MAX_TABLES + 2)
897
 
  {
898
 
    cout << N_("Error: Invalid Value for optimizer_search_depth");
899
 
    exit(-1);
900
 
  }
901
 
  global_system_variables.optimizer_search_depth= in_optimizer_search_depth;
902
 
}
903
 
 
904
 
static void check_limits_pbs(uint64_t in_preload_buff_size)
905
 
{
906
 
  global_system_variables.preload_buff_size= (32*1024L);
907
 
  if (in_preload_buff_size < 1024 || in_preload_buff_size > 1024*1024*1024L)
908
 
  {
909
 
    cout << N_("Error: Invalid Value for preload_buff_size");
910
 
    exit(-1);
911
 
  }
912
 
  global_system_variables.preload_buff_size= in_preload_buff_size;
913
 
}
914
 
 
915
 
static void check_limits_qabs(uint32_t in_query_alloc_block_size)
916
 
{
917
 
  global_system_variables.query_alloc_block_size= QUERY_ALLOC_BLOCK_SIZE;
918
 
  if (in_query_alloc_block_size < 1024)
919
 
  {
920
 
    cout << N_("Error: Invalid Value for query_alloc_block_size");
921
 
    exit(-1);
922
 
  }
923
 
  in_query_alloc_block_size-= in_query_alloc_block_size % 1024;
924
 
  global_system_variables.query_alloc_block_size= in_query_alloc_block_size;
925
 
}
926
 
 
927
 
static void check_limits_qps(uint32_t in_query_prealloc_size)
928
 
{
929
 
  global_system_variables.query_prealloc_size= QUERY_ALLOC_PREALLOC_SIZE;
930
 
  if (in_query_prealloc_size < QUERY_ALLOC_PREALLOC_SIZE)
931
 
  {
932
 
    cout << N_("Error: Invalid Value for query_prealloc_size");
933
 
    exit(-1);
934
 
  }
935
 
  in_query_prealloc_size-= in_query_prealloc_size % 1024;
936
 
  global_system_variables.query_prealloc_size= in_query_prealloc_size;
937
 
}
938
 
 
939
 
static void check_limits_rabs(size_t in_range_alloc_block_size)
940
 
{
941
 
  global_system_variables.range_alloc_block_size= RANGE_ALLOC_BLOCK_SIZE;
942
 
  if (in_range_alloc_block_size < RANGE_ALLOC_BLOCK_SIZE)
943
 
  {
944
 
    cout << N_("Error: Invalid Value for range_alloc_block_size");
945
 
    exit(-1);
946
 
  }
947
 
  in_range_alloc_block_size-= in_range_alloc_block_size % 1024;
948
 
  global_system_variables.range_alloc_block_size= in_range_alloc_block_size;
949
 
}
950
 
 
951
 
static void check_limits_read_buffer_size(int32_t in_read_buff_size)
952
 
{
953
 
  global_system_variables.read_buff_size= (128*1024L);
954
 
  if (in_read_buff_size < IO_SIZE*2 || in_read_buff_size > INT32_MAX)
955
 
  {
956
 
    cout << N_("Error: Invalid Value for read_buff_size");
957
 
    exit(-1);
958
 
  }
959
 
  in_read_buff_size-= in_read_buff_size % IO_SIZE;
960
 
  global_system_variables.read_buff_size= in_read_buff_size;
961
 
}
962
 
 
963
 
static void check_limits_read_rnd_buffer_size(uint32_t in_read_rnd_buff_size)
964
 
{
965
 
  global_system_variables.read_rnd_buff_size= (256*1024L);
966
 
  if (in_read_rnd_buff_size < 64 || in_read_rnd_buff_size > UINT32_MAX)
967
 
  {
968
 
    cout << N_("Error: Invalid Value for read_rnd_buff_size");
969
 
    exit(-1);
970
 
  }
971
 
  global_system_variables.read_rnd_buff_size= in_read_rnd_buff_size;
972
 
}
973
 
 
974
 
static void check_limits_sort_buffer_size(size_t in_sortbuff_size)
975
 
{
976
 
  global_system_variables.sortbuff_size= MAX_SORT_MEMORY;
977
 
  if ((uint32_t)in_sortbuff_size < MIN_SORT_MEMORY)
978
 
  {
979
 
    cout << N_("Error: Invalid Value for sort_buff_size");
980
 
    exit(-1);
981
 
  }
982
 
  global_system_variables.sortbuff_size= in_sortbuff_size;
983
 
}
984
 
 
985
 
static void check_limits_tdc(uint32_t in_table_def_size)
986
 
{
987
 
  table_def_size= 128;
988
 
  if (in_table_def_size < 1 || in_table_def_size > 512*1024L)
989
 
  {
990
 
    cout << N_("Error: Invalid Value for table_def_size");
991
 
    exit(-1);
992
 
  }
993
 
  table_def_size= in_table_def_size;
994
 
}
995
 
 
996
 
static void check_limits_toc(uint32_t in_table_cache_size)
997
 
{
998
 
  table_cache_size= TABLE_OPEN_CACHE_DEFAULT;
999
 
  if (in_table_cache_size < TABLE_OPEN_CACHE_MIN || in_table_cache_size > 512*1024L)
1000
 
  {
1001
 
    cout << N_("Error: Invalid Value for table_cache_size");
1002
 
    exit(-1);
1003
 
  }
1004
 
  table_cache_size= in_table_cache_size;
1005
 
}
1006
 
 
1007
 
static void check_limits_tlwt(uint64_t in_table_lock_wait_timeout)
1008
 
{
1009
 
  table_lock_wait_timeout= 50;
1010
 
  if (in_table_lock_wait_timeout < 1 || in_table_lock_wait_timeout > 1024*1024*1024)
1011
 
  {
1012
 
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1013
 
    exit(-1);
1014
 
  }
1015
 
  table_lock_wait_timeout= in_table_lock_wait_timeout;
1016
 
}
1017
 
 
1018
 
static void check_limits_thread_stack(uint32_t in_my_thread_stack_size)
1019
 
{
1020
 
  my_thread_stack_size= in_my_thread_stack_size - (in_my_thread_stack_size % 1024);
1021
 
}
1022
 
 
1023
 
static void check_limits_tmp_table_size(uint64_t in_tmp_table_size)
1024
 
{
1025
 
  global_system_variables.tmp_table_size= 16*1024*1024L;
1026
 
  if (in_tmp_table_size < 1024 || in_tmp_table_size > MAX_MEM_TABLE_SIZE)
1027
 
  {
1028
 
    cout << N_("Error: Invalid Value for table_lock_wait_timeout");
1029
 
    exit(-1);
1030
 
  }
1031
 
  global_system_variables.tmp_table_size= in_tmp_table_size;
1032
 
}
1033
 
 
1034
 
static void check_limits_transaction_message_threshold(size_t in_transaction_message_threshold)
1035
 
{
1036
 
  global_system_variables.transaction_message_threshold= 1024*1024;
1037
 
  if ((int64_t) in_transaction_message_threshold < 128*1024 || (int64_t)in_transaction_message_threshold > 1024*1024)
1038
 
  {
1039
 
    cout << N_("Error: Invalid Value for transaction_message_threshold valid values are between 131072 - 1048576 bytes");
1040
 
    exit(-1);
1041
 
  }
1042
 
  global_system_variables.transaction_message_threshold= in_transaction_message_threshold;
1043
 
}
1044
 
 
1045
 
static void process_defaults_files()
1046
 
{
1047
 
  for (vector<string>::iterator iter= defaults_file_list.begin();
1048
 
       iter != defaults_file_list.end();
1049
 
       ++iter)
1050
 
  {
1051
 
    fs::path file_location= *iter;
1052
 
 
1053
 
    ifstream input_defaults_file(file_location.file_string().c_str());
1054
 
    
1055
 
    po::parsed_options file_parsed=
1056
 
      dpo::parse_config_file(input_defaults_file, full_options, true);
1057
 
    vector<string> file_unknown= 
1058
 
      po::collect_unrecognized(file_parsed.options, po::include_positional);
1059
 
 
1060
 
    for (vector<string>::iterator it= file_unknown.begin();
1061
 
         it != file_unknown.end();
1062
 
         ++it)
1063
 
    {
1064
 
      string new_unknown_opt("--");
1065
 
      new_unknown_opt.append(*it);
1066
 
      ++it;
1067
 
      if (it != file_unknown.end())
1068
 
      {
1069
 
        if ((*it) != "true")
1070
 
        {
1071
 
          new_unknown_opt.push_back('=');
1072
 
          new_unknown_opt.append(*it);
1073
 
        }
1074
 
      }
1075
 
      else
1076
 
      {
1077
 
        break;
1078
 
      }
1079
 
      unknown_options.push_back(new_unknown_opt);
1080
 
    }
1081
 
    store(file_parsed, vm);
1082
 
  }
1083
 
}
1084
 
 
1085
 
static void compose_defaults_file_list(vector<string> in_options)
1086
 
{
1087
 
  for (vector<string>::iterator it= in_options.begin();
1088
 
       it != in_options.end();
1089
 
       ++it)
1090
 
  {
1091
 
    fs::path p(*it);
1092
 
    if (fs::is_regular_file(p))
1093
 
      defaults_file_list.push_back(*it);
1094
 
    else
1095
 
    {
1096
 
      errmsg_printf(ERRMSG_LVL_ERROR,
1097
 
                  _("Defaults file '%s' not found\n"), (*it).c_str());
1098
 
      unireg_abort(1);
1099
 
    }
1100
 
 
1101
 
  }
1102
 
}
1103
 
 
1104
 
int init_common_variables(int argc, char **argv, module::Registry &plugins)
 
1358
static int init_common_variables(const char *conf_file_name, int argc,
 
1359
                                 char **argv, const char **groups)
1105
1360
{
1106
1361
  time_t curr_time;
1107
 
  umask(((~internal::my_umask) & 0666));
 
1362
  umask(((~my_umask) & 0666));
1108
1363
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1109
1364
  tzset();                      // Set tzname
1110
1365
 
1115
1370
  max_system_variables.pseudo_thread_id= UINT32_MAX;
1116
1371
  server_start_time= flush_status_time= curr_time;
1117
1372
 
 
1373
  if (init_thread_environment())
 
1374
    return 1;
1118
1375
  drizzle_init_variables();
1119
1376
 
1120
 
  find_plugin_dir(argv[0]);
1121
1377
  {
1122
1378
    struct tm tm_tmp;
1123
1379
    localtime_r(&server_start_time,&tm_tmp);
1124
1380
    strncpy(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
1125
1381
            sizeof(system_time_zone)-1);
1126
1382
 
1127
 
  }
 
1383
 }
1128
1384
  /*
1129
1385
    We set SYSTEM time zone as reasonable default and
1130
1386
    also for failure of my_tz_init() and bootstrap mode.
1136
1392
  if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
1137
1393
  {
1138
1394
    strncpy(glob_hostname, STRING_WITH_LEN("localhost"));
1139
 
    errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
1140
 
                  glob_hostname);
1141
 
    pid_file= "drizzle";
 
1395
      errmsg_printf(ERRMSG_LVL_WARN, _("gethostname failed, using '%s' as hostname"),
 
1396
                      glob_hostname);
 
1397
    strncpy(pidfile_name, STRING_WITH_LEN("drizzle"));
1142
1398
  }
1143
1399
  else
1144
 
  {
1145
 
    pid_file= glob_hostname;
1146
 
  }
1147
 
  pid_file.replace_extension(".pid");
1148
 
 
1149
 
  system_config_dir /= "drizzle";
1150
 
 
1151
 
  config_options.add_options()
1152
 
  ("help,?", po::value<bool>(&opt_help)->default_value(false)->zero_tokens(),
1153
 
  N_("Display this help and exit."))
1154
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1155
 
  N_("Configuration file defaults are not used if no-defaults is set"))
1156
 
  ("defaults-file", po::value<vector<string> >()->composing()->notifier(&compose_defaults_file_list),
1157
 
   N_("Configuration file to use"))
1158
 
  ("config-dir", po::value<fs::path>(&system_config_dir),
1159
 
   N_("Base location for config files"))
1160
 
  ("plugin-dir", po::value<fs::path>(&plugin_dir)->notifier(&notify_plugin_dir),
1161
 
  N_("Directory for plugins."))
1162
 
  ;
1163
 
 
1164
 
  plugin_load_options.add_options()
1165
 
  ("plugin-add", po::value<vector<string> >()->composing()->notifier(&compose_plugin_add),
1166
 
  N_("Optional comma separated list of plugins to load at startup in addition "
1167
 
     "to the default list of plugins. "
1168
 
     "[for example: --plugin_add=crc32,logger_gearman]"))    
1169
 
  ("plugin-remove", po::value<vector<string> >()->composing()->notifier(&compose_plugin_remove),
1170
 
  N_("Optional comma separated list of plugins to not load at startup. Effectively "
1171
 
     "removes a plugin from the list of plugins to be loaded. "
1172
 
     "[for example: --plugin_remove=crc32,logger_gearman]"))
1173
 
  ("plugin-load", po::value<string>()->notifier(&notify_plugin_load)->default_value(PANDORA_PLUGIN_LIST),
1174
 
  N_("Optional comma separated list of plugins to load at starup instead of "
1175
 
     "the default plugin load list. "
1176
 
     "[for example: --plugin_load=crc32,logger_gearman]"))
1177
 
  ;
1178
 
 
1179
 
  long_options.add_options()
1180
 
  ("auto-increment-increment", po::value<uint64_t>(&global_system_variables.auto_increment_increment)->default_value(1)->notifier(&check_limits_aii),
1181
 
  N_("Auto-increment columns are incremented by this"))
1182
 
  ("auto-increment-offset", po::value<uint64_t>(&global_system_variables.auto_increment_offset)->default_value(1)->notifier(&check_limits_aio),
1183
 
  N_("Offset added to Auto-increment columns. Used when auto-increment-increment != 1"))
1184
 
  ("basedir,b", po::value<fs::path>(&basedir),
1185
 
  N_("Path to installation directory. All paths are usually resolved "
1186
 
     "relative to this."))
1187
 
  ("chroot,r", po::value<string>(),
1188
 
  N_("Chroot drizzled daemon during startup."))
1189
 
  ("collation-server", po::value<string>(),
1190
 
  N_("Set the default collation."))      
1191
 
  ("completion-type", po::value<uint32_t>(&global_system_variables.completion_type)->default_value(0)->notifier(&check_limits_completion_type),
1192
 
  N_("Default completion type."))
1193
 
  ("core-file",  N_("Write core on errors."))
1194
 
  ("datadir", po::value<fs::path>(&data_home),
1195
 
  N_("Path to the database root."))
1196
 
  ("default-storage-engine", po::value<string>(),
1197
 
  N_("Set the default storage engine for tables."))
1198
 
  ("default-time-zone", po::value<string>(),
1199
 
  N_("Set the default time zone."))
1200
 
  ("exit-info,T", po::value<long>(),
1201
 
  N_("Used for debugging;  Use at your own risk!"))
1202
 
  ("gdb", po::value<bool>(&opt_debugging)->default_value(false)->zero_tokens(),
1203
 
  N_("Set up signals usable for debugging"))
1204
 
  ("lc-time-name", po::value<string>(),
1205
 
  N_("Set the language used for the month names and the days of the week."))
1206
 
  ("log-warnings,W", po::value<bool>(&global_system_variables.log_warnings)->default_value(false)->zero_tokens(),
1207
 
  N_("Log some not critical warnings to the log file."))  
1208
 
  ("pid-file", po::value<fs::path>(&pid_file),
1209
 
  N_("Pid file used by drizzled."))
1210
 
  ("port-open-timeout", po::value<uint32_t>(&drizzled_bind_timeout)->default_value(0),
1211
 
  N_("Maximum time in seconds to wait for the port to become free. "))
1212
 
  ("replicate-query", po::value<bool>(&global_system_variables.replicate_query)->default_value(false)->zero_tokens(),
1213
 
  N_("Include the SQL query in replicated protobuf messages."))
1214
 
  ("secure-file-priv", po::value<fs::path>(&secure_file_priv)->notifier(expand_secure_file_priv),
1215
 
  N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1216
 
     "within specified directory"))
1217
 
  ("server-id", po::value<uint32_t>(&server_id)->default_value(0),
1218
 
  N_("Uniquely identifies the server instance in the community of "
1219
 
     "replication partners."))
1220
 
  ("skip-stack-trace",  
1221
 
  N_("Don't print a stack trace on failure."))
1222
 
  ("symbolic-links,s", po::value<bool>(&internal::my_use_symdir)->default_value(IF_PURIFY(false,true))->zero_tokens(),
1223
 
  N_("Enable symbolic link support."))
1224
 
  ("timed-mutexes", po::value<bool>(&internal::timed_mutexes)->default_value(false)->zero_tokens(),
1225
 
  N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1226
 
     "supported)")) 
1227
 
  ("tmpdir,t", po::value<string>(),
1228
 
  N_("Path for temporary files."))
1229
 
  ("transaction-isolation", po::value<string>(),
1230
 
  N_("Default transaction isolation level."))
1231
 
  ("transaction-message-threshold", po::value<size_t>(&global_system_variables.transaction_message_threshold)->default_value(1024*1024)->notifier(&check_limits_transaction_message_threshold),
1232
 
  N_("Max message size written to transaction log, valid values 131072 - 1048576 bytes."))
1233
 
  ("user,u", po::value<string>(),
1234
 
  N_("Run drizzled daemon as user."))  
1235
 
  ("version,V", 
1236
 
  N_("Output version information and exit."))
1237
 
  ("back-log", po::value<back_log_constraints>(&back_log),
1238
 
  N_("The number of outstanding connection requests Drizzle can have. This "
1239
 
     "comes into play when the main Drizzle thread gets very many connection "
1240
 
     "requests in a very short time."))
1241
 
  ("bulk-insert-buffer-size", 
1242
 
  po::value<uint64_t>(&global_system_variables.bulk_insert_buff_size)->default_value(8192*1024),
1243
 
  N_("Size of tree cache used in bulk insert optimization. Note that this is "
1244
 
     "a limit per thread!"))
1245
 
  ("div-precision-increment",  po::value<uint32_t>(&global_system_variables.div_precincrement)->default_value(4)->notifier(&check_limits_dpi),
1246
 
  N_("Precision of the result of '/' operator will be increased on that "
1247
 
     "value."))
1248
 
  ("group-concat-max-len", po::value<uint64_t>(&global_system_variables.group_concat_max_len)->default_value(1024)->notifier(&check_limits_gcml),
1249
 
  N_("The maximum length of the result of function  group_concat."))
1250
 
  ("join-buffer-size", po::value<uint64_t>(&global_system_variables.join_buff_size)->default_value(128*1024L)->notifier(&check_limits_join_buffer_size),
1251
 
  N_("The size of the buffer that is used for full joins."))
1252
 
  ("join-heap-threshold",
1253
 
  po::value<uint64_t>()->default_value(0),
1254
 
  N_("A global cap on the amount of memory that can be allocated by session join buffers (0 means unlimited)"))
1255
 
  ("max-allowed-packet", po::value<uint32_t>(&global_system_variables.max_allowed_packet)->default_value(64*1024*1024L)->notifier(&check_limits_map),
1256
 
  N_("Max packetlength to send/receive from to server."))
1257
 
  ("max-connect-errors", po::value<uint64_t>(&max_connect_errors)->default_value(MAX_CONNECT_ERRORS)->notifier(&check_limits_mce),
1258
 
  N_("If there is more than this number of interrupted connections from a "
1259
 
     "host this host will be blocked from further connections."))
1260
 
  ("max-error-count", po::value<uint64_t>(&global_system_variables.max_error_count)->default_value(DEFAULT_ERROR_COUNT)->notifier(&check_limits_max_err_cnt),
1261
 
  N_("Max number of errors/warnings to store for a statement."))
1262
 
  ("max-heap-table-size", po::value<uint64_t>(&global_system_variables.max_heap_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_mhts),
1263
 
  N_("Don't allow creation of heap tables bigger than this."))
1264
 
  ("max-join-size", po::value<drizzled::ha_rows>(&global_system_variables.max_join_size)->default_value(INT32_MAX)->notifier(&check_limits_max_join_size),
1265
 
  N_("Joins that are probably going to read more than max_join_size records "
1266
 
     "return an error."))
1267
 
  ("max-length-for-sort-data", po::value<uint64_t>(&global_system_variables.max_length_for_sort_data)->default_value(1024)->notifier(&check_limits_mlfsd),
1268
 
  N_("Max number of bytes in sorted records."))
1269
 
  ("max-seeks-for-key", po::value<uint64_t>(&global_system_variables.max_seeks_for_key)->default_value(ULONG_MAX)->notifier(&check_limits_msfk),
1270
 
  N_("Limit assumed max number of seeks when looking up rows based on a key"))
1271
 
  ("max-sort-length", po::value<size_t>(&global_system_variables.max_sort_length)->default_value(1024)->notifier(&check_limits_max_sort_length),  
1272
 
  N_("The number of bytes to use when sorting BLOB or TEXT values "
1273
 
     "(only the first max_sort_length bytes of each value are used; the "
1274
 
     "rest are ignored)."))
1275
 
  ("max-write-lock-count", po::value<uint64_t>(&max_write_lock_count)->default_value(UINT64_MAX),
1276
 
  N_("After this many write locks, allow some read locks to run in between."))
1277
 
  ("min-examined-row-limit", po::value<uint64_t>(&global_system_variables.min_examined_row_limit)->default_value(0)->notifier(&check_limits_merl),
1278
 
  N_("Don't log queries which examine less than min_examined_row_limit "
1279
 
     "rows to file."))
1280
 
  ("disable-optimizer-prune",
1281
 
  N_("Do not apply any heuristic(s) during query optimization to prune, "
1282
 
     "thus perform an exhaustive search from the optimizer search space."))
1283
 
  ("optimizer-search-depth", po::value<uint32_t>(&global_system_variables.optimizer_search_depth)->default_value(0)->notifier(&check_limits_osd),
1284
 
  N_("Maximum depth of search performed by the query optimizer. Values "
1285
 
     "larger than the number of relations in a query result in better query "
1286
 
     "plans, but take longer to compile a query. Smaller values than the "
1287
 
     "number of tables in a relation result in faster optimization, but may "
1288
 
     "produce very bad query plans. If set to 0, the system will "
1289
 
     "automatically pick a reasonable value; if set to MAX_TABLES+2, the "
1290
 
     "optimizer will switch to the original find_best (used for "
1291
 
     "testing/comparison)."))
1292
 
  ("preload-buffer-size", po::value<uint64_t>(&global_system_variables.preload_buff_size)->default_value(32*1024L)->notifier(&check_limits_pbs),
1293
 
  N_("The size of the buffer that is allocated when preloading indexes"))
1294
 
  ("query-alloc-block-size", 
1295
 
  po::value<uint32_t>(&global_system_variables.query_alloc_block_size)->default_value(QUERY_ALLOC_BLOCK_SIZE)->notifier(&check_limits_qabs),
1296
 
  N_("Allocation block size for query parsing and execution"))
1297
 
  ("query-prealloc-size",
1298
 
  po::value<uint32_t>(&global_system_variables.query_prealloc_size)->default_value(QUERY_ALLOC_PREALLOC_SIZE)->notifier(&check_limits_qps),
1299
 
  N_("Persistent buffer for query parsing and execution"))
1300
 
  ("range-alloc-block-size",
1301
 
  po::value<size_t>(&global_system_variables.range_alloc_block_size)->default_value(RANGE_ALLOC_BLOCK_SIZE)->notifier(&check_limits_rabs),
1302
 
  N_("Allocation block size for storing ranges during optimization"))
1303
 
  ("read-buffer-size",
1304
 
  po::value<uint32_t>(&global_system_variables.read_buff_size)->default_value(128*1024L)->notifier(&check_limits_read_buffer_size),
1305
 
  N_("Each thread that does a sequential scan allocates a buffer of this "
1306
 
      "size for each table it scans. If you do many sequential scans, you may "
1307
 
      "want to increase this value."))
1308
 
  ("read-buffer-threshold",
1309
 
  po::value<uint64_t>()->default_value(0),
1310
 
  N_("A global cap on the size of read-buffer-size (0 means unlimited)"))
1311
 
  ("read-rnd-buffer-size",
1312
 
  po::value<uint32_t>(&global_system_variables.read_rnd_buff_size)->default_value(256*1024L)->notifier(&check_limits_read_rnd_buffer_size),
1313
 
  N_("When reading rows in sorted order after a sort, the rows are read "
1314
 
     "through this buffer to avoid a disk seeks. If not set, then it's set "
1315
 
     "to the value of record_buffer."))
1316
 
  ("read-rnd-threshold",
1317
 
  po::value<uint64_t>()->default_value(0),
1318
 
  N_("A global cap on the size of read-rnd-buffer-size (0 means unlimited)"))
1319
 
  ("scheduler", po::value<string>(),
1320
 
  N_("Select scheduler to be used (by default multi-thread)."))
1321
 
  ("sort-buffer-size",
1322
 
  po::value<size_t>(&global_system_variables.sortbuff_size)->default_value(MAX_SORT_MEMORY)->notifier(&check_limits_sort_buffer_size),
1323
 
  N_("Each thread that needs to do a sort allocates a buffer of this size."))
1324
 
  ("sort-heap-threshold",
1325
 
  po::value<uint64_t>()->default_value(0),
1326
 
  N_("A global cap on the amount of memory that can be allocated by session sort buffers (0 means unlimited)"))
1327
 
  ("table-definition-cache", po::value<size_t>(&table_def_size)->default_value(128)->notifier(&check_limits_tdc),
1328
 
  N_("The number of cached table definitions."))
1329
 
  ("table-open-cache", po::value<uint64_t>(&table_cache_size)->default_value(TABLE_OPEN_CACHE_DEFAULT)->notifier(&check_limits_toc),
1330
 
  N_("The number of cached open tables."))
1331
 
  ("table-lock-wait-timeout", po::value<uint64_t>(&table_lock_wait_timeout)->default_value(50)->notifier(&check_limits_tlwt),
1332
 
  N_("Timeout in seconds to wait for a table level lock before returning an "
1333
 
     "error. Used only if the connection has active cursors."))
1334
 
  ("thread-stack", po::value<size_t>(&my_thread_stack_size)->default_value(DEFAULT_THREAD_STACK)->notifier(&check_limits_thread_stack),
1335
 
  N_("The stack size for each thread."))
1336
 
  ("tmp-table-size", 
1337
 
  po::value<uint64_t>(&global_system_variables.tmp_table_size)->default_value(16*1024*1024L)->notifier(&check_limits_tmp_table_size),
1338
 
  N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
1339
 
     " automatically convert it to an on-disk MyISAM table."))
1340
 
  ;
1341
 
 
1342
 
  full_options.add(long_options);
1343
 
  full_options.add(plugin_load_options);
1344
 
 
1345
 
  initial_options.add(config_options);
1346
 
  initial_options.add(plugin_load_options);
1347
 
 
1348
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1349
 
  /* Get options about where config files and the like are */
1350
 
  po::parsed_options parsed= po::command_line_parser(argc, argv).style(style).
1351
 
    options(initial_options).allow_unregistered().run();
1352
 
  unknown_options=
1353
 
    po::collect_unrecognized(parsed.options, po::include_positional);
1354
 
 
1355
 
  try
1356
 
  {
1357
 
    po::store(parsed, vm);
1358
 
  }
1359
 
  catch (std::exception&)
1360
 
  {
1361
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Duplicate entry for command line option\n"));
1362
 
    unireg_abort(1);
1363
 
  }
1364
 
 
1365
 
  if (not vm["no-defaults"].as<bool>())
1366
 
  {
1367
 
    fs::path system_config_file_drizzle(system_config_dir);
1368
 
    system_config_file_drizzle /= "drizzled.cnf";
1369
 
    defaults_file_list.insert(defaults_file_list.begin(),
1370
 
                              system_config_file_drizzle.file_string());
1371
 
 
1372
 
    fs::path config_conf_d_location(system_config_dir);
1373
 
    config_conf_d_location /= "conf.d";
1374
 
 
1375
 
 
1376
 
    CachedDirectory config_conf_d(config_conf_d_location.file_string());
1377
 
    if (not config_conf_d.fail())
1378
 
    {
1379
 
 
1380
 
      for (CachedDirectory::Entries::const_iterator iter= config_conf_d.getEntries().begin();
1381
 
           iter != config_conf_d.getEntries().end();
1382
 
           ++iter)
1383
 
      {
1384
 
        string file_entry((*iter)->filename);
1385
 
 
1386
 
        if (not file_entry.empty()
1387
 
            && file_entry != "."
1388
 
            && file_entry != "..")
1389
 
        {
1390
 
          fs::path the_entry(config_conf_d_location);
1391
 
          the_entry /= file_entry;
1392
 
          defaults_file_list.push_back(the_entry.file_string());
1393
 
        }
1394
 
      }
1395
 
    }
1396
 
  }
1397
 
 
1398
 
  /* TODO: here is where we should add a process_env_vars */
1399
 
 
1400
 
  /* We need a notify here so that plugin_init will work properly */
1401
 
  try
1402
 
  {
1403
 
    po::notify(vm);
1404
 
  }
1405
 
  catch (po::validation_error &err)
1406
 
  {
1407
 
    errmsg_printf(ERRMSG_LVL_ERROR,  
1408
 
                  _("%s: %s.\n"
1409
 
                    "Use --help to get a list of available options\n"),
1410
 
                  internal::my_progname, err.what());
1411
 
    unireg_abort(1);
1412
 
  }
1413
 
 
1414
 
  process_defaults_files();
1415
 
 
1416
 
  /* Process with notify a second time because a config file may contain
1417
 
     plugin loader options */
1418
 
 
1419
 
  try
1420
 
  {
1421
 
    po::notify(vm);
1422
 
  }
1423
 
  catch (po::validation_error &err)
1424
 
  {
1425
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1426
 
                  _("%s: %s.\n"
1427
 
                    "Use --help to get a list of available options\n"),
1428
 
                  internal::my_progname, err.what());
1429
 
    unireg_abort(1);
1430
 
  }
1431
 
 
1432
 
  /* At this point, we've read all the options we need to read from files and
1433
 
     collected most of them into unknown options - now let's load everything
 
1400
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
 
1401
  strcpy(fn_ext(pidfile_name),".pid");          // Add proper extension
 
1402
 
 
1403
  /*
 
1404
    Add server status variables to the dynamic list of
 
1405
    status variables that is shown by SHOW STATUS.
 
1406
    Later, in plugin_init, and mysql_install_plugin
 
1407
    new entries could be added to that list.
1434
1408
  */
1435
 
 
1436
 
  if (plugin_init(plugins, plugin_options))
1437
 
  {
1438
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins\n"));
1439
 
    unireg_abort(1);
1440
 
  }
1441
 
 
1442
 
  full_options.add(plugin_options);
1443
 
 
1444
 
  vector<string> final_unknown_options;
1445
 
  try
1446
 
  {
1447
 
    po::parsed_options final_parsed=
1448
 
      po::command_line_parser(unknown_options).style(style).
1449
 
      options(full_options).extra_parser(dpo::parse_size_arg).run();
1450
 
 
1451
 
    final_unknown_options=
1452
 
      po::collect_unrecognized(final_parsed.options, po::include_positional);
1453
 
 
1454
 
    po::store(final_parsed, vm);
1455
 
 
1456
 
  }
1457
 
  catch (po::validation_error &err)
1458
 
  {
1459
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1460
 
                  _("%s: %s.\n"
1461
 
                    "Use --help to get a list of available options\n"),
1462
 
                  internal::my_progname, err.what());
1463
 
    unireg_abort(1);
1464
 
  }
1465
 
  catch (po::invalid_command_line_syntax &err)
1466
 
  {
1467
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1468
 
                  _("%s: %s.\n"
1469
 
                    "Use --help to get a list of available options\n"),
1470
 
                  internal::my_progname, err.what());
1471
 
    unireg_abort(1);
1472
 
  }
1473
 
  catch (po::unknown_option &err)
1474
 
  {
1475
 
    errmsg_printf(ERRMSG_LVL_ERROR,
1476
 
                  _("%s\nUse --help to get a list of available options\n"),
1477
 
                  err.what());
1478
 
    unireg_abort(1);
1479
 
  }
1480
 
 
1481
 
  try
1482
 
  {
1483
 
    po::notify(vm);
1484
 
  }
1485
 
  catch (po::validation_error &err)
1486
 
  {
1487
 
    errmsg_printf(ERRMSG_LVL_ERROR,  
1488
 
                  _("%s: %s.\n"
1489
 
                    "Use --help to get a list of available options\n"),
1490
 
                  internal::my_progname, err.what());
1491
 
    unireg_abort(1);
1492
 
  }
1493
 
 
1494
 
  get_options();
1495
 
 
1496
 
  /* Inverted Booleans */
1497
 
 
1498
 
  global_system_variables.optimizer_prune_level=
1499
 
    vm.count("disable-optimizer-prune") ? false : true;
1500
 
 
1501
 
  if (vm.count("help") == 0 && vm.count("help-extended") == 0)
1502
 
  {
1503
 
    if ((user_info= check_user(drizzled_user)))
1504
 
    {
1505
 
      set_user(drizzled_user, user_info);
1506
 
    }
1507
 
  }
1508
 
 
1509
 
  fix_paths();
1510
 
 
1511
 
  current_pid= getpid();                /* Save for later ref */
 
1409
  if (add_status_vars(status_vars))
 
1410
    return 1; // an error was already reported
 
1411
 
 
1412
  load_defaults(conf_file_name, groups, &argc, &argv);
 
1413
  defaults_argv=argv;
 
1414
  defaults_argc=argc;
 
1415
  get_options(&defaults_argc, defaults_argv);
 
1416
  set_server_version();
 
1417
 
 
1418
 
 
1419
  /* connections and databases needs lots of files */
 
1420
  (void) my_set_max_open_files(0xFFFFFFFF);
 
1421
 
 
1422
  current_pid=(ulong) getpid();         /* Save for later ref */
1512
1423
  init_time();                          /* Init time-functions (read zone) */
1513
1424
 
 
1425
  if (init_errmessage())        /* Read error messages from file */
 
1426
    return 1;
1514
1427
  if (item_create_init())
1515
1428
    return 1;
1516
 
  if (sys_var_init())
 
1429
  if (set_var_init())
1517
1430
    return 1;
1518
1431
  /* Creates static regex matching for temporal values */
1519
1432
  if (! init_temporal_formats())
1520
1433
    return 1;
1521
 
 
1522
 
  if (!(default_charset_info=
1523
 
        get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
 
1434
  /*
 
1435
    Process a comma-separated character set list and choose
 
1436
    the first available character set. This is mostly for
 
1437
    test purposes, to be able to start "mysqld" even if
 
1438
    the requested character set is not available (see bug#18743).
 
1439
  */
 
1440
  for (;;)
1524
1441
  {
1525
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error getting default charset"));
1526
 
    return 1;                           // Eof of the list
 
1442
    char *next_character_set_name= strchr(default_character_set_name, ',');
 
1443
    if (next_character_set_name)
 
1444
      *next_character_set_name++= '\0';
 
1445
    if (!(default_charset_info=
 
1446
          get_charset_by_csname(default_character_set_name, MY_CS_PRIMARY)))
 
1447
    {
 
1448
      if (next_character_set_name)
 
1449
      {
 
1450
        default_character_set_name= next_character_set_name;
 
1451
        default_collation_name= 0;          // Ignore collation
 
1452
      }
 
1453
      else
 
1454
        return 1;                           // Eof of the list
 
1455
    }
 
1456
    else
 
1457
      break;
1527
1458
  }
1528
1459
 
1529
 
  if (vm.count("scheduler"))
1530
 
    opt_scheduler= vm["scheduler"].as<string>().c_str();
1531
 
 
1532
1460
  if (default_collation_name)
1533
1461
  {
1534
1462
    const CHARSET_INFO * const default_collation= get_charset_by_name(default_collation_name);
1535
 
    if (not default_collation)
 
1463
    if (!default_collation)
1536
1464
    {
1537
 
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
 
1465
          errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_UNKNOWN_COLLATION)), default_collation_name);
1538
1466
      return 1;
1539
1467
    }
1540
 
    if (not my_charset_same(default_charset_info, default_collation))
 
1468
    if (!my_charset_same(default_charset_info, default_collation))
1541
1469
    {
1542
 
      errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
1543
 
                    default_collation_name,
1544
 
                    default_charset_info->csname);
 
1470
          errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_COLLATION_CHARSET_MISMATCH)),
 
1471
                      default_collation_name,
 
1472
                      default_charset_info->csname);
1545
1473
      return 1;
1546
1474
    }
1547
1475
    default_charset_info= default_collation;
1548
1476
  }
1549
1477
  /* Set collactions that depends on the default collation */
1550
1478
  global_system_variables.collation_server=      default_charset_info;
1551
 
 
1552
 
  if (not (character_set_filesystem=
1553
 
           get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1554
 
  {
1555
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error setting collation"));
 
1479
  global_system_variables.collation_database=    default_charset_info;
 
1480
 
 
1481
  global_system_variables.optimizer_use_mrr= 1;
 
1482
  global_system_variables.optimizer_switch= 0;
 
1483
 
 
1484
  if (!(character_set_filesystem=
 
1485
        get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY)))
1556
1486
    return 1;
1557
 
  }
1558
1487
  global_system_variables.character_set_filesystem= character_set_filesystem;
1559
1488
 
1560
1489
  if (!(my_default_lc_time_names=
1561
1490
        my_locale_by_name(lc_time_names_name)))
1562
1491
  {
1563
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
 
1492
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown locale: '%s'"), lc_time_names_name);
1564
1493
    return 1;
1565
1494
  }
1566
1495
  global_system_variables.lc_time_names= my_default_lc_time_names;
1567
1496
 
1568
 
  /* Reset table_alias_charset */
 
1497
  sys_init_connect.value_length= 0;
 
1498
  if ((sys_init_connect.value= opt_init_connect))
 
1499
    sys_init_connect.value_length= strlen(opt_init_connect);
 
1500
  else
 
1501
    sys_init_connect.value=strdup("");
 
1502
  if (sys_init_connect.value == NULL)
 
1503
    return 1;
 
1504
 
 
1505
  if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
 
1506
    return 1;
 
1507
 
 
1508
  /* Reset table_alias_charset, now that lower_case_table_names is set. */
 
1509
  lower_case_table_names= 1; /* This we need to look at */
1569
1510
  table_alias_charset= files_charset_info;
1570
1511
 
1571
1512
  return 0;
1572
1513
}
1573
1514
 
1574
1515
 
1575
 
int init_server_components(module::Registry &plugins)
 
1516
static int init_thread_environment()
 
1517
{
 
1518
  (void) pthread_mutex_init(&LOCK_drizzleclient_create_db,MY_MUTEX_INIT_SLOW);
 
1519
  (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
 
1520
  (void) pthread_mutex_init(&LOCK_open, NULL);
 
1521
  (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
 
1522
  (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
 
1523
  (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
 
1524
  (void) pthread_rwlock_init(&LOCK_system_variables_hash, NULL);
 
1525
  (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
 
1526
  (void) pthread_rwlock_init(&LOCK_sys_init_connect, NULL);
 
1527
  (void) pthread_cond_init(&COND_thread_count,NULL);
 
1528
  (void) pthread_cond_init(&COND_refresh,NULL);
 
1529
  (void) pthread_cond_init(&COND_global_read_lock,NULL);
 
1530
 
 
1531
  if (pthread_key_create(&THR_Session,NULL) ||
 
1532
      pthread_key_create(&THR_Mem_root,NULL))
 
1533
  {
 
1534
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread-keys"));
 
1535
    return 1;
 
1536
  }
 
1537
  return 0;
 
1538
}
 
1539
 
 
1540
 
 
1541
static int init_server_components()
1576
1542
{
1577
1543
  /*
1578
1544
    We need to call each of these following functions to ensure that
1579
1545
    all things are initialized so that unireg_abort() doesn't fail
1580
1546
  */
1581
 
  if (table_cache_init())
1582
 
  {
1583
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not initialize table cache\n"));
 
1547
  if (table_cache_init() | table_def_init())
1584
1548
    unireg_abort(1);
1585
 
  }
1586
 
 
1587
 
  // Resize the definition Cache at startup
1588
 
  table::Cache::singleton().rehash(table_def_size);
1589
 
  definition::Cache::singleton().rehash(table_def_size);
1590
 
  message::Cache::singleton().rehash(table_def_size);
1591
 
 
 
1549
 
 
1550
  drizzleclient_randominit(&sql_rand,
 
1551
                           (uint64_t) server_start_time,
 
1552
                           (uint64_t) server_start_time/2);
1592
1553
  setup_fpu();
 
1554
  init_thr_lock();
1593
1555
 
1594
1556
  /* Setup logs */
1595
1557
 
1596
1558
  if (xid_cache_init())
1597
1559
  {
1598
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("XA cache initialization failed: Out of memory\n"));
 
1560
      errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory"));
1599
1561
    unireg_abort(1);
1600
1562
  }
1601
1563
 
 
1564
  /* call ha_init_key_cache() on all key caches to init them */
 
1565
  process_key_caches(&ha_init_key_cache);
 
1566
 
1602
1567
  /* Allow storage engine to give real error messages */
1603
 
  ha_init_errors();
 
1568
  if (ha_init_errors())
 
1569
    return(1);
1604
1570
 
 
1571
  if (plugin_init(&defaults_argc, defaults_argv,
 
1572
                  (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
 
1573
                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
 
1574
  {
 
1575
      errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to initialize plugins."));
 
1576
    unireg_abort(1);
 
1577
  }
1605
1578
 
1606
1579
  if (opt_help)
1607
1580
    unireg_abort(0);
1608
1581
 
1609
 
  if (plugin_finalize(plugins))
1610
 
  {
 
1582
  /* we do want to exit if there are any other unknown options */
 
1583
  if (defaults_argc > 1)
 
1584
  {
 
1585
    int ho_error;
 
1586
    char **tmp_argv= defaults_argv;
 
1587
    struct my_option no_opts[]=
 
1588
    {
 
1589
      {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1590
    };
 
1591
    /*
 
1592
      We need to eat any 'loose' arguments first before we conclude
 
1593
      that there are unprocessed options.
 
1594
      But we need to preserve defaults_argv pointer intact for
 
1595
      free_defaults() to work. Thus we use a copy here.
 
1596
    */
 
1597
    my_getopt_skip_unknown= 0;
 
1598
 
 
1599
    if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
 
1600
                                  drizzled_get_one_option)))
 
1601
      unireg_abort(ho_error);
 
1602
 
 
1603
    if (defaults_argc)
 
1604
    {
 
1605
      fprintf(stderr,
 
1606
              _("%s: Too many arguments (first extra is '%s').\n"
 
1607
                "Use --verbose --help to get a list of available options\n"),
 
1608
              my_progname, *tmp_argv);
 
1609
      unireg_abort(1);
 
1610
    }
 
1611
  }
 
1612
 
 
1613
  /* We have to initialize the storage engines before CSV logging */
 
1614
  if (ha_init())
 
1615
  {
 
1616
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't init databases"));
1611
1617
    unireg_abort(1);
1612
1618
  }
1613
1619
 
1614
 
  string scheduler_name;
1615
 
  if (opt_scheduler)
1616
 
  {
1617
 
    scheduler_name= opt_scheduler;
1618
 
  }
1619
 
  else
1620
 
  {
1621
 
    scheduler_name= opt_scheduler_default;
1622
 
    opt_scheduler= opt_scheduler_default; 
1623
 
  }
1624
 
 
1625
 
  if (plugin::Scheduler::setPlugin(scheduler_name))
1626
 
  {
1627
 
      errmsg_printf(ERRMSG_LVL_ERROR,
1628
 
                   _("No scheduler found, cannot continue!\n"));
1629
 
      unireg_abort(1);
1630
 
  }
1631
 
 
1632
 
  /*
1633
 
    This is entirely for legacy. We will create a new "disk based" engine and a
1634
 
    "memory" engine which will be configurable longterm.
1635
 
  */
1636
 
  const std::string myisam_engine_name("MyISAM");
1637
 
  const std::string heap_engine_name("MEMORY");
1638
 
  myisam_engine= plugin::StorageEngine::findByName(myisam_engine_name);
1639
 
  heap_engine= plugin::StorageEngine::findByName(heap_engine_name);
1640
 
 
1641
1620
  /*
1642
1621
    Check that the default storage engine is actually available.
1643
1622
  */
1644
1623
  if (default_storage_engine_str)
1645
1624
  {
1646
 
    const std::string name(default_storage_engine_str);
1647
 
    plugin::StorageEngine *engine;
 
1625
    LEX_STRING name= { default_storage_engine_str,
 
1626
                       strlen(default_storage_engine_str) };
 
1627
    plugin_ref plugin;
 
1628
    handlerton *hton;
1648
1629
 
1649
 
    engine= plugin::StorageEngine::findByName(name);
1650
 
    if (engine == NULL)
1651
 
    {
1652
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported storage engine: %s\n"),
 
1630
    if ((plugin= ha_resolve_by_name(0, &name)))
 
1631
    {
 
1632
      hton= plugin_data(plugin,handlerton *);
 
1633
    }
 
1634
    else
 
1635
    {
 
1636
          errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown/unsupported table type: %s"),
 
1637
                      default_storage_engine_str);
 
1638
      unireg_abort(1);
 
1639
    }
 
1640
    if (!ha_storage_engine_is_enabled(hton))
 
1641
    {
 
1642
      errmsg_printf(ERRMSG_LVL_ERROR, _("Default storage engine (%s) is not available"),
1653
1643
                    default_storage_engine_str);
1654
1644
      unireg_abort(1);
1655
 
    }
1656
 
    global_system_variables.storage_engine= engine;
 
1645
      //assert(global_system_variables.table_plugin);
 
1646
    }
 
1647
    else
 
1648
    {
 
1649
      /*
 
1650
        Need to unlock as global_system_variables.table_plugin
 
1651
        was acquired during plugin_init()
 
1652
      */
 
1653
      plugin_unlock(0, global_system_variables.table_plugin);
 
1654
      global_system_variables.table_plugin= plugin;
 
1655
    }
1657
1656
  }
1658
1657
 
1659
 
  if (plugin::XaResourceManager::recoverAllXids())
 
1658
  if (ha_recover(0))
1660
1659
  {
1661
 
    /* This function alredy generates error messages */
1662
1660
    unireg_abort(1);
1663
1661
  }
1664
1662
 
 
1663
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
 
1664
  if (locked_in_memory && !getuid())
 
1665
  {
 
1666
    if (setreuid((uid_t)-1, 0) == -1)
 
1667
    {                        // this should never happen
 
1668
      sql_perror("setreuid");
 
1669
      unireg_abort(1);
 
1670
    }
 
1671
    if (mlockall(MCL_CURRENT))
 
1672
    {
 
1673
      if (global_system_variables.log_warnings)
 
1674
            errmsg_printf(ERRMSG_LVL_WARN, _("Failed to lock memory. Errno: %d\n"),errno);
 
1675
      locked_in_memory= 0;
 
1676
    }
 
1677
    if (user_info)
 
1678
      set_user(drizzled_user, user_info);
 
1679
  }
 
1680
  else
 
1681
#endif
 
1682
    locked_in_memory=0;
 
1683
 
1665
1684
  init_update_queries();
1666
 
 
1667
1685
  return(0);
1668
1686
}
1669
1687
 
1670
1688
 
 
1689
int main(int argc, char **argv)
 
1690
{
 
1691
#if defined(ENABLE_NLS)
 
1692
# if defined(HAVE_LOCALE_H)
 
1693
  setlocale(LC_ALL, "");
 
1694
# endif
 
1695
  bindtextdomain("drizzle", LOCALEDIR);
 
1696
  textdomain("drizzle");
 
1697
#endif
 
1698
 
 
1699
  MY_INIT(argv[0]);             // init my_sys library & pthreads
 
1700
  /* nothing should come before this line ^^^ */
 
1701
 
 
1702
  /* Set signal used to kill Drizzle */
 
1703
#if defined(SIGUSR2)
 
1704
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
 
1705
#else
 
1706
  thr_kill_signal= SIGINT;
 
1707
#endif
 
1708
 
 
1709
#ifdef _CUSTOMSTARTUPCONFIG_
 
1710
  if (_cust_check_startup())
 
1711
  {
 
1712
    / * _cust_check_startup will report startup failure error * /
 
1713
    exit(1);
 
1714
  }
 
1715
#endif
 
1716
 
 
1717
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
 
1718
                            argc, argv, load_default_groups))
 
1719
    unireg_abort(1);                            // Will do exit
 
1720
 
 
1721
  init_signals();
 
1722
 
 
1723
#ifdef TODO_MOVE_OUT_TO_SCHEDULER_API
 
1724
  pthread_attr_setstacksize(&connection_attrib, my_thread_stack_size);
 
1725
 
 
1726
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
 
1727
  {
 
1728
    /* Retrieve used stack size;  Needed for checking stack overflows */
 
1729
    size_t stack_size= 0;
 
1730
    pthread_attr_getstacksize(&connection_attrib, &stack_size);
 
1731
    /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
 
1732
    if (stack_size && stack_size < my_thread_stack_size)
 
1733
    {
 
1734
      if (global_system_variables.log_warnings)
 
1735
      {
 
1736
            errmsg_printf(ERRMSG_LVL_WARN, _("Asked for %"PRIu64" thread stack, "
 
1737
                            "but got %"PRIu64),
 
1738
                          (uint64_t)my_thread_stack_size,
 
1739
                          (uint64_t)stack_size);
 
1740
      }
 
1741
      my_thread_stack_size= stack_size;
 
1742
    }
 
1743
  }
 
1744
#endif
 
1745
#endif
 
1746
 
 
1747
  select_thread=pthread_self();
 
1748
  select_thread_in_use=1;
 
1749
 
 
1750
  /*
 
1751
    We have enough space for fiddling with the argv, continue
 
1752
  */
 
1753
  check_data_home(drizzle_real_data_home);
 
1754
  if (chdir(drizzle_real_data_home) && !opt_help)
 
1755
    unireg_abort(1);                            /* purecov: inspected */
 
1756
  drizzle_data_home= drizzle_data_home_buff;
 
1757
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
 
1758
  drizzle_data_home[1]=0;
 
1759
  drizzle_data_home_len= 2;
 
1760
 
 
1761
  if ((user_info= check_user(drizzled_user)))
 
1762
  {
 
1763
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
 
1764
    if (locked_in_memory) // getuid() == 0 here
 
1765
      set_effective_user(user_info);
 
1766
    else
 
1767
#endif
 
1768
      set_user(drizzled_user, user_info);
 
1769
  }
 
1770
 
 
1771
  if (server_id == 0)
 
1772
  {
 
1773
    server_id= 1;
 
1774
  }
 
1775
 
 
1776
  if (init_server_components())
 
1777
    unireg_abort(1);
 
1778
 
 
1779
  network_init();
 
1780
 
 
1781
  safe_read_error_hook= safe_read_error_impl; 
 
1782
 
 
1783
  /*
 
1784
    init signals & alarm
 
1785
    After this we can't quit by a simple unireg_abort
 
1786
  */
 
1787
  error_handler_hook= my_message_sql;
 
1788
 
 
1789
  if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
 
1790
  {
 
1791
    abort_loop= true;
 
1792
    select_thread_in_use=0;
 
1793
    (void) pthread_kill(signal_thread, SIGTERM);
 
1794
 
 
1795
    (void) unlink(pidfile_name);        // Not needed anymore
 
1796
 
 
1797
    exit(1);
 
1798
  }
 
1799
 
 
1800
  init_status_vars();
 
1801
 
 
1802
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
 
1803
                        "", drizzled_port, COMPILATION_COMMENT);
 
1804
 
 
1805
 
 
1806
  handle_connections_sockets();
 
1807
  /* (void) pthread_attr_destroy(&connection_attrib); */
 
1808
 
 
1809
 
 
1810
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
1811
  select_thread_in_use=0;                       // For close_connections
 
1812
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1813
  (void) pthread_cond_broadcast(&COND_thread_count);
 
1814
 
 
1815
  /* Wait until cleanup is done */
 
1816
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
1817
  while (!ready_to_exit)
 
1818
    pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
1819
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
1820
 
 
1821
  clean_up(1);
 
1822
  clean_up_mutexes();
 
1823
  my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
 
1824
  return 0;
 
1825
}
 
1826
 
 
1827
 
 
1828
/**
 
1829
  Create new thread to handle incoming connection.
 
1830
 
 
1831
    This function will create new thread to handle the incoming
 
1832
    connection.  If there are idle cached threads one will be used.
 
1833
    'session' will be pushed into 'threads'.
 
1834
 
 
1835
    In single-threaded mode (\#define ONE_THREAD) connection will be
 
1836
    handled inside this function.
 
1837
 
 
1838
  @param[in,out] session    Thread handle of future thread.
 
1839
*/
 
1840
 
 
1841
static void create_new_thread(Session *session)
 
1842
{
 
1843
  ++connection_count;
 
1844
 
 
1845
  if (connection_count > max_used_connections)
 
1846
    max_used_connections= connection_count;
 
1847
 
 
1848
  /*
 
1849
    The initialization of thread_id is done in create_embedded_session() for
 
1850
    the embedded library.
 
1851
    TODO: refactor this to avoid code duplication there
 
1852
  */
 
1853
  session->thread_id= session->variables.pseudo_thread_id= thread_id++;
 
1854
 
 
1855
  /* 
 
1856
    If we error on creation we drop the connection and delete the session.
 
1857
  */
 
1858
  pthread_mutex_lock(&LOCK_thread_count);
 
1859
  session_list.append(session);
 
1860
  pthread_mutex_unlock(&LOCK_thread_count);
 
1861
  if (thread_scheduler.add_connection(session))
 
1862
  {
 
1863
    char error_message_buff[DRIZZLE_ERRMSG_SIZE];
 
1864
 
 
1865
    session->killed= Session::KILL_CONNECTION;                        // Safety
 
1866
 
 
1867
    statistic_increment(aborted_connects, &LOCK_status);
 
1868
 
 
1869
    /* Can't use my_error() since store_globals has not been called. */
 
1870
    snprintf(error_message_buff, sizeof(error_message_buff), ER(ER_CANT_CREATE_THREAD), 1); /* TODO replace will better error message */
 
1871
    net_send_error(session, ER_CANT_CREATE_THREAD, error_message_buff);
 
1872
    unlink_session(session);
 
1873
  }
 
1874
}
 
1875
 
 
1876
 
 
1877
        /* Handle new connections and spawn new process to handle them */
 
1878
 
 
1879
void handle_connections_sockets()
 
1880
{
 
1881
  int x;
 
1882
  int sock,new_sock;
 
1883
  uint32_t error_count=0;
 
1884
  Session *session;
 
1885
  struct sockaddr_storage cAddr;
 
1886
 
 
1887
  while (!abort_loop)
 
1888
  {
 
1889
    int number_of;
 
1890
 
 
1891
    if ((number_of= poll(fds, pollfd_count, -1)) == -1)
 
1892
    {
 
1893
      if (errno != EINTR)
 
1894
      {
 
1895
        if (!select_errors++ && !abort_loop)    /* purecov: inspected */
 
1896
                errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
 
1897
                          errno); /* purecov: inspected */
 
1898
      }
 
1899
      continue;
 
1900
    }
 
1901
    if (number_of == 0)
 
1902
      continue;
 
1903
 
 
1904
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
 
1905
    assert(number_of > 1); /* Not handling this at the moment */
 
1906
#endif
 
1907
 
 
1908
    if (abort_loop)
 
1909
    {
 
1910
      break;
 
1911
    }
 
1912
 
 
1913
    for (x= 0, sock= -1; x < pollfd_count; x++)
 
1914
    {
 
1915
      if (fds[x].revents == POLLIN)
 
1916
      {
 
1917
        sock= fds[x].fd;
 
1918
        break;
 
1919
      }
 
1920
    }
 
1921
    assert(sock != -1);
 
1922
 
 
1923
    for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
 
1924
    {
 
1925
      socklen_t length= sizeof(struct sockaddr_storage);
 
1926
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
 
1927
                       &length);
 
1928
      if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
 
1929
        break;
 
1930
    }
 
1931
 
 
1932
 
 
1933
    if (new_sock == -1)
 
1934
    {
 
1935
      if ((error_count++ & 255) == 0)           // This can happen often
 
1936
        sql_perror("Error in accept");
 
1937
      if (errno == ENFILE || errno == EMFILE)
 
1938
        sleep(1);                               // Give other threads some time
 
1939
      continue;
 
1940
    }
 
1941
 
 
1942
    {
 
1943
      socklen_t dummyLen;
 
1944
      struct sockaddr_storage dummy;
 
1945
      dummyLen = sizeof(dummy);
 
1946
      if (  getsockname(new_sock,(struct sockaddr *)&dummy,
 
1947
                        (socklen_t *)&dummyLen) < 0  )
 
1948
      {
 
1949
        sql_perror("Error on new connection socket");
 
1950
        (void) shutdown(new_sock, SHUT_RDWR);
 
1951
        (void) close(new_sock);
 
1952
        continue;
 
1953
      }
 
1954
      dummyLen = sizeof(dummy);
 
1955
      if ( getpeername(new_sock, (struct sockaddr *)&dummy,
 
1956
                       (socklen_t *)&dummyLen) < 0)
 
1957
      {
 
1958
        sql_perror("Error on new connection socket");
 
1959
        (void) shutdown(new_sock, SHUT_RDWR);
 
1960
        (void) close(new_sock);
 
1961
         continue;
 
1962
      }
 
1963
    }
 
1964
 
 
1965
    /*
 
1966
    ** Don't allow too many connections
 
1967
    */
 
1968
 
 
1969
    if (!(session= new Session))
 
1970
    {
 
1971
      (void) shutdown(new_sock, SHUT_RDWR);
 
1972
      close(new_sock);
 
1973
      continue;
 
1974
    }
 
1975
    if (drizzleclient_net_init_sock(&session->net, new_sock, sock == 0))
 
1976
    {
 
1977
      delete session;
 
1978
      continue;
 
1979
    }
 
1980
 
 
1981
    create_new_thread(session);
 
1982
  }
 
1983
}
 
1984
 
 
1985
 
1671
1986
/****************************************************************************
1672
1987
  Handle start options
1673
1988
******************************************************************************/
1674
1989
 
1675
1990
enum options_drizzled
1676
1991
{
1677
 
  OPT_SOCKET=256,
1678
 
  OPT_BIND_ADDRESS,            
1679
 
  OPT_PID_FILE,
 
1992
  OPT_ISAM_LOG=256,
 
1993
  OPT_SOCKET,
 
1994
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
1680
1995
  OPT_STORAGE_ENGINE,          
1681
1996
  OPT_INIT_FILE,
 
1997
  OPT_DELAY_KEY_WRITE_ALL,
 
1998
  OPT_DELAY_KEY_WRITE,
1682
1999
  OPT_WANT_CORE,
1683
2000
  OPT_MEMLOCK,
 
2001
  OPT_MYISAM_RECOVER,
1684
2002
  OPT_SERVER_ID,
1685
2003
  OPT_TC_HEURISTIC_RECOVER,
 
2004
  OPT_ENGINE_CONDITION_PUSHDOWN,
1686
2005
  OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
1687
2006
  OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
1688
2007
  OPT_DO_PSTACK,
1689
2008
  OPT_LOCAL_INFILE,
1690
2009
  OPT_BACK_LOG,
 
2010
  OPT_CONNECT_TIMEOUT,
1691
2011
  OPT_JOIN_BUFF_SIZE,
 
2012
  OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
 
2013
  OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
1692
2014
  OPT_MAX_ALLOWED_PACKET,
1693
2015
  OPT_MAX_CONNECT_ERRORS,
1694
2016
  OPT_MAX_HEP_TABLE_SIZE,
1701
2023
  OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
1702
2024
  OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
1703
2025
  OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
1704
 
  OPT_NET_BUFFER_LENGTH,
 
2026
  OPT_MYISAM_STATS_METHOD,
 
2027
  OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
 
2028
  OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
1705
2029
  OPT_PRELOAD_BUFFER_SIZE,
1706
2030
  OPT_RECORD_BUFFER,
1707
2031
  OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT,
1721
2045
  OPT_DEFAULT_TIME_ZONE,
1722
2046
  OPT_OPTIMIZER_SEARCH_DEPTH,
1723
2047
  OPT_SCHEDULER,
1724
 
  OPT_PROTOCOL,
1725
2048
  OPT_OPTIMIZER_PRUNE_LEVEL,
1726
2049
  OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
1727
2050
  OPT_ENABLE_LARGE_PAGES,
1728
2051
  OPT_TIMED_MUTEXES,
1729
2052
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
1730
 
  OPT_PLUGIN_ADD,
1731
 
  OPT_PLUGIN_REMOVE,
1732
2053
  OPT_PLUGIN_LOAD,
1733
2054
  OPT_PLUGIN_DIR,
1734
2055
  OPT_PORT_OPEN_TIMEOUT,
 
2056
  OPT_KEEP_FILES_ON_CREATE,
1735
2057
  OPT_SECURE_FILE_PRIV,
1736
 
  OPT_MIN_EXAMINED_ROW_LIMIT,
1737
 
  OPT_PRINT_DEFAULTS
 
2058
  OPT_MIN_EXAMINED_ROW_LIMIT
1738
2059
};
1739
2060
 
1740
2061
 
1741
 
struct option my_long_options[] =
 
2062
#define LONG_TIMEOUT ((uint32_t) 3600L*24L*365L)
 
2063
 
 
2064
struct my_option my_long_options[] =
1742
2065
{
1743
 
 
1744
2066
  {"help", '?', N_("Display this help and exit."),
1745
2067
   (char**) &opt_help, (char**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1746
2068
   0, 0},
1748
2070
   N_("Auto-increment columns are incremented by this"),
1749
2071
   (char**) &global_system_variables.auto_increment_increment,
1750
2072
   (char**) &max_system_variables.auto_increment_increment, 0, GET_ULL,
1751
 
   OPT_ARG, 1, 1, INT64_MAX, 0, 1, 0 },
 
2073
   OPT_ARG, 1, 1, UINT64_MAX, 0, 1, 0 },
1752
2074
  {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
1753
2075
   N_("Offset added to Auto-increment columns. Used when "
1754
2076
      "auto-increment-increment != 1"),
1755
2077
   (char**) &global_system_variables.auto_increment_offset,
1756
2078
   (char**) &max_system_variables.auto_increment_offset, 0, GET_ULL, OPT_ARG,
1757
 
   1, 1, INT64_MAX, 0, 1, 0 },
 
2079
   1, 1, UINT64_MAX, 0, 1, 0 },
1758
2080
  {"basedir", 'b',
1759
2081
   N_("Path to installation directory. All paths are usually resolved "
1760
2082
      "relative to this."),
1761
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG,
 
2083
   (char**) &drizzle_home_ptr, (char**) &drizzle_home_ptr, 0, GET_STR, REQUIRED_ARG,
1762
2084
   0, 0, 0, 0, 0, 0},
 
2085
  {"bind-address", OPT_BIND_ADDRESS, N_("IP address to bind to."),
 
2086
   (char**) &my_bind_addr_str, (char**) &my_bind_addr_str, 0, GET_STR,
 
2087
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2088
  {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
 
2089
   N_("Set the filesystem character set."),
 
2090
   (char**) &character_set_filesystem_name,
 
2091
   (char**) &character_set_filesystem_name,
 
2092
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2093
  {"character-set-server", 'C',
 
2094
   N_("Set the default character set."),
 
2095
   (char**) &default_character_set_name, (char**) &default_character_set_name,
 
2096
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
1763
2097
  {"chroot", 'r',
1764
2098
   N_("Chroot drizzled daemon during startup."),
1765
2099
   (char**) &drizzled_chroot, (char**) &drizzled_chroot, 0, GET_STR, REQUIRED_ARG,
1779
2113
   NO_ARG, 0, 0, 0, 0, 0, 0},
1780
2114
  {"datadir", 'h',
1781
2115
   N_("Path to the database root."),
1782
 
   NULL, NULL, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2116
   (char**) &drizzle_data_home,
 
2117
   (char**) &drizzle_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1783
2118
  {"default-storage-engine", OPT_STORAGE_ENGINE,
1784
2119
   N_("Set the default storage engine (table type) for tables."),
1785
2120
   (char**)&default_storage_engine_str, (char**)&default_storage_engine_str,
1788
2123
   N_("Set the default time zone."),
1789
2124
   (char**) &default_tz_name, (char**) &default_tz_name,
1790
2125
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2126
  {"delay-key-write", OPT_DELAY_KEY_WRITE,
 
2127
   N_("Type of DELAY_KEY_WRITE."),
 
2128
   0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2129
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
2130
  {"enable-pstack", OPT_DO_PSTACK,
 
2131
   N_("Print a symbolic stack trace on failure."),
 
2132
   (char**) &opt_do_pstack, (char**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
 
2133
   0, 0, 0, 0},
 
2134
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
2135
  {"engine-condition-pushdown",
 
2136
   OPT_ENGINE_CONDITION_PUSHDOWN,
 
2137
   N_("Push supported query conditions to the storage engine."),
 
2138
   (char**) &global_system_variables.engine_condition_pushdown,
 
2139
   (char**) &global_system_variables.engine_condition_pushdown,
 
2140
   0, GET_BOOL, NO_ARG, false, 0, 0, 0, 0, 0},
1791
2141
  /* See how it's handled in get_one_option() */
1792
2142
  {"exit-info", 'T',
1793
2143
   N_("Used for debugging;  Use at your own risk!"),
1798
2148
   N_("Set up signals usable for debugging"),
1799
2149
   (char**) &opt_debugging, (char**) &opt_debugging,
1800
2150
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
2151
  {"init-connect", OPT_INIT_CONNECT,
 
2152
   N_("Command(s) that are executed for each new connection"),
 
2153
   (char**) &opt_init_connect, (char**) &opt_init_connect, 0, GET_STR_ALLOC,
 
2154
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2155
  {"init-file", OPT_INIT_FILE,
 
2156
   N_("Read SQL commands from this file at startup."),
 
2157
   (char**) &opt_init_file, (char**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
 
2158
   0, 0, 0, 0, 0, 0},
 
2159
  {"language", 'L',
 
2160
   N_("(IGNORED)"),
 
2161
   (char**) &language_ptr, (char**) &language_ptr, 0, GET_STR, REQUIRED_ARG,
 
2162
   0, 0, 0, 0, 0, 0},
1801
2163
  {"lc-time-names", OPT_LC_TIME_NAMES,
1802
2164
   N_("Set the language used for the month names and the days of the week."),
1803
2165
   (char**) &lc_time_names_name,
1804
2166
   (char**) &lc_time_names_name,
1805
2167
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
 
2168
  {"log", 'l',
 
2169
   N_("Log connections and queries to file."),
 
2170
   (char**) &opt_logname,
 
2171
   (char**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2172
  {"log-isam", OPT_ISAM_LOG,
 
2173
   N_("Log all MyISAM changes to file."),
 
2174
   (char**) &myisam_log_filename, (char**) &myisam_log_filename, 0, GET_STR,
 
2175
   OPT_ARG, 0, 0, 0, 0, 0, 0},
1806
2176
  {"log-warnings", 'W',
1807
2177
   N_("Log some not critical warnings to the log file."),
1808
2178
   (char**) &global_system_variables.log_warnings,
1809
2179
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1810
2180
   0, 0, 0},
 
2181
  {"memlock", OPT_MEMLOCK,
 
2182
   N_("Lock drizzled in memory."),
 
2183
   (char**) &locked_in_memory,
 
2184
   (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
2185
  {"myisam-recover", OPT_MYISAM_RECOVER,
 
2186
   N_("Syntax: myisam-recover[=option[,option...]], where option can be "
 
2187
      "DEFAULT, BACKUP, FORCE or QUICK."),
 
2188
   (char**) &myisam_recover_options_str, (char**) &myisam_recover_options_str, 0,
 
2189
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2190
  {"old-alter-table", OPT_OLD_ALTER_TABLE,
 
2191
   N_("Use old, non-optimized alter table."),
 
2192
   (char**) &global_system_variables.old_alter_table,
 
2193
   (char**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
 
2194
   0, 0, 0, 0, 0, 0},
1811
2195
  {"pid-file", OPT_PID_FILE,
1812
 
   N_("Pid file used by drizzled."),
1813
 
   NULL, NULL, 0, GET_STR,
 
2196
   N_("Pid file used by safe_mysqld."),
 
2197
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1814
2198
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2199
  {"port", 'P',
 
2200
   N_("Port number to use for connection or 0 for default to, in "
 
2201
      "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
 
2202
      "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
 
2203
   (char**) &drizzled_port,
 
2204
   (char**) &drizzled_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1815
2205
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
1816
2206
   N_("Maximum time in seconds to wait for the port to become free. "
1817
2207
      "(Default: no wait)"),
1818
 
   (char**) &drizzled_bind_timeout,
1819
 
   (char**) &drizzled_bind_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2208
   (char**) &drizzled_port_timeout,
 
2209
   (char**) &drizzled_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1820
2210
  {"secure-file-priv", OPT_SECURE_FILE_PRIV,
1821
2211
   N_("Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
1822
2212
      "within specified directory"),
1823
 
   NULL, NULL, 0,
 
2213
   (char**) &opt_secure_file_priv, (char**) &opt_secure_file_priv, 0,
1824
2214
   GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1825
2215
  {"server-id", OPT_SERVER_ID,
1826
2216
   N_("Uniquely identifies the server instance in the community of "
1833
2223
   0, 0, 0, 0},
1834
2224
  {"symbolic-links", 's',
1835
2225
   N_("Enable symbolic link support."),
1836
 
   (char**) &internal::my_use_symdir, (char**) &internal::my_use_symdir, 0, GET_BOOL, NO_ARG,
 
2226
   (char**) &my_use_symdir, (char**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
1837
2227
   /*
1838
2228
     The system call realpath() produces warnings under valgrind and
1839
2229
     purify. These are not suppressed: instead we disable symlinks
1840
2230
     option if compiled with valgrind support.
1841
2231
   */
1842
2232
   IF_PURIFY(0,1), 0, 0, 0, 0, 0},
 
2233
  {"temp-pool", OPT_TEMP_POOL,
 
2234
   N_("Using this option will cause most temporary files created to use a "
 
2235
      "small set of names, rather than a unique name for each new file."),
 
2236
   (char**) &use_temp_pool, (char**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
 
2237
   0, 0, 0, 0, 0},
1843
2238
  {"timed_mutexes", OPT_TIMED_MUTEXES,
1844
2239
   N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1845
2240
      "supported)"),
1846
 
   (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
 
2241
   (char**) &timed_mutexes, (char**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1847
2242
    0, 0, 0, 0, 0},
1848
2243
  {"tmpdir", 't',
1849
2244
   N_("Path for temporary files."),
1873
2268
    (char**) &global_system_variables.bulk_insert_buff_size,
1874
2269
    (char**) &max_system_variables.bulk_insert_buff_size,
1875
2270
    0, GET_ULL, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
 
2271
  { "connect_timeout", OPT_CONNECT_TIMEOUT,
 
2272
    N_("The number of seconds the drizzled server is waiting for a connect "
 
2273
       "packet before responding with 'Bad handshake'."),
 
2274
    (char**) &connect_timeout, (char**) &connect_timeout,
 
2275
    0, GET_UINT32, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
1876
2276
  { "div_precision_increment", OPT_DIV_PRECINCREMENT,
1877
2277
   N_("Precision of the result of '/' operator will be increased on that "
1878
2278
      "value."),
1890
2290
   (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
1891
2291
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
1892
2292
   MALLOC_OVERHEAD, IO_SIZE, 0},
 
2293
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
 
2294
   N_("Don't overwrite stale .MYD and .MYI even if no directory is specified."),
 
2295
   (char**) &global_system_variables.keep_files_on_create,
 
2296
   (char**) &max_system_variables.keep_files_on_create,
 
2297
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
2298
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
 
2299
   N_("The size of the buffer used for index blocks for MyISAM tables. "
 
2300
      "Increase this to get better index handling (for all reads and multiple "
 
2301
      "writes) to as much as you can afford;"),
 
2302
   (char**) &dflt_key_cache_var.param_buff_size,
 
2303
   (char**) 0,
 
2304
   0, (GET_ULL | GET_ASK_ADDR),
 
2305
   REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
 
2306
   IO_SIZE, 0},
 
2307
  {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
 
2308
   N_("This characterizes the number of hits a hot block has to be untouched "
 
2309
      "until it is considered aged enough to be downgraded to a warm block. "
 
2310
      "This specifies the percentage ratio of that number of hits to the "
 
2311
      "total number of blocks in key cache"),
 
2312
   (char**) &dflt_key_cache_var.param_age_threshold,
 
2313
   (char**) 0,
 
2314
   0, (GET_UINT32 | GET_ASK_ADDR), REQUIRED_ARG,
 
2315
   300, 100, ULONG_MAX, 0, 100, 0},
 
2316
  {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
 
2317
   N_("The default size of key cache blocks"),
 
2318
   (char**) &dflt_key_cache_var.param_block_size,
 
2319
   (char**) 0,
 
2320
   0, (GET_UINT32 | GET_ASK_ADDR), REQUIRED_ARG,
 
2321
   KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
 
2322
  {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
 
2323
   N_("The minimum percentage of warm blocks in key cache"),
 
2324
   (char**) &dflt_key_cache_var.param_division_limit,
 
2325
   (char**) 0,
 
2326
   0, (GET_UINT32 | GET_ASK_ADDR) , REQUIRED_ARG, 100,
 
2327
   1, 100, 0, 1, 0},
1893
2328
  {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
1894
2329
   N_("Max packetlength to send/receive from to server."),
1895
2330
   (char**) &global_system_variables.max_allowed_packet,
1896
2331
   (char**) &max_system_variables.max_allowed_packet, 0, GET_UINT32,
1897
 
   REQUIRED_ARG, 64*1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
2332
   REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
1898
2333
  {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
1899
2334
   N_("If there is more than this number of interrupted connections from a "
1900
2335
      "host this host will be blocked from further connections."),
1909
2344
   N_("Don't allow creation of heap tables bigger than this."),
1910
2345
   (char**) &global_system_variables.max_heap_table_size,
1911
2346
   (char**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
1912
 
   REQUIRED_ARG, 16*1024*1024L, 16384, (int64_t)MAX_MEM_TABLE_SIZE,
 
2347
   REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
1913
2348
   MALLOC_OVERHEAD, 1024, 0},
1914
2349
  {"max_join_size", OPT_MAX_JOIN_SIZE,
1915
2350
   N_("Joins that are probably going to read more than max_join_size records "
1934
2369
   (char**) &global_system_variables.max_sort_length,
1935
2370
   (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
1936
2371
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
 
2372
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
 
2373
   N_("Maximum number of temporary tables a client can keep open at a time."),
 
2374
   (char**) &global_system_variables.max_tmp_tables,
 
2375
   (char**) &max_system_variables.max_tmp_tables, 0, GET_UINT64,
 
2376
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
1937
2377
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
1938
2378
   N_("After this many write locks, allow some read locks to run in between."),
1939
2379
   (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
1944
2384
   (char**) &global_system_variables.min_examined_row_limit,
1945
2385
   (char**) &max_system_variables.min_examined_row_limit, 0, GET_ULL,
1946
2386
   REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
 
2387
  {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
 
2388
   N_("Specifies how MyISAM index statistics collection code should threat "
 
2389
      "NULLs. Possible values of name are 'nulls_unequal' "
 
2390
      "(default behavior), "
 
2391
      "'nulls_equal' (emulate MySQL 4.0 behavior), and 'nulls_ignored'."),
 
2392
   (char**) &myisam_stats_method_str, (char**) &myisam_stats_method_str, 0,
 
2393
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
2394
  {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
 
2395
   N_("Buffer length for TCP/IP and socket communication."),
 
2396
   (char**) &global_system_variables.net_buffer_length,
 
2397
   (char**) &max_system_variables.net_buffer_length, 0, GET_UINT32,
 
2398
   REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
 
2399
  {"net_read_timeout", OPT_NET_READ_TIMEOUT,
 
2400
   N_("Number of seconds to wait for more data from a connection before "
 
2401
      "aborting the read."),
 
2402
   (char**) &global_system_variables.net_read_timeout,
 
2403
   (char**) &max_system_variables.net_read_timeout, 0, GET_UINT32,
 
2404
   REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
 
2405
  {"net_retry_count", OPT_NET_RETRY_COUNT,
 
2406
   N_("If a read on a communication port is interrupted, retry this many "
 
2407
      "times before giving up."),
 
2408
   (char**) &global_system_variables.net_retry_count,
 
2409
   (char**) &max_system_variables.net_retry_count,0,
 
2410
   GET_UINT32, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
 
2411
  {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
 
2412
   N_("Number of seconds to wait for a block to be written to a connection "
 
2413
      "before aborting the write."),
 
2414
   (char**) &global_system_variables.net_write_timeout,
 
2415
   (char**) &max_system_variables.net_write_timeout, 0, GET_UINT32,
 
2416
   REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
1947
2417
  {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
1948
2418
    N_("Controls the heuristic(s) applied during query optimization to prune "
1949
2419
       "less-promising partial plans from the optimizer search space. Meaning: "
1963
2433
      "testing/comparison)."),
1964
2434
   (char**) &global_system_variables.optimizer_search_depth,
1965
2435
   (char**) &max_system_variables.optimizer_search_depth,
1966
 
   0, GET_UINT, OPT_ARG, 0, 0, MAX_TABLES+2, 0, 1, 0},
 
2436
   0, GET_UINT, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
1967
2437
  {"plugin_dir", OPT_PLUGIN_DIR,
1968
2438
   N_("Directory for plugins."),
1969
 
   NULL, NULL, 0,
1970
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1971
 
  {"plugin_add", OPT_PLUGIN_ADD,
1972
 
   N_("Optional comma separated list of plugins to load at startup in addition "
1973
 
      "to the default list of plugins. "
1974
 
      "[for example: --plugin_add=crc32,logger_gearman]"),
1975
 
   NULL, NULL, 0,
1976
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1977
 
  {"plugin_remove", OPT_PLUGIN_ADD,
1978
 
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
1979
 
      "removes a plugin from the list of plugins to be loaded. "
1980
 
      "[for example: --plugin_remove=crc32,logger_gearman]"),
1981
 
   NULL, NULL, 0,
 
2439
   (char**) &opt_plugin_dir_ptr, (char**) &opt_plugin_dir_ptr, 0,
1982
2440
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1983
2441
  {"plugin_load", OPT_PLUGIN_LOAD,
1984
 
   N_("Optional comma separated list of plugins to load at starup instead of "
1985
 
      "the default plugin load list. "
1986
 
      "[for example: --plugin_load=crc32,logger_gearman]"),
1987
 
   NULL, NULL, 0,
 
2442
   N_("Optional colon (or semicolon) separated list of plugins to load,"
 
2443
      "where each plugin is identified by the name of the shared library. "
 
2444
      "[for example: --plugin_load=libmd5udf.so:libauth_pam.so]"),
 
2445
   (char**) &opt_plugin_load, (char**) &opt_plugin_load, 0,
1988
2446
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1989
2447
  {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
1990
2448
   N_("The size of the buffer that is allocated when preloading indexes"),
2006
2464
   N_("Allocation block size for storing ranges during optimization"),
2007
2465
   (char**) &global_system_variables.range_alloc_block_size,
2008
2466
   (char**) &max_system_variables.range_alloc_block_size, 0, GET_SIZE,
2009
 
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, (int64_t)SIZE_MAX,
 
2467
   REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, SIZE_MAX,
2010
2468
   0, 1024, 0},
2011
2469
  {"read_buffer_size", OPT_RECORD_BUFFER,
2012
2470
    N_("Each thread that does a sequential scan allocates a buffer of this "
2025
2483
   GET_UINT, REQUIRED_ARG, 256*1024L, 64 /*IO_SIZE*2+MALLOC_OVERHEAD*/ ,
2026
2484
   UINT32_MAX, MALLOC_OVERHEAD, 1 /* Small lower limit to be able to test MRR */, 0},
2027
2485
  {"scheduler", OPT_SCHEDULER,
2028
 
   N_("Select scheduler to be used (by default multi-thread)."),
2029
 
   (char**)&opt_scheduler, (char**)&opt_scheduler,
2030
 
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2031
 
  /* x8 compared to MySQL's x2. We have UTF8 to consider. */
 
2486
   N_("Select scheduler to be used (by default pool-of-threads)."),
 
2487
   (char**) &opt_scheduler, (char**) &opt_scheduler, 0,
 
2488
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2032
2489
  {"sort_buffer_size", OPT_SORT_BUFFER,
2033
2490
   N_("Each thread that needs to do a sort allocates a buffer of this size."),
2034
2491
   (char**) &global_system_variables.sortbuff_size,
2035
2492
   (char**) &max_system_variables.sortbuff_size, 0, GET_SIZE, REQUIRED_ARG,
2036
 
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*8, (int64_t)SIZE_MAX,
 
2493
   MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, SIZE_MAX,
2037
2494
   MALLOC_OVERHEAD, 1, 0},
2038
2495
  {"table_definition_cache", OPT_TABLE_DEF_CACHE,
2039
2496
   N_("The number of cached table definitions."),
2040
2497
   (char**) &table_def_size, (char**) &table_def_size,
2041
 
   0, GET_SIZE, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
 
2498
   0, GET_ULL, REQUIRED_ARG, 128, 1, 512*1024L, 0, 1, 0},
2042
2499
  {"table_open_cache", OPT_TABLE_OPEN_CACHE,
2043
2500
   N_("The number of cached open tables."),
2044
2501
   (char**) &table_cache_size, (char**) &table_cache_size, 0, GET_UINT64,
2045
 
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, TABLE_OPEN_CACHE_MIN, 512*1024L, 0, 1, 0},
 
2502
   REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
2046
2503
  {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
2047
2504
   N_("Timeout in seconds to wait for a table level lock before returning an "
2048
2505
      "error. Used only if the connection has active cursors."),
2053
2510
   (char**) &my_thread_stack_size,
2054
2511
   (char**) &my_thread_stack_size, 0, GET_SIZE,
2055
2512
   REQUIRED_ARG,DEFAULT_THREAD_STACK,
2056
 
   UINT32_C(1024*512), (int64_t)SIZE_MAX, 0, 1024, 0},
 
2513
   UINT32_C(1024*128), SIZE_MAX, 0, 1024, 0},
2057
2514
  {"tmp_table_size", OPT_TMP_TABLE_SIZE,
2058
2515
   N_("If an internal in-memory temporary table exceeds this size, Drizzle will"
2059
2516
      " automatically convert it to an on-disk MyISAM table."),
2060
2517
   (char**) &global_system_variables.tmp_table_size,
2061
2518
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2062
 
   REQUIRED_ARG, 16*1024*1024L, 1024, (int64_t)MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
2519
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
 
2520
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
 
2521
   N_("Allocation block size for transactions to be stored in binary log"),
 
2522
   (char**) &global_system_variables.trans_alloc_block_size,
 
2523
   (char**) &max_system_variables.trans_alloc_block_size, 0, GET_UINT,
 
2524
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
2525
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
 
2526
   N_("Persistent buffer for transactions to be stored in binary log"),
 
2527
   (char**) &global_system_variables.trans_prealloc_size,
 
2528
   (char**) &max_system_variables.trans_prealloc_size, 0, GET_UINT,
 
2529
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
 
2530
  {"wait_timeout", OPT_WAIT_TIMEOUT,
 
2531
   N_("The number of seconds the server waits for activity on a connection "
 
2532
      "before closing it."),
 
2533
   (char**) &global_system_variables.net_wait_timeout,
 
2534
   (char**) &max_system_variables.net_wait_timeout, 0, GET_UINT,
 
2535
   REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT,
 
2536
   0, 1, 0},
2063
2537
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2064
2538
};
2065
2539
 
 
2540
static int show_net_compression(Session *session,
 
2541
                                SHOW_VAR *var,
 
2542
                                char *)
 
2543
{
 
2544
  var->type= SHOW_MY_BOOL;
 
2545
  var->value= (char *)&session->net.compress;
 
2546
  return 0;
 
2547
}
 
2548
 
 
2549
static st_show_var_func_container
 
2550
show_net_compression_cont= { &show_net_compression };
 
2551
 
 
2552
static int show_starttime(Session *session, SHOW_VAR *var, char *buff)
 
2553
{
 
2554
  var->type= SHOW_LONG;
 
2555
  var->value= buff;
 
2556
  *((long *)buff)= (long) (session->query_start() - server_start_time);
 
2557
  return 0;
 
2558
}
 
2559
 
 
2560
static st_show_var_func_container
 
2561
show_starttime_cont= { &show_starttime };
 
2562
 
 
2563
static int show_flushstatustime(Session *session, SHOW_VAR *var, char *buff)
 
2564
{
 
2565
  var->type= SHOW_LONG;
 
2566
  var->value= buff;
 
2567
  *((long *)buff)= (long) (session->query_start() - flush_status_time);
 
2568
  return 0;
 
2569
}
 
2570
 
 
2571
static st_show_var_func_container
 
2572
show_flushstatustime_cont= { &show_flushstatustime };
 
2573
 
 
2574
static int show_open_tables(Session *, SHOW_VAR *var, char *buff)
 
2575
{
 
2576
  var->type= SHOW_LONG;
 
2577
  var->value= buff;
 
2578
  *((long *)buff)= (long)cached_open_tables();
 
2579
  return 0;
 
2580
}
 
2581
 
 
2582
static int show_table_definitions(Session *,
 
2583
                                  SHOW_VAR *var, char *buff)
 
2584
{
 
2585
  var->type= SHOW_LONG;
 
2586
  var->value= buff;
 
2587
  *((long *)buff)= (long)cached_table_definitions();
 
2588
  return 0;
 
2589
}
 
2590
 
 
2591
static st_show_var_func_container
 
2592
show_open_tables_cont= { &show_open_tables };
 
2593
static st_show_var_func_container
 
2594
show_table_definitions_cont= { &show_table_definitions };
 
2595
 
 
2596
/*
 
2597
  Variables shown by SHOW STATUS in alphabetical order
 
2598
*/
 
2599
 
 
2600
SHOW_VAR status_vars[]= {
 
2601
  {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONGLONG},
 
2602
  {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONGLONG},
 
2603
  {"Bytes_received",           (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
 
2604
  {"Bytes_sent",               (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
 
2605
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
 
2606
  {"Compression",              (char*) &show_net_compression_cont, SHOW_FUNC},
 
2607
  {"Connections",              (char*) &thread_id,          SHOW_INT_NOFLUSH},
 
2608
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
 
2609
  {"Created_tmp_files",        (char*) &my_tmp_file_created,SHOW_INT},
 
2610
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
 
2611
  {"Flush_commands",           (char*) &refresh_version,    SHOW_INT_NOFLUSH},
 
2612
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
 
2613
  {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
 
2614
  {"Handler_prepare",          (char*) offsetof(STATUS_VAR, ha_prepare_count),  SHOW_LONG_STATUS},
 
2615
  {"Handler_read_first",       (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
 
2616
  {"Handler_read_key",         (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
 
2617
  {"Handler_read_next",        (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
 
2618
  {"Handler_read_prev",        (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
 
2619
  {"Handler_read_rnd",         (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
 
2620
  {"Handler_read_rnd_next",    (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
 
2621
  {"Handler_rollback",         (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
 
2622
  {"Handler_savepoint",        (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
 
2623
  {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
 
2624
  {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
 
2625
  {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
 
2626
  {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
 
2627
  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
 
2628
  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
 
2629
  {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
 
2630
  {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
 
2631
  {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
 
2632
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
 
2633
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
 
2634
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_INT},
 
2635
  {"Open_files",               (char*) &my_file_opened,    SHOW_INT_NOFLUSH},
 
2636
  {"Open_streams",             (char*) &my_stream_opened,  SHOW_INT_NOFLUSH},
 
2637
  {"Open_table_definitions",   (char*) &show_table_definitions_cont, SHOW_FUNC},
 
2638
  {"Open_tables",              (char*) &show_open_tables_cont,       SHOW_FUNC},
 
2639
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_INT_NOFLUSH},
 
2640
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
 
2641
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
 
2642
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
 
2643
  {"Select_full_join",         (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
 
2644
  {"Select_full_range_join",   (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
 
2645
  {"Select_range",             (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
 
2646
  {"Select_range_check",       (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
 
2647
  {"Select_scan",              (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
 
2648
  {"Slow_launch_threads",      (char*) &slow_launch_threads,    SHOW_LONGLONG},
 
2649
  {"Slow_queries",             (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
 
2650
  {"Sort_merge_passes",        (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
 
2651
  {"Sort_range",               (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
 
2652
  {"Sort_rows",                (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
 
2653
  {"Sort_scan",                (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
 
2654
  {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_INT},
 
2655
  {"Table_locks_waited",       (char*) &locks_waited,           SHOW_INT},
 
2656
  {"Threads_connected",        (char*) &connection_count,       SHOW_INT},
 
2657
  {"Uptime",                   (char*) &show_starttime_cont,         SHOW_FUNC},
 
2658
  {"Uptime_since_flush_status",(char*) &show_flushstatustime_cont,   SHOW_FUNC},
 
2659
  {NULL, NULL, SHOW_LONGLONG}
 
2660
};
 
2661
 
2066
2662
static void print_version(void)
2067
2663
{
 
2664
  set_server_version();
2068
2665
  /*
2069
2666
    Note: the instance manager keys off the string 'Ver' so it can find the
2070
2667
    version from the output of 'drizzled --version', so don't change it!
2071
2668
  */
2072
 
  printf("%s  Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
2073
 
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
2074
 
         COMPILATION_COMMENT);
 
2669
  printf("%s  Ver %s for %s on %s (%s)\n",my_progname,
 
2670
         server_version,SYSTEM_TYPE,MACHINE_TYPE, COMPILATION_COMMENT);
2075
2671
}
2076
2672
 
2077
2673
static void usage(void)
2085
2681
         "This software comes with ABSOLUTELY NO WARRANTY. "
2086
2682
         "This is free software,\n"
2087
2683
         "and you are welcome to modify and redistribute it under the GPL "
2088
 
         "license\n\n"));
2089
 
 
2090
 
 
2091
 
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
2092
 
 
2093
 
  po::options_description all_options("Drizzled Options");
2094
 
  all_options.add(config_options);
2095
 
  all_options.add(plugin_load_options);
2096
 
  all_options.add(long_options);
2097
 
  all_options.add(plugin_options);
2098
 
  cout << all_options << endl;
2099
 
 
 
2684
         "license\n\n"
 
2685
         "Starts the Drizzle database server\n"));
 
2686
 
 
2687
  printf(_("Usage: %s [OPTIONS]\n"), my_progname);
 
2688
  {
 
2689
#ifdef FOO
 
2690
  print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
2691
  puts("");
 
2692
  set_ports();
 
2693
#endif
 
2694
 
 
2695
  /* Print out all the options including plugin supplied options */
 
2696
  my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
 
2697
 
 
2698
  puts(_("\nTo see what values a running Drizzle server is using, type\n"
 
2699
         "'drizzleadmin variables' instead of 'drizzled --help'."));
 
2700
  }
2100
2701
}
2101
2702
 
 
2703
 
2102
2704
/**
2103
2705
  Initialize all Drizzle global variables to default values.
2104
2706
 
2118
2720
static void drizzle_init_variables(void)
2119
2721
{
2120
2722
  /* Things reset to zero */
 
2723
  drizzle_home[0]= pidfile_name[0]= 0;
 
2724
  opt_logname= 0;
2121
2725
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
 
2726
  opt_secure_file_priv= 0;
 
2727
  segfaulted= 0;
2122
2728
  cleanup_done= 0;
2123
 
  dropping_tables= ha_open_options=0;
2124
 
  test_flags.reset();
 
2729
  defaults_argc= 0;
 
2730
  defaults_argv= 0;
 
2731
  server_id_supplied= 0;
 
2732
  test_flags= select_errors= dropping_tables= ha_open_options=0;
2125
2733
  wake_thread=0;
 
2734
  opt_endinfo= using_udf_functions= 0;
2126
2735
  abort_loop= select_thread_in_use= false;
2127
2736
  ready_to_exit= shutdown_in_progress= 0;
2128
 
  drizzled_user= drizzled_chroot= 0;
2129
 
  memset(&current_global_counters, 0, sizeof(current_global_counters));
2130
 
  key_map_full.set();
 
2737
  aborted_threads= aborted_connects= 0;
 
2738
  max_used_connections= 0;
 
2739
  slow_launch_threads= 0;
 
2740
  drizzled_user= drizzled_chroot= opt_init_file= 0;
 
2741
  my_bind_addr_str= NULL;
 
2742
  memset(&global_status_var, 0, sizeof(global_status_var));
 
2743
  key_map_full.set_all();
2131
2744
 
2132
2745
  /* Character sets */
2133
2746
  system_charset_info= &my_charset_utf8_general_ci;
2136
2749
  character_set_filesystem= &my_charset_bin;
2137
2750
 
2138
2751
  /* Things with default values that are not zero */
 
2752
  delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_ON;
 
2753
  drizzle_home_ptr= drizzle_home;
 
2754
  pidfile_name_ptr= pidfile_name;
 
2755
  language_ptr= language;
 
2756
  drizzle_data_home= drizzle_real_data_home;
2139
2757
  session_startup_options= (OPTION_AUTO_IS_NULL | OPTION_SQL_NOTES);
2140
2758
  refresh_version= 1L;  /* Increments on each reload */
2141
 
  global_thread_id= 1UL;
2142
 
  session::Cache::singleton().getCache().clear();
 
2759
  thread_id= 1;
 
2760
  strcpy(server_version, VERSION);
 
2761
  myisam_recover_options_str= "OFF";
 
2762
  myisam_stats_method_str= "nulls_unequal";
 
2763
  session_list.empty();
 
2764
  key_caches.empty();
 
2765
  if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
 
2766
                                                default_key_cache_base.length)))
 
2767
    exit(1);
 
2768
  /* set key_cache_hash.default_value = dflt_key_cache */
 
2769
  multi_keycache_init();
 
2770
 
 
2771
  /* Set directory paths */
 
2772
  strncpy(language, LANGUAGE, sizeof(language)-1);
 
2773
  strncpy(drizzle_real_data_home, get_relative_path(LOCALSTATEDIR),
 
2774
          sizeof(drizzle_real_data_home)-1);
 
2775
  drizzle_data_home_buff[0]=FN_CURLIB;  // all paths are relative from here
 
2776
  drizzle_data_home_buff[1]=0;
 
2777
  drizzle_data_home_len= 2;
2143
2778
 
2144
2779
  /* Variables in libraries */
2145
 
  default_character_set_name= "utf8";
2146
 
  default_collation_name= (char *)compiled_default_collation_name;
2147
 
  character_set_filesystem_name= "binary";
 
2780
  default_character_set_name= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
 
2781
  default_collation_name= compiled_default_collation_name;
 
2782
  character_set_filesystem_name= (char*) "binary";
2148
2783
  lc_time_names_name= (char*) "en_US";
2149
2784
  /* Set default values for some option variables */
2150
2785
  default_storage_engine_str= (char*) "innodb";
2151
 
  global_system_variables.storage_engine= NULL;
 
2786
  global_system_variables.table_plugin= NULL;
2152
2787
  global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
2153
2788
  global_system_variables.select_limit= (uint64_t) HA_POS_ERROR;
2154
2789
  max_system_variables.select_limit=    (uint64_t) HA_POS_ERROR;
2155
2790
  global_system_variables.max_join_size= (uint64_t) HA_POS_ERROR;
2156
2791
  max_system_variables.max_join_size=   (uint64_t) HA_POS_ERROR;
2157
 
  max_system_variables.auto_increment_increment= UINT64_MAX;
2158
 
  max_system_variables.auto_increment_offset= UINT64_MAX;
2159
 
  max_system_variables.completion_type= 2;
2160
 
  max_system_variables.log_warnings= true;
2161
 
  max_system_variables.bulk_insert_buff_size= ULONG_MAX;
2162
 
  max_system_variables.div_precincrement= DECIMAL_MAX_SCALE;
2163
 
  max_system_variables.group_concat_max_len= ULONG_MAX;
2164
 
  max_system_variables.join_buff_size= ULONG_MAX;
2165
 
  max_system_variables.max_allowed_packet= 1024L*1024L*1024L;
2166
 
  max_system_variables.max_error_count= 65535;
2167
 
  max_system_variables.max_heap_table_size= MAX_MEM_TABLE_SIZE;
2168
 
  max_system_variables.max_join_size= INT32_MAX;
2169
 
  max_system_variables.max_length_for_sort_data= 8192*1024L;
2170
 
  max_system_variables.max_seeks_for_key= ULONG_MAX;
2171
 
  max_system_variables.max_sort_length= 8192*1024L;
2172
 
  max_system_variables.min_examined_row_limit= ULONG_MAX;
2173
 
  max_system_variables.optimizer_prune_level= 1;
2174
 
  max_system_variables.optimizer_search_depth= MAX_TABLES+2;
2175
 
  max_system_variables.preload_buff_size= 1024*1024*1024L;
2176
 
  max_system_variables.query_alloc_block_size= UINT32_MAX;
2177
 
  max_system_variables.query_prealloc_size= UINT32_MAX;
2178
 
  max_system_variables.range_alloc_block_size= SIZE_MAX;
2179
 
  max_system_variables.read_buff_size= INT32_MAX;
2180
 
  max_system_variables.read_rnd_buff_size= UINT32_MAX;
2181
 
  max_system_variables.sortbuff_size= SIZE_MAX;
2182
 
  max_system_variables.tmp_table_size= MAX_MEM_TABLE_SIZE;
2183
 
 
2184
 
  opt_scheduler_default= (char*) "multi_thread";
 
2792
  global_system_variables.old_alter_table= 0;
 
2793
  /*
 
2794
    Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
 
2795
    when collecting index statistics for MyISAM tables.
 
2796
  */
 
2797
  global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
2185
2798
 
2186
2799
  /* Variables that depends on compile options */
2187
2800
#ifdef HAVE_BROKEN_REALPATH
2190
2803
  have_symlink=SHOW_OPTION_YES;
2191
2804
#endif
2192
2805
 
 
2806
  const char *tmpenv;
 
2807
  if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
 
2808
    tmpenv = PREFIX;
 
2809
  (void) strncpy(drizzle_home, tmpenv, sizeof(drizzle_home)-1);
 
2810
  
2193
2811
  connection_count= 0;
2194
2812
}
2195
2813
 
2196
2814
 
2197
 
/**
2198
 
  @todo
2199
 
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "drizzled/error.h" and return that code?
2200
 
*/
2201
 
static void get_options()
 
2815
bool
 
2816
drizzled_get_one_option(int optid, const struct my_option *opt,
 
2817
                        char *argument)
2202
2818
{
2203
 
 
2204
 
  fs::path &data_home_catalog= getDataHomeCatalog();
2205
 
  data_home_catalog= getDataHome();
2206
 
  data_home_catalog /= "local"; 
2207
 
 
2208
 
  if (vm.count("user"))
2209
 
  {
2210
 
    if (! drizzled_user || ! strcmp(drizzled_user, vm["user"].as<string>().c_str()))
2211
 
      drizzled_user= (char *)vm["user"].as<string>().c_str();
2212
 
 
 
2819
  switch(optid) {
 
2820
  case '#':
 
2821
    opt_endinfo=1;                              /* unireg: memory allocation */
 
2822
    break;
 
2823
  case 'a':
 
2824
    global_system_variables.tx_isolation= ISO_SERIALIZABLE;
 
2825
    break;
 
2826
  case 'b':
 
2827
    strncpy(drizzle_home,argument,sizeof(drizzle_home)-1);
 
2828
    break;
 
2829
  case 'C':
 
2830
    if (default_collation_name == compiled_default_collation_name)
 
2831
      default_collation_name= 0;
 
2832
    break;
 
2833
  case 'h':
 
2834
    strncpy(drizzle_real_data_home,argument, sizeof(drizzle_real_data_home)-1);
 
2835
    /* Correct pointer set by my_getopt (for embedded library) */
 
2836
    drizzle_data_home= drizzle_real_data_home;
 
2837
    drizzle_data_home_len= strlen(drizzle_data_home);
 
2838
    break;
 
2839
  case 'u':
 
2840
    if (!drizzled_user || !strcmp(drizzled_user, argument))
 
2841
      drizzled_user= argument;
2213
2842
    else
2214
2843
      errmsg_printf(ERRMSG_LVL_WARN, _("Ignoring user change to '%s' because the user was "
2215
 
                                       "set to '%s' earlier on the command line\n"),
2216
 
                    vm["user"].as<string>().c_str(), drizzled_user);
2217
 
  }
2218
 
 
2219
 
  if (vm.count("version"))
2220
 
  {
 
2844
                          "set to '%s' earlier on the command line\n"),
 
2845
                        argument, drizzled_user);
 
2846
    break;
 
2847
  case 'L':
 
2848
    strncpy(language, argument, sizeof(language)-1);
 
2849
    break;
 
2850
  case 'V':
2221
2851
    print_version();
2222
2852
    exit(0);
2223
 
  }
2224
 
 
2225
 
  if (vm.count("sort-heap-threshold"))
2226
 
  {
2227
 
    if ((vm["sort-heap-threshold"].as<uint64_t>() > 0) and
2228
 
      (vm["sort-heap-threshold"].as<uint64_t>() < 
2229
 
      global_system_variables.sortbuff_size))
2230
 
    {
2231
 
      cout << N_("Error: sort-heap-threshold cannot be less than sort-buffer-size") << endl;
2232
 
      exit(-1);
2233
 
    }
2234
 
 
2235
 
    global_sort_buffer.setMaxSize(vm["sort-heap-threshold"].as<uint64_t>());
2236
 
  }
2237
 
 
2238
 
  if (vm.count("join-heap-threshold"))
2239
 
  {
2240
 
    if ((vm["join-heap-threshold"].as<uint64_t>() > 0) and
2241
 
      (vm["join-heap-threshold"].as<uint64_t>() <
2242
 
      global_system_variables.join_buff_size))
2243
 
    {
2244
 
      cout << N_("Error: join-heap-threshold cannot be less than join-buffer-size") << endl;
2245
 
      exit(-1);
2246
 
    }
2247
 
 
2248
 
    global_join_buffer.setMaxSize(vm["join-heap-threshold"].as<uint64_t>());
2249
 
  }
2250
 
 
2251
 
  if (vm.count("read-rnd-threshold"))
2252
 
  {
2253
 
    if ((vm["read-rnd-threshold"].as<uint64_t>() > 0) and
2254
 
      (vm["read-rnd-threshold"].as<uint64_t>() <
2255
 
      global_system_variables.read_rnd_buff_size))
2256
 
    {
2257
 
      cout << N_("Error: read-rnd-threshold cannot be less than read-rnd-buffer-size") << endl;
2258
 
      exit(-1);
2259
 
    }
2260
 
 
2261
 
    global_read_rnd_buffer.setMaxSize(vm["read-rnd-threshold"].as<uint64_t>());
2262
 
  }
2263
 
 
2264
 
  if (vm.count("read-buffer-threshold"))
2265
 
  {
2266
 
    if ((vm["read-buffer-threshold"].as<uint64_t>() > 0) and
2267
 
      (vm["read-buffer-threshold"].as<uint64_t>() <
2268
 
      global_system_variables.read_buff_size))
2269
 
    {
2270
 
      cout << N_("Error: read-buffer-threshold cannot be less than read-buffer-size") << endl;
2271
 
      exit(-1);
2272
 
    }
2273
 
 
2274
 
    global_read_buffer.setMaxSize(vm["read-buffer-threshold"].as<uint64_t>());
2275
 
  }
2276
 
 
2277
 
  if (vm.count("exit-info"))
2278
 
  {
2279
 
    if (vm["exit-info"].as<long>())
2280
 
    {
2281
 
      test_flags.set((uint32_t) vm["exit-info"].as<long>());
2282
 
    }
2283
 
  }
2284
 
 
2285
 
  if (vm.count("want-core"))
2286
 
  {
2287
 
    test_flags.set(TEST_CORE_ON_SIGNAL);
2288
 
  }
2289
 
 
2290
 
  if (vm.count("skip-stack-trace"))
2291
 
  {
2292
 
    test_flags.set(TEST_NO_STACKTRACE);
2293
 
  }
2294
 
 
2295
 
  if (vm.count("skip-symlinks"))
2296
 
  {
2297
 
    internal::my_use_symdir=0;
2298
 
  }
2299
 
 
2300
 
  if (vm.count("transaction-isolation"))
2301
 
  {
2302
 
    int type;
2303
 
    type= find_type_or_exit((char *)vm["transaction-isolation"].as<string>().c_str(), &tx_isolation_typelib, "transaction-isolation");
2304
 
    global_system_variables.tx_isolation= (type-1);
2305
 
  }
2306
 
 
2307
 
  /* @TODO Make this all strings */
2308
 
  if (vm.count("default-storage-engine"))
2309
 
  {
2310
 
    default_storage_engine_str= (char *)vm["default-storage-engine"].as<string>().c_str();
2311
 
  }
 
2853
  case 'W':
 
2854
    if (!argument)
 
2855
      global_system_variables.log_warnings++;
 
2856
    else if (argument == disabled_my_option)
 
2857
      global_system_variables.log_warnings= 0L;
 
2858
    else
 
2859
      global_system_variables.log_warnings= atoi(argument);
 
2860
    break;
 
2861
  case 'T':
 
2862
    test_flags= argument ? (uint32_t) atoi(argument) : 0;
 
2863
    opt_endinfo=1;
 
2864
    break;
 
2865
  case (int) OPT_WANT_CORE:
 
2866
    test_flags |= TEST_CORE_ON_SIGNAL;
 
2867
    break;
 
2868
  case (int) OPT_SKIP_STACK_TRACE:
 
2869
    test_flags|=TEST_NO_STACKTRACE;
 
2870
    break;
 
2871
  case (int) OPT_SKIP_SYMLINKS:
 
2872
    my_use_symdir=0;
 
2873
    break;
 
2874
  case (int) OPT_BIND_ADDRESS:
 
2875
    {
 
2876
      struct addrinfo *res_lst, hints;
 
2877
 
 
2878
      memset(&hints, 0, sizeof(struct addrinfo));
 
2879
      hints.ai_socktype= SOCK_STREAM;
 
2880
      hints.ai_protocol= IPPROTO_TCP;
 
2881
 
 
2882
      if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
 
2883
      {
 
2884
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: cannot resolve hostname!"));
 
2885
        exit(1);
 
2886
      }
 
2887
 
 
2888
      if (res_lst->ai_next)
 
2889
      {
 
2890
          errmsg_printf(ERRMSG_LVL_ERROR, _("Can't start server: bind-address refers to "
 
2891
                          "multiple interfaces!"));
 
2892
        exit(1);
 
2893
      }
 
2894
      freeaddrinfo(res_lst);
 
2895
    }
 
2896
    break;
 
2897
  case (int) OPT_PID_FILE:
 
2898
    strncpy(pidfile_name, argument, sizeof(pidfile_name)-1);
 
2899
    break;
 
2900
  case OPT_SERVER_ID:
 
2901
    server_id_supplied = 1;
 
2902
    break;
 
2903
  case OPT_DELAY_KEY_WRITE_ALL:
 
2904
    if (argument != disabled_my_option)
 
2905
      argument= (char*) "ALL";
 
2906
    /* Fall through */
 
2907
  case OPT_DELAY_KEY_WRITE:
 
2908
    if (argument == disabled_my_option)
 
2909
      delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_NONE;
 
2910
    else if (! argument)
 
2911
      delay_key_write_options= (uint32_t) DELAY_KEY_WRITE_ON;
 
2912
    else
 
2913
    {
 
2914
      int type;
 
2915
      type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
 
2916
      delay_key_write_options= (uint32_t) type-1;
 
2917
    }
 
2918
    break;
 
2919
  case OPT_TX_ISOLATION:
 
2920
    {
 
2921
      int type;
 
2922
      type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
 
2923
      global_system_variables.tx_isolation= (type-1);
 
2924
      break;
 
2925
    }
 
2926
  case OPT_MYISAM_RECOVER:
 
2927
    {
 
2928
      if (!argument)
 
2929
      {
 
2930
        myisam_recover_options=    HA_RECOVER_DEFAULT;
 
2931
        myisam_recover_options_str= myisam_recover_typelib.type_names[0];
 
2932
      }
 
2933
      else if (!argument[0])
 
2934
      {
 
2935
        myisam_recover_options= HA_RECOVER_NONE;
 
2936
        myisam_recover_options_str= "OFF";
 
2937
      }
 
2938
      else
 
2939
      {
 
2940
        myisam_recover_options_str=argument;
 
2941
        myisam_recover_options=
 
2942
          find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
 
2943
      }
 
2944
      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
 
2945
      break;
 
2946
    }
 
2947
  case OPT_TC_HEURISTIC_RECOVER:
 
2948
    tc_heuristic_recover= find_type_or_exit(argument,
 
2949
                                            &tc_heuristic_recover_typelib,
 
2950
                                            opt->name);
 
2951
    break;
 
2952
  case OPT_MYISAM_STATS_METHOD:
 
2953
    {
 
2954
      uint32_t method_conv;
 
2955
      int method;
 
2956
 
 
2957
      myisam_stats_method_str= argument;
 
2958
      method= find_type_or_exit(argument, &myisam_stats_method_typelib,
 
2959
                                opt->name);
 
2960
      switch (method-1) {
 
2961
      case 2:
 
2962
        method_conv= MI_STATS_METHOD_IGNORE_NULLS;
 
2963
        break;
 
2964
      case 1:
 
2965
        method_conv= MI_STATS_METHOD_NULLS_EQUAL;
 
2966
        break;
 
2967
      case 0:
 
2968
      default:
 
2969
        method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
 
2970
        break;
 
2971
      }
 
2972
      global_system_variables.myisam_stats_method= method_conv;
 
2973
      break;
 
2974
    }
 
2975
  }
 
2976
  return 0;
 
2977
}
 
2978
 
 
2979
 
 
2980
/** Handle arguments for multiple key caches. */
 
2981
 
 
2982
extern "C" char **drizzle_getopt_value(const char *keyname, uint32_t key_length,
 
2983
                                       const struct my_option *option);
 
2984
 
 
2985
char**
 
2986
drizzle_getopt_value(const char *keyname, uint32_t key_length,
 
2987
                    const struct my_option *option)
 
2988
{
 
2989
  switch (option->id) {
 
2990
  case OPT_KEY_BUFFER_SIZE:
 
2991
  case OPT_KEY_CACHE_BLOCK_SIZE:
 
2992
  case OPT_KEY_CACHE_DIVISION_LIMIT:
 
2993
  case OPT_KEY_CACHE_AGE_THRESHOLD:
 
2994
  {
 
2995
    KEY_CACHE *key_cache;
 
2996
    if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
 
2997
      exit(1);
 
2998
    switch (option->id) {
 
2999
    case OPT_KEY_BUFFER_SIZE:
 
3000
      return (char**) &key_cache->param_buff_size;
 
3001
    case OPT_KEY_CACHE_BLOCK_SIZE:
 
3002
      return (char**) &key_cache->param_block_size;
 
3003
    case OPT_KEY_CACHE_DIVISION_LIMIT:
 
3004
      return (char**) &key_cache->param_division_limit;
 
3005
    case OPT_KEY_CACHE_AGE_THRESHOLD:
 
3006
      return (char**) &key_cache->param_age_threshold;
 
3007
    }
 
3008
  }
 
3009
  }
 
3010
  return (char **)option->value;
 
3011
}
 
3012
 
 
3013
 
 
3014
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
 
3015
 
 
3016
void option_error_reporter(enum loglevel level, const char *format, ...)
 
3017
{
 
3018
  va_list args;
 
3019
  va_start(args, format);
 
3020
 
 
3021
  /* Don't print warnings for --loose options during bootstrap */
 
3022
  if (level == ERROR_LEVEL || global_system_variables.log_warnings)
 
3023
  {
 
3024
    errmsg_vprintf (current_session, ERROR_LEVEL, format, args);
 
3025
  }
 
3026
  va_end(args);
 
3027
}
 
3028
 
 
3029
 
 
3030
/**
 
3031
  @todo
 
3032
  - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
 
3033
*/
 
3034
static void get_options(int *argc,char **argv)
 
3035
{
 
3036
  int ho_error;
 
3037
 
 
3038
  my_getopt_register_get_addr(drizzle_getopt_value);
 
3039
  my_getopt_error_reporter= option_error_reporter;
2312
3040
 
2313
3041
  /* Skip unknown options so that they may be processed later by plugins */
2314
3042
  my_getopt_skip_unknown= true;
2315
3043
 
 
3044
  if ((ho_error= handle_options(argc, &argv, my_long_options,
 
3045
                                drizzled_get_one_option)))
 
3046
    exit(ho_error);
 
3047
  (*argc)++; /* add back one for the progname handle_options removes */
 
3048
             /* no need to do this for argv as we are discarding it. */
2316
3049
 
2317
3050
#if defined(HAVE_BROKEN_REALPATH)
2318
 
  internal::my_use_symdir=0;
2319
 
  internal::my_disable_symlinks=1;
 
3051
  my_use_symdir=0;
 
3052
  my_disable_symlinks=1;
2320
3053
  have_symlink=SHOW_OPTION_NO;
2321
3054
#else
2322
 
  if (!internal::my_use_symdir)
 
3055
  if (!my_use_symdir)
2323
3056
  {
2324
 
    internal::my_disable_symlinks=1;
 
3057
    my_disable_symlinks=1;
2325
3058
    have_symlink=SHOW_OPTION_DISABLED;
2326
3059
  }
2327
3060
#endif
2328
3061
  if (opt_debugging)
2329
3062
  {
2330
3063
    /* Allow break with SIGINT, no core or stack trace */
2331
 
    test_flags.set(TEST_SIGINT);
2332
 
    test_flags.set(TEST_NO_STACKTRACE);
2333
 
    test_flags.reset(TEST_CORE_ON_SIGNAL);
 
3064
    test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
 
3065
    test_flags&= ~TEST_CORE_ON_SIGNAL;
2334
3066
  }
 
3067
  /* Set global MyISAM variables from delay_key_write_options */
 
3068
  fix_delay_key_write((Session*) 0, OPT_GLOBAL);
2335
3069
 
2336
3070
  if (drizzled_chroot)
2337
3071
    set_root(drizzled_chroot);
 
3072
  fix_paths();
2338
3073
 
2339
3074
  /*
2340
3075
    Set some global variables from the global_system_variables
2341
3076
    In most cases the global variables will not be used
2342
3077
  */
2343
 
  internal::my_default_record_cache_size=global_system_variables.read_buff_size;
2344
 
}
2345
 
 
2346
 
 
2347
 
static void fix_paths()
2348
 
{
2349
 
  fs::path pid_file_path(pid_file);
2350
 
  if (pid_file_path.root_path().string() == "")
2351
 
  {
2352
 
    pid_file_path= getDataHome();
2353
 
    pid_file_path /= pid_file;
2354
 
  }
2355
 
  pid_file= fs::system_complete(pid_file_path);
2356
 
 
2357
 
  if (not opt_help)
2358
 
  {
2359
 
    const char *tmp_string= getenv("TMPDIR") ? getenv("TMPDIR") : NULL;
 
3078
  my_default_record_cache_size=global_system_variables.read_buff_size;
 
3079
  myisam_max_temp_length= INT32_MAX;
 
3080
}
 
3081
 
 
3082
/*
 
3083
  Create version name for running drizzled version
 
3084
  We automaticly add suffixes -debug, -embedded and -log to the version
 
3085
  name to make the version more descriptive.
 
3086
  (DRIZZLE_SERVER_SUFFIX is set by the compilation environment)
 
3087
*/
 
3088
 
 
3089
#ifdef DRIZZLE_SERVER_SUFFIX
 
3090
#define DRIZZLE_SERVER_SUFFIX_STR STRINGIFY_ARG(DRIZZLE_SERVER_SUFFIX)
 
3091
#else
 
3092
#define DRIZZLE_SERVER_SUFFIX_STR ""
 
3093
#endif
 
3094
 
 
3095
static void set_server_version(void)
 
3096
{
 
3097
  char *end= server_version;
 
3098
  end+= sprintf(server_version, "%s%s", VERSION, 
 
3099
                DRIZZLE_SERVER_SUFFIX_STR);
 
3100
}
 
3101
 
 
3102
 
 
3103
static const char *get_relative_path(const char *path)
 
3104
{
 
3105
  if (test_if_hard_path(path) &&
 
3106
      is_prefix(path,PREFIX) &&
 
3107
      strcmp(PREFIX,FN_ROOTDIR))
 
3108
  {
 
3109
    if (strlen(PREFIX) < strlen(path))
 
3110
      path+=(size_t) strlen(PREFIX);
 
3111
    while (*path == FN_LIBCHAR)
 
3112
      path++;
 
3113
  }
 
3114
  return path;
 
3115
}
 
3116
 
 
3117
 
 
3118
static void fix_paths(void)
 
3119
{
 
3120
  char buff[FN_REFLEN],*pos;
 
3121
  convert_dirname(drizzle_home,drizzle_home,NULL);
 
3122
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
 
3123
  my_realpath(drizzle_home,drizzle_home,MYF(0));
 
3124
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
 
3125
  pos= strchr(drizzle_home, '\0');
 
3126
  if (pos[-1] != FN_LIBCHAR)
 
3127
  {
 
3128
    pos[0]= FN_LIBCHAR;
 
3129
    pos[1]= 0;
 
3130
  }
 
3131
  convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
 
3132
  (void) fn_format(buff, drizzle_real_data_home, "", "",
 
3133
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
3134
  (void) unpack_dirname(drizzle_unpacked_real_data_home, buff);
 
3135
  convert_dirname(language,language,NULL);
 
3136
  (void) my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
3137
  (void) my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
 
3138
  (void) my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
 
3139
  (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
 
3140
                                      get_relative_path(PKGPLUGINDIR),
 
3141
                                      drizzle_home);
 
3142
  opt_plugin_dir_ptr= opt_plugin_dir;
 
3143
 
 
3144
  const char *sharedir= get_relative_path(PKGDATADIR);
 
3145
  if (test_if_hard_path(sharedir))
 
3146
    strncpy(buff,sharedir,sizeof(buff)-1);              /* purecov: tested */
 
3147
  else
 
3148
  {
 
3149
    strcpy(buff, drizzle_home);
 
3150
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
 
3151
  }
 
3152
  convert_dirname(buff,buff,NULL);
 
3153
  (void) my_load_path(language,language,buff);
 
3154
 
 
3155
  {
 
3156
    char *tmp_string;
2360
3157
    struct stat buf;
2361
 
    drizzle_tmpdir.clear();
2362
 
 
2363
 
    if (vm.count("tmpdir"))
2364
 
    {
2365
 
      drizzle_tmpdir.append(vm["tmpdir"].as<string>());
2366
 
    }
 
3158
 
 
3159
    tmp_string= getenv("TMPDIR");
 
3160
 
 
3161
    if (opt_drizzle_tmpdir)
 
3162
      drizzle_tmpdir= strdup(opt_drizzle_tmpdir);
2367
3163
    else if (tmp_string == NULL)
2368
 
    {
2369
 
      drizzle_tmpdir.append(getDataHome().file_string());
2370
 
      drizzle_tmpdir.push_back(FN_LIBCHAR);
2371
 
      drizzle_tmpdir.append(GLOBAL_TEMPORARY_EXT);
2372
 
    }
2373
 
    else
2374
 
    {
2375
 
      drizzle_tmpdir.append(tmp_string);
2376
 
    }
2377
 
 
2378
 
    drizzle_tmpdir= fs::path(fs::system_complete(fs::path(drizzle_tmpdir))).file_string();
2379
 
    assert(drizzle_tmpdir.size());
2380
 
 
2381
 
    if (mkdir(drizzle_tmpdir.c_str(), 0777) == -1)
2382
 
    {
2383
 
      if (errno != EEXIST)
2384
 
      {
2385
 
        perror(drizzle_tmpdir.c_str());
2386
 
        exit(1);
2387
 
      }
2388
 
    }
2389
 
 
2390
 
    if (stat(drizzle_tmpdir.c_str(), &buf) || (S_ISDIR(buf.st_mode) == false))
2391
 
    {
2392
 
      perror(drizzle_tmpdir.c_str());
2393
 
      exit(1);
2394
 
    }
2395
 
  }
2396
 
 
2397
 
}
2398
 
 
2399
 
} /* namespace drizzled */
2400
 
 
 
3164
      drizzle_tmpdir= strdup(P_tmpdir);
 
3165
    else
 
3166
      drizzle_tmpdir= strdup(tmp_string);
 
3167
 
 
3168
    assert(drizzle_tmpdir);
 
3169
 
 
3170
    if (stat(drizzle_tmpdir, &buf) || (S_ISDIR(buf.st_mode) == false))
 
3171
    {
 
3172
      exit(1);
 
3173
    }
 
3174
  }
 
3175
 
 
3176
  /*
 
3177
    Convert the secure-file-priv option to system format, allowing
 
3178
    a quick strcmp to check if read or write is in an allowed dir
 
3179
   */
 
3180
  if (opt_secure_file_priv)
 
3181
  {
 
3182
    convert_dirname(buff, opt_secure_file_priv, NULL);
 
3183
    free(opt_secure_file_priv);
 
3184
    opt_secure_file_priv= strdup(buff);
 
3185
    if (opt_secure_file_priv == NULL)
 
3186
      exit(1);
 
3187
  }
 
3188
}
 
3189
 
 
3190
 
 
3191
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
 
3192
                                      const char *option)
 
3193
{
 
3194
  uint32_t res;
 
3195
 
 
3196
  const char **ptr;
 
3197
 
 
3198
  if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
 
3199
  {
 
3200
    ptr= bit_lib->type_names;
 
3201
    if (!*x)
 
3202
      fprintf(stderr, _("No option given to %s\n"), option);
 
3203
    else
 
3204
      fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
 
3205
              option, x);
 
3206
    fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
 
3207
    while (*++ptr)
 
3208
      fprintf(stderr, ",'%s'", *ptr);
 
3209
    fprintf(stderr, "\n");
 
3210
    exit(1);
 
3211
  }
 
3212
  return res;
 
3213
}
 
3214
 
 
3215
 
 
3216
/**
 
3217
  @return
 
3218
    a bitfield from a string of substrings separated by ','
 
3219
    or
 
3220
    ~(uint32_t) 0 on error.
 
3221
*/
 
3222
 
 
3223
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
 
3224
{
 
3225
  bool found_end;
 
3226
  int  found_count;
 
3227
  const char *end,*i,*j;
 
3228
  const char **array, *pos;
 
3229
  uint32_t found,found_int,bit;
 
3230
 
 
3231
  found=0;
 
3232
  found_end= 0;
 
3233
  pos=(char *) x;
 
3234
  while (*pos == ' ') pos++;
 
3235
  found_end= *pos == 0;
 
3236
  while (!found_end)
 
3237
  {
 
3238
    if ((end=strrchr(pos,',')) != NULL)         /* Let end point at fieldend */
 
3239
    {
 
3240
      while (end > pos && end[-1] == ' ')
 
3241
        end--;                                  /* Skip end-space */
 
3242
      found_end=1;
 
3243
    }
 
3244
    else
 
3245
    {
 
3246
        end=pos+strlen(pos);
 
3247
        found_end=1;
 
3248
    }
 
3249
    found_int=0; found_count=0;
 
3250
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
 
3251
    {
 
3252
      j=pos;
 
3253
      while (j != end)
 
3254
      {
 
3255
        if (my_toupper(mysqld_charset,*i++) !=
 
3256
            my_toupper(mysqld_charset,*j++))
 
3257
          goto skip;
 
3258
      }
 
3259
      found_int=bit;
 
3260
      if (! *i)
 
3261
      {
 
3262
        found_count=1;
 
3263
        break;
 
3264
      }
 
3265
      else if (j != pos)                        // Half field found
 
3266
      {
 
3267
        found_count++;                          // Could be one of two values
 
3268
      }
 
3269
skip: ;
 
3270
    }
 
3271
    if (found_count != 1)
 
3272
      return(~(uint32_t) 0);                            // No unique value
 
3273
    found|=found_int;
 
3274
    pos=end+1;
 
3275
  }
 
3276
 
 
3277
  return(found);
 
3278
} /* find_bit_type */
 
3279
 
 
3280
 
 
3281
bool safe_read_error_impl(NET *net)
 
3282
{
 
3283
  if (net->vio)
 
3284
    return drizzleclient_vio_was_interrupted(net->vio);
 
3285
  return false;
 
3286
}
 
3287
 
 
3288
 
 
3289
/*****************************************************************************
 
3290
  Instantiate templates
 
3291
*****************************************************************************/
 
3292
 
 
3293
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3294
/* Used templates */
 
3295
template class I_List<Session>;
 
3296
template class I_List_iterator<Session>;
 
3297
template class I_List<i_string>;
 
3298
template class I_List<i_string_pair>;
 
3299
template class I_List<NAMED_LIST>;
 
3300
template class I_List<Statement>;
 
3301
template class I_List_iterator<Statement>;
 
3302
#endif