~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Monty Taylor
  • Date: 2010-02-05 08:11:15 UTC
  • mfrom: (1283 build)
  • mto: (1273.13.43 fix_is)
  • mto: This revision was merged to the branch mainline in revision 1300.
  • Revision ID: mordred@inaugust.com-20100205081115-dr82nvrwv4lvw7sd
Merged trunk.

Show diffs side-by-side

added added

removed removed

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