~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2010-02-11 01:35:55 UTC
  • mfrom: (1289 staging)
  • mto: This revision was merged to the branch mainline in revision 1293.
  • Revision ID: mordred@inaugust.com-20100211013555-f9okqsgi91mwm4xu
Merged up with trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
 
73
73
#include <locale.h>
74
74
 
75
 
#define mysqld_charset &my_charset_utf8_general_ci
76
 
 
77
 
#ifdef HAVE_purify
78
 
#define IF_PURIFY(A,B) (A)
79
 
#else
80
 
#define IF_PURIFY(A,B) (B)
81
 
#endif
82
 
 
83
 
#define MAX_MEM_TABLE_SIZE SIZE_MAX
84
75
 
85
76
#include <errno.h>
86
77
#include <sys/stat.h>
120
111
#include <sys/fpu.h>
121
112
#endif
122
113
 
 
114
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
 
115
 
 
116
#include <drizzled/gettext.h>
 
117
 
 
118
 
 
119
#ifdef HAVE_purify
 
120
#define IF_PURIFY(A,B) (A)
 
121
#else
 
122
#define IF_PURIFY(A,B) (B)
 
123
#endif
 
124
 
 
125
#define MAX_MEM_TABLE_SIZE SIZE_MAX
 
126
 
 
127
using namespace std;
 
128
 
 
129
namespace drizzled
 
130
{
 
131
 
 
132
#define mysqld_charset &my_charset_utf8_general_ci
123
133
inline void setup_fpu()
124
134
{
125
135
#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
149
159
#endif /* __i386__ && HAVE_FPU_CONTROL_H && _FPU_DOUBLE */
150
160
}
151
161
 
152
 
#include "drizzled/internal/my_pthread.h"                       // For thr_setconcurency()
153
 
 
154
 
#include <drizzled/gettext.h>
155
 
 
156
162
#ifdef SOLARIS
157
163
extern "C" int gethostname(char *name, int namelen);
158
164
#endif
159
165
 
160
 
using namespace std;
161
 
using namespace drizzled;
162
 
 
163
166
/* Constants */
164
 
 
165
 
 
166
 
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
167
 
static const char *optimizer_switch_names[]=
168
 
{
169
 
  "no_materialization", "no_semijoin",
170
 
  NULL
171
 
};
172
 
 
173
 
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
174
 
static const unsigned int optimizer_switch_names_len[]=
175
 
{
176
 
  /*no_materialization*/          19,
177
 
  /*no_semijoin*/                 11
178
 
};
179
 
 
180
 
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
181
 
                                    optimizer_switch_names,
182
 
                                    (unsigned int *)optimizer_switch_names_len };
183
 
 
184
167
static const char *tc_heuristic_recover_names[]=
185
168
{
186
169
  "COMMIT", "ROLLBACK", NULL
233
216
 
234
217
/* Global variables */
235
218
 
236
 
bool locked_in_memory;
237
219
bool volatile abort_loop;
238
220
bool volatile shutdown_in_progress;
239
221
uint32_t max_used_connections;
379
361
  Number of currently active user connections. The variable is protected by
380
362
  LOCK_thread_count.
381
363
*/
382
 
drizzled::atomic<uint32_t> connection_count;
 
364
atomic<uint32_t> connection_count;
383
365
 
384
366
/** 
385
367
  Refresh value. We use to test this to find out if a refresh even has happened recently.
392
374
extern "C" pthread_handler_t signal_hand(void *arg);
393
375
static void drizzle_init_variables(void);
394
376
static void get_options(int *argc,char **argv);
395
 
extern "C" bool drizzled_get_one_option(int, const struct my_option *, char *);
 
377
bool drizzled_get_one_option(int, const struct my_option *, char *);
396
378
static int init_thread_environment();
397
379
static const char *get_relative_path(const char *path);
398
380
static void fix_paths(string &progname);
512
494
void unireg_end(void)
513
495
{
514
496
  clean_up(1);
515
 
  my_thread_end();
 
497
  internal::my_thread_end();
516
498
#if defined(SIGNALS_DONT_BREAK_READ)
517
499
  exit(0);
518
500
#else
530
512
    usage();
531
513
  clean_up(!opt_help && (exit_code));
532
514
  clean_up_mutexes();
533
 
  my_end();
 
515
  internal::my_end();
534
516
  exit(exit_code);
535
517
}
536
518
 
550
532
  xid_cache_free();
551
533
  free_status_vars();
552
534
  if (defaults_argv)
553
 
    free_defaults(defaults_argv);
 
535
    internal::free_defaults(defaults_argv);
554
536
  free(drizzle_tmpdir);
555
537
  if (opt_secure_file_priv)
556
538
    free(opt_secure_file_priv);
564
546
  (void) unlink(pidfile_name);  // This may not always exist
565
547
 
566
548
  if (print_message && server_start_time)
567
 
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),my_progname);
 
549
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_SHUTDOWN_COMPLETE)),internal::my_progname);
568
550
  /* Returns NULL on globerrs, we don't want to try to free that */
569
551
  //void *freeme=
570
552
  (void *)my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST);
687
669
}
688
670
 
689
671
 
690
 
static void set_effective_user(struct passwd *user_info_arg)
691
 
{
692
 
  assert(user_info_arg != 0);
693
 
  if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
694
 
  {
695
 
    sql_perror("setregid");
696
 
    unireg_abort(1);
697
 
  }
698
 
  if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
699
 
  {
700
 
    sql_perror("setreuid");
701
 
    unireg_abort(1);
702
 
  }
703
 
}
704
 
 
705
 
 
706
672
/** Change root user if started with @c --chroot . */
707
673
static void set_root(const char *path)
708
674
{
894
860
                      "nsswitch.conf, or use a\n"
895
861
                      "drizzled that is not statically linked.\n"));
896
862
 
897
 
  if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
 
863
  if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
898
864
    fprintf(stderr,
899
865
            _("\nYou are running a statically-linked LinuxThreads binary "
900
866
              "on an NPTL system.\n"
906
872
              "Please consult\n"
907
873
              "the documentation for your distribution on how to do that.\n"));
908
874
 
909
 
  if (locked_in_memory)
910
 
  {
911
 
    fprintf(stderr,
912
 
            _("\nThe '--memlock' argument, which was enabled, uses system "
913
 
              "calls that are\n"
914
 
              "unreliable and unstable on some operating systems and "
915
 
              "operating-system\n"
916
 
              "versions (notably, some versions of Linux).  "
917
 
              "This crash could be due to use\n"
918
 
              "of those buggy OS calls.  You should consider whether you "
919
 
              "really need the\n"
920
 
              "'--memlock' parameter and/or consult the OS "
921
 
              "distributor about 'mlockall'\n bugs.\n"));
922
 
  }
923
 
 
924
875
#ifdef HAVE_WRITE_CORE
925
876
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
926
877
  {
940
891
#define SA_NODEFER 0
941
892
#endif
942
893
 
943
 
static void init_signals(void)
944
 
{
945
 
  sigset_t set;
946
 
  struct sigaction sa;
947
 
 
948
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
949
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
950
 
  {
951
 
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
952
 
    sigemptyset(&sa.sa_mask);
953
 
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
954
 
 
955
 
    init_stacktrace();
956
 
    sa.sa_handler=handle_segfault;
957
 
    sigaction(SIGSEGV, &sa, NULL);
958
 
    sigaction(SIGABRT, &sa, NULL);
959
 
#ifdef SIGBUS
960
 
    sigaction(SIGBUS, &sa, NULL);
961
 
#endif
962
 
    sigaction(SIGILL, &sa, NULL);
963
 
    sigaction(SIGFPE, &sa, NULL);
964
 
  }
965
 
 
966
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
967
 
  {
968
 
    /* Change limits so that we will get a core file */
969
 
    struct rlimit rl;
970
 
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
971
 
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
972
 
        errmsg_printf(ERRMSG_LVL_WARN,
973
 
                      _("setrlimit could not change the size of core files "
974
 
                        "to 'infinity';  We may not be able to generate a "
975
 
                        "core file on signals"));
976
 
  }
977
 
  (void) sigemptyset(&set);
978
 
  my_sigset(SIGPIPE,SIG_IGN);
979
 
  sigaddset(&set,SIGPIPE);
980
 
#ifndef IGNORE_SIGHUP_SIGQUIT
981
 
  sigaddset(&set,SIGQUIT);
982
 
  sigaddset(&set,SIGHUP);
983
 
#endif
984
 
  sigaddset(&set,SIGTERM);
985
 
 
986
 
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
987
 
  sigemptyset(&sa.sa_mask);
988
 
  sa.sa_flags = 0;
989
 
  sa.sa_handler = print_signal_warning;
990
 
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
991
 
  sa.sa_flags = 0;
992
 
  sa.sa_handler = print_signal_warning;
993
 
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
994
 
#ifdef SIGTSTP
995
 
  sigaddset(&set,SIGTSTP);
996
 
#endif
997
 
  if (test_flags.test(TEST_SIGINT))
998
 
  {
999
 
    my_sigset(thr_kill_signal, end_thread_signal);
1000
 
    // May be SIGINT
1001
 
    sigdelset(&set, thr_kill_signal);
1002
 
  }
1003
 
  else
1004
 
    sigaddset(&set,SIGINT);
1005
 
  sigprocmask(SIG_SETMASK,&set,NULL);
1006
 
  pthread_sigmask(SIG_SETMASK,&set,NULL);
1007
 
  return;;
1008
 
}
1009
 
 
1010
 
void my_message_sql(uint32_t error, const char *str, myf MyFlags);
1011
894
 
1012
895
/**
1013
896
  All global error messages are sent here where the first one is stored
1014
897
  for the client.
1015
898
*/
1016
 
void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
899
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
1017
900
{
1018
901
  Session *session;
1019
902
  /*
1062
945
    }
1063
946
  }
1064
947
  if (!session || MyFlags & ME_NOREFRESH)
1065
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",my_progname,str);
 
948
    errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
1066
949
}
1067
950
 
1068
951
 
1148
1031
  {"show_create_db",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
1149
1032
  {"show_create_table",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
1150
1033
  {"show_databases",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
1151
 
  {"show_engine_status",   (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
1152
1034
  {"show_errors",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
1153
1035
  {"show_fields",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
1154
1036
  {"show_keys",            (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
1155
 
  {"show_open_tables",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
1156
1037
  {"show_processlist",     (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
1157
1038
  {"show_status",          (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
1158
1039
  {"show_table_status",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
1173
1054
  {"Com",                      (char*) com_status_vars, SHOW_ARRAY},
1174
1055
  {"Connections",              (char*) &global_thread_id, SHOW_INT_NOFLUSH},
1175
1056
  {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
1176
 
  {"Created_tmp_files",        (char*) &my_tmp_file_created,SHOW_INT},
 
1057
  {"Created_tmp_files",        (char*) &internal::my_tmp_file_created,SHOW_INT},
1177
1058
  {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
1178
1059
  {"Flush_commands",           (char*) &refresh_version,    SHOW_INT_NOFLUSH},
1179
1060
  {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
1199
1080
  {"Key_writes",               (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
1200
1081
  {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
1201
1082
  {"Max_used_connections",     (char*) &max_used_connections,  SHOW_INT},
1202
 
  {"Open_files",               (char*) &my_file_opened,    SHOW_INT_NOFLUSH},
1203
 
  {"Open_streams",             (char*) &my_stream_opened,  SHOW_INT_NOFLUSH},
 
1083
  {"Open_files",               (char*) &internal::my_file_opened,    SHOW_INT_NOFLUSH},
 
1084
  {"Open_streams",             (char*) &internal::my_stream_opened,  SHOW_INT_NOFLUSH},
1204
1085
  {"Open_table_definitions",   (char*) &show_table_definitions_cont, SHOW_FUNC},
1205
1086
  {"Open_tables",              (char*) &show_open_tables_cont,       SHOW_FUNC},
1206
 
  {"Opened_files",             (char*) &my_file_total_opened, SHOW_INT_NOFLUSH},
 
1087
  {"Opened_files",             (char*) &internal::my_file_total_opened, SHOW_INT_NOFLUSH},
1207
1088
  {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
1208
1089
  {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
1209
1090
  {"Questions",                (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
1229
1110
                                 char **argv, const char **groups)
1230
1111
{
1231
1112
  time_t curr_time;
1232
 
  umask(((~my_umask) & 0666));
 
1113
  umask(((~internal::my_umask) & 0666));
1233
1114
  my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
1234
1115
  tzset();                      // Set tzname
1235
1116
 
1268
1149
  }
1269
1150
  else
1270
1151
    strncpy(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
1271
 
  strcpy(fn_ext(pidfile_name),".pid");          // Add proper extension
 
1152
  strcpy(internal::fn_ext(pidfile_name),".pid");                // Add proper extension
1272
1153
 
1273
1154
  /*
1274
1155
    Add server status variables to the dynamic list of
1278
1159
  if (add_status_vars(status_vars))
1279
1160
    return 1; // an error was already reported
1280
1161
 
1281
 
  load_defaults(conf_file_name, groups, &argc, &argv);
 
1162
  internal::load_defaults(conf_file_name, groups, &argc, &argv);
1282
1163
  defaults_argv=argv;
1283
1164
  defaults_argc=argc;
1284
1165
  get_options(&defaults_argc, defaults_argv);
1416
1297
      We need to eat any 'loose' arguments first before we conclude
1417
1298
      that there are unprocessed options.
1418
1299
      But we need to preserve defaults_argv pointer intact for
1419
 
      free_defaults() to work. Thus we use a copy here.
 
1300
      internal::free_defaults() to work. Thus we use a copy here.
1420
1301
    */
1421
1302
    my_getopt_skip_unknown= 0;
1422
1303
 
1429
1310
      fprintf(stderr,
1430
1311
              _("%s: Too many arguments (first extra is '%s').\n"
1431
1312
                "Use --verbose --help to get a list of available options\n"),
1432
 
              my_progname, *tmp_argv);
 
1313
              internal::my_progname, *tmp_argv);
1433
1314
      unireg_abort(1);
1434
1315
    }
1435
1316
  }
1504
1385
    unireg_abort(1);
1505
1386
  }
1506
1387
 
1507
 
#if defined(MCL_CURRENT)
1508
 
  if (locked_in_memory && !getuid())
1509
 
  {
1510
 
    if (setreuid((uid_t)-1, 0) == -1)
1511
 
    {                        // this should never happen
1512
 
      sql_perror("setreuid");
1513
 
      unireg_abort(1);
1514
 
    }
1515
 
    if (mlockall(MCL_CURRENT))
1516
 
    {
1517
 
      if (global_system_variables.log_warnings)
1518
 
            errmsg_printf(ERRMSG_LVL_WARN, _("Failed to lock memory. Errno: %d\n"),errno);
1519
 
      locked_in_memory= 0;
1520
 
    }
1521
 
    if (user_info)
1522
 
      set_user(drizzled_user, user_info);
1523
 
  }
1524
 
  else
1525
 
#endif
1526
 
    locked_in_memory=0;
1527
 
 
1528
1388
  init_update_queries();
 
1389
 
1529
1390
  return(0);
1530
1391
}
1531
1392
 
1532
1393
 
1533
 
int main(int argc, char **argv)
1534
 
{
1535
 
#if defined(ENABLE_NLS)
1536
 
# if defined(HAVE_LOCALE_H)
1537
 
  setlocale(LC_ALL, "");
1538
 
# endif
1539
 
  bindtextdomain("drizzle", LOCALEDIR);
1540
 
  textdomain("drizzle");
1541
 
#endif
1542
 
 
1543
 
  plugin::Registry &plugins= plugin::Registry::singleton();
1544
 
  plugin::Client *client;
1545
 
  Session *session;
1546
 
 
1547
 
  MY_INIT(argv[0]);             // init my_sys library & pthreads
1548
 
  /* nothing should come before this line ^^^ */
1549
 
 
1550
 
  /* Set signal used to kill Drizzle */
1551
 
#if defined(SIGUSR2)
1552
 
  thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
1553
 
#else
1554
 
  thr_kill_signal= SIGINT;
1555
 
#endif
1556
 
 
1557
 
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
1558
 
                            argc, argv, load_default_groups))
1559
 
    unireg_abort(1);                            // Will do exit
1560
 
 
1561
 
  init_signals();
1562
 
 
1563
 
 
1564
 
  select_thread=pthread_self();
1565
 
  select_thread_in_use=1;
1566
 
 
1567
 
  if (chdir(drizzle_real_data_home) && !opt_help)
1568
 
  {
1569
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
1570
 
    unireg_abort(1);
1571
 
  }
1572
 
  drizzle_data_home= drizzle_data_home_buff;
1573
 
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
1574
 
  drizzle_data_home[1]=0;
1575
 
  drizzle_data_home_len= 2;
1576
 
 
1577
 
  if ((user_info= check_user(drizzled_user)))
1578
 
  {
1579
 
#if defined(MCL_CURRENT)
1580
 
    if (locked_in_memory) // getuid() == 0 here
1581
 
      set_effective_user(user_info);
1582
 
    else
1583
 
#endif
1584
 
      set_user(drizzled_user, user_info);
1585
 
  }
1586
 
 
1587
 
  if (server_id == 0)
1588
 
  {
1589
 
    server_id= 1;
1590
 
  }
1591
 
 
1592
 
  if (init_server_components(plugins))
1593
 
    unireg_abort(1);
1594
 
 
1595
 
  if (plugin::Listen::setup())
1596
 
    unireg_abort(1);
1597
 
 
1598
 
  /*
1599
 
    init signals & alarm
1600
 
    After this we can't quit by a simple unireg_abort
1601
 
  */
1602
 
  error_handler_hook= my_message_sql;
1603
 
 
1604
 
  if (drizzle_rm_tmp_tables() ||
1605
 
      my_tz_init((Session *)0, default_tz_name))
1606
 
  {
1607
 
    abort_loop= true;
1608
 
    select_thread_in_use=0;
1609
 
    (void) pthread_kill(signal_thread, SIGTERM);
1610
 
 
1611
 
    (void) unlink(pidfile_name);        // Not needed anymore
1612
 
 
1613
 
    exit(1);
1614
 
  }
1615
 
 
1616
 
  init_status_vars();
1617
 
 
1618
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), my_progname,
1619
 
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
1620
 
 
1621
 
 
1622
 
  /* Listen for new connections and start new session for each connection
1623
 
     accepted. The listen.getClient() method will return NULL when the server
1624
 
     should be shutdown. */
1625
 
  while ((client= plugin::Listen::getClient()) != NULL)
1626
 
  {
1627
 
    if (!(session= new Session(client)))
1628
 
    {
1629
 
      delete client;
1630
 
      continue;
1631
 
    }
1632
 
 
1633
 
    /* If we error on creation we drop the connection and delete the session. */
1634
 
    if (session->schedule())
1635
 
      Session::unlink(session);
1636
 
  }
1637
 
 
1638
 
  /* (void) pthread_attr_destroy(&connection_attrib); */
1639
 
 
1640
 
 
1641
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
1642
 
  select_thread_in_use=0;                       // For close_connections
1643
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
1644
 
  (void) pthread_cond_broadcast(&COND_thread_count);
1645
 
 
1646
 
  /* Wait until cleanup is done */
1647
 
  (void) pthread_mutex_lock(&LOCK_thread_count);
1648
 
  while (!ready_to_exit)
1649
 
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
1650
 
  (void) pthread_mutex_unlock(&LOCK_thread_count);
1651
 
 
1652
 
  clean_up(1);
1653
 
  plugin::Registry::shutdown();
1654
 
  clean_up_mutexes();
1655
 
  my_end();
1656
 
  return 0;
1657
 
}
1658
 
 
1659
 
 
1660
1394
/****************************************************************************
1661
1395
  Handle start options
1662
1396
******************************************************************************/
1719
1453
  OPT_TIMED_MUTEXES,
1720
1454
  OPT_TABLE_LOCK_WAIT_TIMEOUT,
1721
1455
  OPT_PLUGIN_ADD,
 
1456
  OPT_PLUGIN_REMOVE,
1722
1457
  OPT_PLUGIN_LOAD,
1723
1458
  OPT_PLUGIN_DIR,
1724
1459
  OPT_PORT_OPEN_TIMEOUT,
1811
1546
   (char**) &global_system_variables.log_warnings,
1812
1547
   (char**) &max_system_variables.log_warnings, 0, GET_BOOL, OPT_ARG, 1, 0, 0,
1813
1548
   0, 0, 0},
1814
 
  {"memlock", OPT_MEMLOCK,
1815
 
   N_("Lock drizzled in memory."),
1816
 
   (char**) &locked_in_memory,
1817
 
   (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1818
1549
  {"pid-file", OPT_PID_FILE,
1819
1550
   N_("Pid file used by safe_mysqld."),
1820
1551
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
1840
1571
   0, 0, 0, 0},
1841
1572
  {"symbolic-links", 's',
1842
1573
   N_("Enable symbolic link support."),
1843
 
   (char**) &my_use_symdir, (char**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
 
1574
   (char**) &internal::my_use_symdir, (char**) &internal::my_use_symdir, 0, GET_BOOL, NO_ARG,
1844
1575
   /*
1845
1576
     The system call realpath() produces warnings under valgrind and
1846
1577
     purify. These are not suppressed: instead we disable symlinks
1850
1581
  {"timed_mutexes", OPT_TIMED_MUTEXES,
1851
1582
   N_("Specify whether to time mutexes (only InnoDB mutexes are currently "
1852
1583
      "supported)"),
1853
 
   (char**) &timed_mutexes, (char**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
 
1584
   (char**) &internal::timed_mutexes, (char**) &internal::timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
1854
1585
    0, 0, 0, 0, 0},
1855
1586
  {"tmpdir", 't',
1856
1587
   N_("Path for temporary files."),
1981
1712
      "[for example: --plugin_add=crc32,logger_gearman]"),
1982
1713
   (char**) &opt_plugin_add, (char**) &opt_plugin_add, 0,
1983
1714
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1715
  {"plugin_remove", OPT_PLUGIN_ADD,
 
1716
   N_("Optional comma separated list of plugins to not load at startup. Effectively "
 
1717
      "removes a plugin from the list of plugins to be loaded. "
 
1718
      "[for example: --plugin_remove=crc32,logger_gearman]"),
 
1719
   (char**) &opt_plugin_remove, (char**) &opt_plugin_remove, 0,
 
1720
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1984
1721
  {"plugin_load", OPT_PLUGIN_LOAD,
1985
1722
   N_("Optional comma separated list of plugins to load at starup instead of "
1986
1723
      "the default plugin load list. "
2061
1798
   (char**) &global_system_variables.tmp_table_size,
2062
1799
   (char**) &max_system_variables.tmp_table_size, 0, GET_ULL,
2063
1800
   REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
2064
 
  {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
2065
 
   N_("Allocation block size for transactions to be stored in binary log"),
2066
 
   (char**) &global_system_variables.trans_alloc_block_size,
2067
 
   (char**) &max_system_variables.trans_alloc_block_size, 0, GET_UINT,
2068
 
   REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
2069
 
  {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
2070
 
   N_("Persistent buffer for transactions to be stored in binary log"),
2071
 
   (char**) &global_system_variables.trans_prealloc_size,
2072
 
   (char**) &max_system_variables.trans_prealloc_size, 0, GET_UINT,
2073
 
   REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
2074
1801
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
2075
1802
};
2076
1803
 
2080
1807
    Note: the instance manager keys off the string 'Ver' so it can find the
2081
1808
    version from the output of 'drizzled --version', so don't change it!
2082
1809
  */
2083
 
  printf("%s  Ver %s for %s-%s on %s (%s)\n",my_progname,
 
1810
  printf("%s  Ver %s for %s-%s on %s (%s)\n",internal::my_progname,
2084
1811
         PANDORA_RELEASE_VERSION, HOST_VENDOR, HOST_OS, HOST_CPU,
2085
1812
         COMPILATION_COMMENT);
2086
1813
}
2099
1826
         "license\n\n"
2100
1827
         "Starts the Drizzle database server\n"));
2101
1828
 
2102
 
  printf(_("Usage: %s [OPTIONS]\n"), my_progname);
 
1829
  printf(_("Usage: %s [OPTIONS]\n"), internal::my_progname);
2103
1830
  {
2104
 
     print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
 
1831
     internal::print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
2105
1832
     puts("");
2106
1833
 
2107
1834
     /* Print out all the options including plugin supplied options */
2201
1928
}
2202
1929
 
2203
1930
 
2204
 
extern "C" bool
2205
 
drizzled_get_one_option(int optid, const struct my_option *opt,
2206
 
                        char *argument)
 
1931
bool drizzled_get_one_option(int optid, const struct my_option *opt,
 
1932
                             char *argument)
2207
1933
{
2208
1934
  switch(optid) {
2209
1935
  case 'a':
2257
1983
    test_flags.set(TEST_NO_STACKTRACE);
2258
1984
    break;
2259
1985
  case (int) OPT_SKIP_SYMLINKS:
2260
 
    my_use_symdir=0;
 
1986
    internal::my_use_symdir=0;
2261
1987
    break;
2262
1988
  case (int) OPT_BIND_ADDRESS:
2263
1989
    {
2304
2030
  return 0;
2305
2031
}
2306
2032
 
2307
 
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
2308
 
 
2309
 
extern "C" void option_error_reporter(enum loglevel level, const char *format, ...)
 
2033
static void option_error_reporter(enum loglevel level, const char *format, ...)
2310
2034
{
2311
2035
  va_list args;
2312
2036
  va_start(args, format);
2342
2066
             /* no need to do this for argv as we are discarding it. */
2343
2067
 
2344
2068
#if defined(HAVE_BROKEN_REALPATH)
2345
 
  my_use_symdir=0;
2346
 
  my_disable_symlinks=1;
 
2069
  internal::my_use_symdir=0;
 
2070
  internal::my_disable_symlinks=1;
2347
2071
  have_symlink=SHOW_OPTION_NO;
2348
2072
#else
2349
 
  if (!my_use_symdir)
 
2073
  if (!internal::my_use_symdir)
2350
2074
  {
2351
 
    my_disable_symlinks=1;
 
2075
    internal::my_disable_symlinks=1;
2352
2076
    have_symlink=SHOW_OPTION_DISABLED;
2353
2077
  }
2354
2078
#endif
2368
2092
    Set some global variables from the global_system_variables
2369
2093
    In most cases the global variables will not be used
2370
2094
  */
2371
 
  my_default_record_cache_size=global_system_variables.read_buff_size;
 
2095
  internal::my_default_record_cache_size=global_system_variables.read_buff_size;
2372
2096
}
2373
2097
 
2374
2098
 
2375
2099
static const char *get_relative_path(const char *path)
2376
2100
{
2377
 
  if (test_if_hard_path(path) &&
 
2101
  if (internal::test_if_hard_path(path) &&
2378
2102
      (strncmp(path, PREFIX, strlen(PREFIX)) == 0) &&
2379
2103
      strcmp(PREFIX,FN_ROOTDIR))
2380
2104
  {
2390
2114
static void fix_paths(string &progname)
2391
2115
{
2392
2116
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
2393
 
  convert_dirname(drizzle_home,drizzle_home,NULL);
 
2117
  internal::convert_dirname(drizzle_home,drizzle_home,NULL);
2394
2118
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
2395
2119
#if defined(HAVE_BROKEN_REALPATH)
2396
 
   my_load_path(drizzle_home, drizzle_home, NULL);
 
2120
   internal::my_load_path(drizzle_home, drizzle_home, NULL);
2397
2121
#else
2398
2122
  if (!realpath(drizzle_home,rp_buff))
2399
 
    my_load_path(rp_buff, drizzle_home, NULL);
 
2123
    internal::my_load_path(rp_buff, drizzle_home, NULL);
2400
2124
  rp_buff[FN_REFLEN-1]= '\0';
2401
2125
  strcpy(drizzle_home,rp_buff);
2402
2126
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
2407
2131
    pos[0]= FN_LIBCHAR;
2408
2132
    pos[1]= 0;
2409
2133
  }
2410
 
  convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
2411
 
  (void) fn_format(buff, drizzle_real_data_home, "", "",
 
2134
  internal::convert_dirname(drizzle_real_data_home,drizzle_real_data_home,NULL);
 
2135
  (void) internal::fn_format(buff, drizzle_real_data_home, "", "",
2412
2136
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
2413
 
  (void) unpack_dirname(drizzle_unpacked_real_data_home, buff);
2414
 
  convert_dirname(language,language,NULL);
2415
 
  (void) my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
2416
 
  (void) my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
2417
 
  (void) my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
 
2137
  (void) internal::unpack_dirname(drizzle_unpacked_real_data_home, buff);
 
2138
  internal::convert_dirname(language,language,NULL);
 
2139
  (void) internal::my_load_path(drizzle_home, drizzle_home,""); // Resolve current dir
 
2140
  (void) internal::my_load_path(drizzle_real_data_home, drizzle_real_data_home,drizzle_home);
 
2141
  (void) internal::my_load_path(pidfile_name, pidfile_name,drizzle_real_data_home);
2418
2142
 
2419
2143
  if (opt_plugin_dir_ptr == NULL)
2420
2144
  {
2449
2173
      /* drizzled.o doesn't exist - we are not in a source dir.
2450
2174
       * Go on as usual
2451
2175
       */
2452
 
      (void) my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
 
2176
      (void) internal::my_load_path(opt_plugin_dir, get_relative_path(PKGPLUGINDIR),
2453
2177
                                          drizzle_home);
2454
2178
    }
2455
2179
    else
2458
2182
      size_t last_libchar_pos= progdir.rfind(FN_LIBCHAR,progdir.size()-2)+1;
2459
2183
      string source_plugindir(progdir.substr(0,last_libchar_pos));
2460
2184
      source_plugindir.append("plugin/.libs");
2461
 
      (void) my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
 
2185
      (void) internal::my_load_path(opt_plugin_dir, source_plugindir.c_str(), "");
2462
2186
    }
2463
2187
  }
2464
2188
  else
2465
2189
  {
2466
 
    (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
 
2190
    (void) internal::my_load_path(opt_plugin_dir, opt_plugin_dir_ptr, drizzle_home);
2467
2191
  }
2468
2192
  opt_plugin_dir_ptr= opt_plugin_dir;
2469
2193
 
2470
2194
  const char *sharedir= get_relative_path(PKGDATADIR);
2471
 
  if (test_if_hard_path(sharedir))
 
2195
  if (internal::test_if_hard_path(sharedir))
2472
2196
    strncpy(buff,sharedir,sizeof(buff)-1);
2473
2197
  else
2474
2198
  {
2475
2199
    strcpy(buff, drizzle_home);
2476
2200
    strncat(buff, sharedir, sizeof(buff)-strlen(drizzle_home)-1);
2477
2201
  }
2478
 
  convert_dirname(buff,buff,NULL);
2479
 
  (void) my_load_path(language,language,buff);
 
2202
  internal::convert_dirname(buff,buff,NULL);
 
2203
  (void) internal::my_load_path(language,language,buff);
2480
2204
 
2481
2205
  {
2482
2206
    char *tmp_string;
2505
2229
   */
2506
2230
  if (opt_secure_file_priv)
2507
2231
  {
2508
 
    convert_dirname(buff, opt_secure_file_priv, NULL);
 
2232
    internal::convert_dirname(buff, opt_secure_file_priv, NULL);
2509
2233
    free(opt_secure_file_priv);
2510
2234
    opt_secure_file_priv= strdup(buff);
2511
2235
    if (opt_secure_file_priv == NULL)
2513
2237
  }
2514
2238
}
2515
2239
 
 
2240
} /* namespace drizzled */
 
2241
 
 
2242
using namespace drizzled;
 
2243
 
 
2244
 
 
2245
static void init_signals(void)
 
2246
{
 
2247
  sigset_t set;
 
2248
  struct sigaction sa;
 
2249
 
 
2250
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
 
2251
        test_flags.test(TEST_CORE_ON_SIGNAL)))
 
2252
  {
 
2253
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
 
2254
    sigemptyset(&sa.sa_mask);
 
2255
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
 
2256
 
 
2257
    init_stacktrace();
 
2258
    sa.sa_handler=handle_segfault;
 
2259
    sigaction(SIGSEGV, &sa, NULL);
 
2260
    sigaction(SIGABRT, &sa, NULL);
 
2261
#ifdef SIGBUS
 
2262
    sigaction(SIGBUS, &sa, NULL);
 
2263
#endif
 
2264
    sigaction(SIGILL, &sa, NULL);
 
2265
    sigaction(SIGFPE, &sa, NULL);
 
2266
  }
 
2267
 
 
2268
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
2269
  {
 
2270
    /* Change limits so that we will get a core file */
 
2271
    struct rlimit rl;
 
2272
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
 
2273
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
 
2274
        errmsg_printf(ERRMSG_LVL_WARN,
 
2275
                      _("setrlimit could not change the size of core files "
 
2276
                        "to 'infinity';  We may not be able to generate a "
 
2277
                        "core file on signals"));
 
2278
  }
 
2279
  (void) sigemptyset(&set);
 
2280
  my_sigset(SIGPIPE,SIG_IGN);
 
2281
  sigaddset(&set,SIGPIPE);
 
2282
#ifndef IGNORE_SIGHUP_SIGQUIT
 
2283
  sigaddset(&set,SIGQUIT);
 
2284
  sigaddset(&set,SIGHUP);
 
2285
#endif
 
2286
  sigaddset(&set,SIGTERM);
 
2287
 
 
2288
  /* Fix signals if blocked by parents (can happen on Mac OS X) */
 
2289
  sigemptyset(&sa.sa_mask);
 
2290
  sa.sa_flags = 0;
 
2291
  sa.sa_handler = print_signal_warning;
 
2292
  sigaction(SIGTERM, &sa, (struct sigaction*) 0);
 
2293
  sa.sa_flags = 0;
 
2294
  sa.sa_handler = print_signal_warning;
 
2295
  sigaction(SIGHUP, &sa, (struct sigaction*) 0);
 
2296
#ifdef SIGTSTP
 
2297
  sigaddset(&set,SIGTSTP);
 
2298
#endif
 
2299
  if (test_flags.test(TEST_SIGINT))
 
2300
  {
 
2301
    my_sigset(thr_kill_signal, end_thread_signal);
 
2302
    // May be SIGINT
 
2303
    sigdelset(&set, thr_kill_signal);
 
2304
  }
 
2305
  else
 
2306
    sigaddset(&set,SIGINT);
 
2307
  sigprocmask(SIG_SETMASK,&set,NULL);
 
2308
  pthread_sigmask(SIG_SETMASK,&set,NULL);
 
2309
  return;;
 
2310
}
 
2311
 
 
2312
int main(int argc, char **argv)
 
2313
{
 
2314
#if defined(ENABLE_NLS)
 
2315
# if defined(HAVE_LOCALE_H)
 
2316
  setlocale(LC_ALL, "");
 
2317
# endif
 
2318
  bindtextdomain("drizzle", LOCALEDIR);
 
2319
  textdomain("drizzle");
 
2320
#endif
 
2321
 
 
2322
  plugin::Registry &plugins= plugin::Registry::singleton();
 
2323
  plugin::Client *client;
 
2324
  Session *session;
 
2325
 
 
2326
  MY_INIT(argv[0]);             // init my_sys library & pthreads
 
2327
  /* nothing should come before this line ^^^ */
 
2328
 
 
2329
  /* Set signal used to kill Drizzle */
 
2330
#if defined(SIGUSR2)
 
2331
  thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
 
2332
#else
 
2333
  thr_kill_signal= SIGINT;
 
2334
#endif
 
2335
 
 
2336
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
 
2337
                            argc, argv, load_default_groups))
 
2338
    unireg_abort(1);                            // Will do exit
 
2339
 
 
2340
  init_signals();
 
2341
 
 
2342
 
 
2343
  select_thread=pthread_self();
 
2344
  select_thread_in_use=1;
 
2345
 
 
2346
  if (chdir(drizzle_real_data_home) && !opt_help)
 
2347
  {
 
2348
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), drizzle_real_data_home);
 
2349
    unireg_abort(1);
 
2350
  }
 
2351
  drizzle_data_home= drizzle_data_home_buff;
 
2352
  drizzle_data_home[0]=FN_CURLIB;               // all paths are relative from here
 
2353
  drizzle_data_home[1]=0;
 
2354
  drizzle_data_home_len= 2;
 
2355
 
 
2356
  if ((user_info= check_user(drizzled_user)))
 
2357
  {
 
2358
    set_user(drizzled_user, user_info);
 
2359
  }
 
2360
 
 
2361
  if (server_id == 0)
 
2362
  {
 
2363
    server_id= 1;
 
2364
  }
 
2365
 
 
2366
  if (init_server_components(plugins))
 
2367
    unireg_abort(1);
 
2368
 
 
2369
  if (plugin::Listen::setup())
 
2370
    unireg_abort(1);
 
2371
 
 
2372
  /*
 
2373
    init signals & alarm
 
2374
    After this we can't quit by a simple unireg_abort
 
2375
  */
 
2376
  error_handler_hook= my_message_sql;
 
2377
 
 
2378
  if (drizzle_rm_tmp_tables() ||
 
2379
      my_tz_init((Session *)0, default_tz_name))
 
2380
  {
 
2381
    abort_loop= true;
 
2382
    select_thread_in_use=0;
 
2383
    (void) pthread_kill(signal_thread, SIGTERM);
 
2384
 
 
2385
    (void) unlink(pidfile_name);        // Not needed anymore
 
2386
 
 
2387
    exit(1);
 
2388
  }
 
2389
 
 
2390
  init_status_vars();
 
2391
 
 
2392
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
 
2393
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
 
2394
 
 
2395
 
 
2396
  /* Listen for new connections and start new session for each connection
 
2397
     accepted. The listen.getClient() method will return NULL when the server
 
2398
     should be shutdown. */
 
2399
  while ((client= plugin::Listen::getClient()) != NULL)
 
2400
  {
 
2401
    if (!(session= new Session(client)))
 
2402
    {
 
2403
      delete client;
 
2404
      continue;
 
2405
    }
 
2406
 
 
2407
    /* If we error on creation we drop the connection and delete the session. */
 
2408
    if (session->schedule())
 
2409
      Session::unlink(session);
 
2410
  }
 
2411
 
 
2412
  /* (void) pthread_attr_destroy(&connection_attrib); */
 
2413
 
 
2414
 
 
2415
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
2416
  select_thread_in_use=0;                       // For close_connections
 
2417
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
2418
  (void) pthread_cond_broadcast(&COND_thread_count);
 
2419
 
 
2420
  /* Wait until cleanup is done */
 
2421
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
2422
  while (!ready_to_exit)
 
2423
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
 
2424
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
2425
 
 
2426
  clean_up(1);
 
2427
  plugin::Registry::shutdown();
 
2428
  clean_up_mutexes();
 
2429
  internal::my_end();
 
2430
  return 0;
 
2431
}
 
2432