~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

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