~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: Nathan Williams
  • Date: 2009-06-26 19:37:44 UTC
  • mfrom: (1076 staging)
  • mto: This revision was merged to the branch mainline in revision 1082.
  • Revision ID: nathanlws@gmail.com-20090626193744-i9zek83am2craqz6
Merged trunk, resolved conflict.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <drizzled/atomics.h>
24
24
 
25
25
#include <netdb.h>
26
 
#include <sys/poll.h>
27
26
#include <netinet/tcp.h>
28
27
#include <signal.h>
29
28
 
45
44
#include <drizzled/unireg.h>
46
45
#include <drizzled/scheduling.h>
47
46
#include "drizzled/temporal_format.h" /* For init_temporal_formats() */
 
47
#include <drizzled/listen.h>
48
48
 
49
49
#if TIME_WITH_SYS_TIME
50
50
# include <sys/time.h>
239
239
static char *default_collation_name;
240
240
static char *default_storage_engine_str;
241
241
static char compiled_default_collation_name[]= DRIZZLE_DEFAULT_COLLATION_NAME;
242
 
static struct pollfd fds[UINT8_MAX];
243
 
static uint8_t pollfd_count= 0;
244
242
 
245
243
/* Global variables */
246
244
 
248
246
bool opt_endinfo, using_udf_functions;
249
247
bool locked_in_memory;
250
248
bool volatile abort_loop;
251
 
int abort_pipe[2];
252
249
bool volatile shutdown_in_progress;
253
250
uint32_t max_used_connections;
254
251
const string opt_scheduler_default("multi_thread");
255
252
char *opt_scheduler= NULL;
256
253
 
257
 
const char *opt_protocol= "oldlibdrizzle";
258
 
 
259
254
size_t my_thread_stack_size= 65536;
260
255
 
261
256
/*
275
270
#ifdef HAVE_INITGROUPS
276
271
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
277
272
#endif
278
 
uint32_t drizzled_port, test_flags, select_errors, dropping_tables, ha_open_options;
 
273
 
 
274
/*
 
275
  This needs to be a uint32_t and not a in_port_t because the config system
 
276
  requires a 4-byte integer.
 
277
*/
 
278
uint32_t drizzled_tcp_port;
 
279
 
279
280
uint32_t drizzled_port_timeout;
280
 
uint32_t delay_key_write_options, protocol_version= PROTOCOL_VERSION;
 
281
uint32_t test_flags, dropping_tables, ha_open_options;
 
282
uint32_t delay_key_write_options;
281
283
uint32_t tc_heuristic_recover= 0;
282
284
uint64_t session_startup_options;
283
285
uint32_t back_log;
343
345
char server_version[SERVER_VERSION_LENGTH];
344
346
char *drizzle_tmpdir= NULL;
345
347
char *opt_drizzle_tmpdir= NULL;
346
 
const char *myisam_recover_options_str="OFF";
347
348
const char *myisam_stats_method_str="nulls_unequal";
348
349
 
349
350
/** name of reference on left espression in rewritten IN subquery */
388
389
pthread_t signal_thread;
389
390
pthread_cond_t  COND_server_end;
390
391
 
391
 
/* replication parameters, if master_host is not NULL, we are a slave */
392
 
uint32_t report_port= DRIZZLE_PORT;
393
 
uint32_t master_retry_count= 0;
394
 
char *master_info_file;
395
 
char *report_host;
396
 
char *opt_logname;
397
 
 
398
392
/* Static variables */
399
393
 
400
394
static bool segfaulted;
431
425
static int init_thread_environment();
432
426
static const char *get_relative_path(const char *path);
433
427
static void fix_paths(void);
434
 
void handle_connections_sockets();
435
428
extern "C" pthread_handler_t handle_slave(void *arg);
436
 
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib);
437
 
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
438
 
                                   const char *option);
439
429
static void clean_up(bool print_message);
440
430
 
441
431
static void usage(void);
442
432
static void clean_up_mutexes(void);
 
433
static void create_new_thread(Session *session);
443
434
 
444
435
/****************************************************************************
445
436
** Code to end drizzled
448
439
void close_connections(void)
449
440
{
450
441
  /* Abort listening to new connections */
451
 
  ssize_t ret= write(abort_pipe[1], "\0", 1);
452
 
  assert(ret);
 
442
  listen_abort();
453
443
 
454
444
  /* kill connection thread */
455
445
  (void) pthread_mutex_lock(&LOCK_thread_count);
631
621
}
632
622
 
633
623
 
634
 
/****************************************************************************
635
 
** Init IP and UNIX socket
636
 
****************************************************************************/
637
 
 
638
 
static void set_ports()
 
624
/**
 
625
 * Setup default port value from (in order or precedence):
 
626
 * - Command line option
 
627
 * - DRIZZLE_TCP_PORT environment variable
 
628
 * - Compile options
 
629
 * - Lookup in /etc/services
 
630
 * - Default value
 
631
 */
 
632
static void set_default_port()
639
633
{
640
 
  char  *env;
641
 
  if (!drizzled_port)
642
 
  {                                     // Get port if not from commandline
643
 
    drizzled_port= DRIZZLE_PORT;
644
 
 
645
 
    /*
646
 
      if builder specifically requested a default port, use that
647
 
      (even if it coincides with our factory default).
648
 
      only if they didn't do we check /etc/services (and, failing
649
 
      on that, fall back to the factory default of 4427).
650
 
      either default can be overridden by the environment variable
651
 
      DRIZZLE_TCP_PORT, which in turn can be overridden with command
652
 
      line options.
653
 
    */
654
 
 
655
 
    struct  servent *serv_ptr;
656
 
    if ((serv_ptr= getservbyname("drizzle", "tcp")))
657
 
      drizzled_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
 
634
  struct servent *serv_ptr;
 
635
  char *env;
 
636
 
 
637
  if (drizzled_tcp_port == 0)
 
638
  {
 
639
    drizzled_tcp_port= DRIZZLE_TCP_PORT;
 
640
 
 
641
    if (DRIZZLE_TCP_PORT_DEFAULT == 0)
 
642
    {
 
643
      if ((serv_ptr= getservbyname("drizzle", "tcp")))
 
644
        drizzled_tcp_port= ntohs((u_short) serv_ptr->s_port);
 
645
    }
658
646
 
659
647
    if ((env = getenv("DRIZZLE_TCP_PORT")))
660
 
      drizzled_port= (uint32_t) atoi(env);              /* purecov: inspected */
 
648
      drizzled_tcp_port= (uint32_t) atoi(env);
661
649
 
662
 
    assert(drizzled_port);
 
650
    assert(drizzled_tcp_port != 0);
663
651
  }
664
652
}
665
653
 
785
773
}
786
774
 
787
775
 
788
 
static void network_init(void)
789
 
{
790
 
  int   ret;
791
 
  uint32_t  waited;
792
 
  uint32_t  this_wait;
793
 
  uint32_t  retry;
794
 
  char port_buf[NI_MAXSERV];
795
 
  struct addrinfo *ai;
796
 
  struct addrinfo *next;
797
 
  struct addrinfo hints;
798
 
  int error;
799
 
  int ip_sock= -1;
800
 
 
801
 
  set_ports();
802
 
 
803
 
  memset(fds, 0, sizeof(struct pollfd) * UINT8_MAX);
804
 
  memset(&hints, 0, sizeof (hints));
805
 
  hints.ai_flags= AI_PASSIVE;
806
 
  hints.ai_socktype= SOCK_STREAM;
807
 
 
808
 
  snprintf(port_buf, NI_MAXSERV, "%d", drizzled_port);
809
 
  error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
810
 
  if (error != 0)
811
 
  {
812
 
    sql_perror(ER(ER_IPSOCK_ERROR));            /* purecov: tested */
813
 
    unireg_abort(1);                            /* purecov: tested */
814
 
  }
815
 
 
816
 
  for (next= ai, pollfd_count= 0; next; next= next->ai_next)
817
 
  {
818
 
    ip_sock= socket(next->ai_family, next->ai_socktype, next->ai_protocol);
819
 
    if (ip_sock == -1)
820
 
    {
821
 
      /* getaddrinfo can return bad results, skip them here and error later if
822
 
         we didn't find anything to bind to. */
823
 
      continue;
824
 
    }
825
 
 
826
 
    fds[pollfd_count].fd= ip_sock;
827
 
    fds[pollfd_count].events= POLLIN | POLLERR;
828
 
    pollfd_count++;
829
 
 
830
 
    /* Add options for our listening socket */
831
 
    {
832
 
      struct linger ling = {0, 0};
833
 
      int flags =1;
834
 
 
835
 
#ifdef IPV6_V6ONLY
836
 
      if (next->ai_family == AF_INET6)
837
 
      {
838
 
        error= setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
839
 
        if (error != 0)
840
 
        {
841
 
          perror("setsockopt");
842
 
          assert(error == 0);
843
 
        }
844
 
      }
845
 
#endif
846
 
      error= setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof(flags));
847
 
      if (error != 0)
848
 
      {
849
 
        perror("setsockopt");
850
 
        assert(error == 0);
851
 
      }
852
 
      error= setsockopt(ip_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
853
 
      if (error != 0)
854
 
      {
855
 
        perror("setsockopt");
856
 
        assert(error == 0);
857
 
      }
858
 
      error= setsockopt(ip_sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
859
 
      if (error != 0)
860
 
      {
861
 
        perror("setsockopt");
862
 
        assert(error == 0);
863
 
      }
864
 
      error= setsockopt(ip_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
865
 
      if (error != 0)
866
 
      {
867
 
        perror("setsockopt");
868
 
        assert(error == 0);
869
 
      }
870
 
    }
871
 
 
872
 
 
873
 
    /*
874
 
      Sometimes the port is not released fast enough when stopping and
875
 
      restarting the server. This happens quite often with the test suite
876
 
      on busy Linux systems. Retry to bind the address at these intervals:
877
 
      Sleep intervals: 1, 2, 4,  6,  9, 13, 17, 22, ...
878
 
      Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
879
 
      Limit the sequence by drizzled_port_timeout (set --port-open-timeout=#).
880
 
    */
881
 
    for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
882
 
    {
883
 
      if (((ret= ::bind(ip_sock, next->ai_addr, next->ai_addrlen)) >= 0 ) ||
884
 
          (errno != EADDRINUSE) ||
885
 
          (waited >= drizzled_port_timeout))
886
 
        break;
887
 
          errmsg_printf(ERRMSG_LVL_INFO, _("Retrying bind on TCP/IP port %u"), drizzled_port);
888
 
      this_wait= retry * retry / 3 + 1;
889
 
      sleep(this_wait);
890
 
    }
891
 
    if (ret < 0)
892
 
    {
893
 
      sql_perror(_("Can't start server: Bind on TCP/IP port"));
894
 
          errmsg_printf(ERRMSG_LVL_ERROR, _("Do you already have another drizzled server running "
895
 
                        "on port: %d ?"),drizzled_port);
896
 
      unireg_abort(1);
897
 
    }
898
 
    if (listen(ip_sock,(int) back_log) < 0)
899
 
    {
900
 
      sql_perror(_("Can't start server: listen() on TCP/IP port"));
901
 
          errmsg_printf(ERRMSG_LVL_ERROR, _("listen() on TCP/IP failed with error %d"),
902
 
                      errno);
903
 
      unireg_abort(1);
904
 
    }
905
 
  }
906
 
 
907
 
  if (pollfd_count == 0 && ai != NULL)
908
 
  {
909
 
    sql_perror(ER(ER_IPSOCK_ERROR));            /* purecov: tested */
910
 
    unireg_abort(1);                            /* purecov: tested */
911
 
  }
912
 
 
913
 
  freeaddrinfo(ai);
914
 
 
915
 
  /* We need a pipe to wakeup the listening thread since some operating systems
916
 
     are stupid. *cough* OSX *cough* */
917
 
  if (pipe(abort_pipe) == -1)
918
 
  {
919
 
    sql_perror(_("Can't open abort pipet"));
920
 
    errmsg_printf(ERRMSG_LVL_ERROR,
921
 
                  _("pipe() on abort_pipe failed with error %d"), errno);
922
 
    unireg_abort(1);
923
 
  }
924
 
 
925
 
  fds[pollfd_count].fd= abort_pipe[0];
926
 
  fds[pollfd_count].events= POLLIN | POLLERR;
927
 
  pollfd_count++; 
928
 
 
929
 
  return;
930
 
}
931
 
 
932
 
 
933
 
 
934
776
/** Called when a thread is aborted. */
935
777
/* ARGSUSED */
936
778
extern "C" void end_thread_signal(int )
1692
1534
 
1693
1535
int main(int argc, char **argv)
1694
1536
{
 
1537
  ListenHandler listen_handler;
 
1538
  Protocol *protocol;
 
1539
  Session *session;
 
1540
 
 
1541
 
1695
1542
#if defined(ENABLE_NLS)
1696
1543
# if defined(HAVE_LOCALE_H)
1697
1544
  setlocale(LC_ALL, "");
1780
1627
  if (init_server_components())
1781
1628
    unireg_abort(1);
1782
1629
 
1783
 
  network_init();
 
1630
  set_default_port();
 
1631
 
 
1632
  if (listen_handler.bindAll(my_bind_addr_str, drizzled_port_timeout))
 
1633
    unireg_abort(1);
1784
1634
 
1785
1635
  /*
1786
1636
    init signals & alarm
1788
1638
  */
1789
1639
  error_handler_hook= my_message_sql;
1790
1640
 
1791
 
  if (drizzle_rm_tmp_tables() || my_tz_init((Session *)0, default_tz_name))
 
1641
  if (drizzle_rm_tmp_tables(listen_handler) ||
 
1642
      my_tz_init((Session *)0, default_tz_name))
1792
1643
  {
1793
1644
    abort_loop= true;
1794
1645
    select_thread_in_use=0;
1801
1652
 
1802
1653
  init_status_vars();
1803
1654
 
1804
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
1805
 
                        "", drizzled_port, COMPILATION_COMMENT);
1806
 
 
1807
 
 
1808
 
  handle_connections_sockets();
 
1655
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), my_progname, server_version,
 
1656
                COMPILATION_COMMENT);
 
1657
 
 
1658
 
 
1659
  /* Listen for new connections and start new session for each connection
 
1660
     accepted. The listen.getProtocol() method will return NULL when the server
 
1661
     should be shutdown. */
 
1662
  while ((protocol= listen_handler.getProtocol()) != NULL)
 
1663
  {
 
1664
    if (!(session= new Session(protocol)))
 
1665
    {
 
1666
      delete protocol;
 
1667
      continue;
 
1668
    }
 
1669
 
 
1670
    create_new_thread(session);
 
1671
  }
 
1672
 
1809
1673
  /* (void) pthread_attr_destroy(&connection_attrib); */
1810
1674
 
1811
1675
 
1878
1742
}
1879
1743
 
1880
1744
 
1881
 
        /* Handle new connections and spawn new process to handle them */
1882
 
 
1883
 
void handle_connections_sockets()
1884
 
{
1885
 
  int x;
1886
 
  int sock,new_sock;
1887
 
  uint32_t error_count=0;
1888
 
  Session *session;
1889
 
  struct sockaddr_storage cAddr;
1890
 
  Protocol *protocol;
1891
 
 
1892
 
  while (!abort_loop)
1893
 
  {
1894
 
    int number_of;
1895
 
 
1896
 
    if ((number_of= poll(fds, pollfd_count, -1)) == -1)
1897
 
    {
1898
 
      if (errno != EINTR)
1899
 
      {
1900
 
        if (!select_errors++ && !abort_loop)    /* purecov: inspected */
1901
 
                errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
1902
 
                          errno); /* purecov: inspected */
1903
 
      }
1904
 
      continue;
1905
 
    }
1906
 
    if (number_of == 0)
1907
 
      continue;
1908
 
 
1909
 
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
1910
 
    assert(number_of > 1); /* Not handling this at the moment */
1911
 
#endif
1912
 
 
1913
 
    if (abort_loop)
1914
 
    {
1915
 
      break;
1916
 
    }
1917
 
 
1918
 
    for (x= 0, sock= -1; x < pollfd_count; x++)
1919
 
    {
1920
 
      if (fds[x].revents == POLLIN)
1921
 
      {
1922
 
        sock= fds[x].fd;
1923
 
        break;
1924
 
      }
1925
 
    }
1926
 
    assert(sock != -1);
1927
 
 
1928
 
    for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
1929
 
    {
1930
 
      socklen_t length= sizeof(struct sockaddr_storage);
1931
 
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
1932
 
                       &length);
1933
 
      if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
1934
 
        break;
1935
 
    }
1936
 
 
1937
 
 
1938
 
    if (new_sock == -1)
1939
 
    {
1940
 
      if ((error_count++ & 255) == 0)           // This can happen often
1941
 
        sql_perror("Error in accept");
1942
 
      if (errno == ENFILE || errno == EMFILE)
1943
 
        sleep(1);                               // Give other threads some time
1944
 
      continue;
1945
 
    }
1946
 
 
1947
 
    {
1948
 
      socklen_t dummyLen;
1949
 
      struct sockaddr_storage dummy;
1950
 
      dummyLen = sizeof(dummy);
1951
 
      if (  getsockname(new_sock,(struct sockaddr *)&dummy,
1952
 
                        (socklen_t *)&dummyLen) < 0  )
1953
 
      {
1954
 
        sql_perror("Error on new connection socket");
1955
 
        (void) shutdown(new_sock, SHUT_RDWR);
1956
 
        (void) close(new_sock);
1957
 
        continue;
1958
 
      }
1959
 
      dummyLen = sizeof(dummy);
1960
 
      if ( getpeername(new_sock, (struct sockaddr *)&dummy,
1961
 
                       (socklen_t *)&dummyLen) < 0)
1962
 
      {
1963
 
        sql_perror("Error on new connection socket");
1964
 
        (void) shutdown(new_sock, SHUT_RDWR);
1965
 
        (void) close(new_sock);
1966
 
         continue;
1967
 
      }
1968
 
    }
1969
 
 
1970
 
    /*
1971
 
    ** Don't allow too many connections
1972
 
    */
1973
 
 
1974
 
    if (!(protocol= get_protocol()))
1975
 
    {
1976
 
      (void) shutdown(new_sock, SHUT_RDWR);
1977
 
      close(new_sock);
1978
 
      continue;
1979
 
    }
1980
 
 
1981
 
    if (!(session= new Session(protocol)))
1982
 
    {
1983
 
      delete protocol;
1984
 
      (void) shutdown(new_sock, SHUT_RDWR);
1985
 
      close(new_sock);
1986
 
      continue;
1987
 
    }
1988
 
 
1989
 
    if (protocol->setFileDescriptor(new_sock))
1990
 
    {
1991
 
      delete session;
1992
 
      continue;
1993
 
    }
1994
 
 
1995
 
    create_new_thread(session);
1996
 
  }
1997
 
 
1998
 
  for (x= 0; x < pollfd_count; x++)
1999
 
  {
2000
 
    if (fds[x].fd != -1)
2001
 
    {
2002
 
      (void) shutdown(fds[x].fd, SHUT_RDWR);
2003
 
      (void) close(fds[x].fd);
2004
 
      fds[x].fd= -1;
2005
 
    }
2006
 
  }
2007
 
 
2008
 
  /* abort_pipe[0] was closed in the for loop above in fds[] */
2009
 
  (void) close(abort_pipe[1]);
2010
 
}
2011
 
 
2012
 
 
2013
1745
/****************************************************************************
2014
1746
  Handle start options
2015
1747
******************************************************************************/
2016
1748
 
2017
1749
enum options_drizzled
2018
1750
{
2019
 
  OPT_ISAM_LOG=256,
2020
 
  OPT_SOCKET,
 
1751
  OPT_SOCKET=256,
2021
1752
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
2022
1753
  OPT_STORAGE_ENGINE,          
2023
1754
  OPT_INIT_FILE,
2025
1756
  OPT_DELAY_KEY_WRITE,
2026
1757
  OPT_WANT_CORE,
2027
1758
  OPT_MEMLOCK,
2028
 
  OPT_MYISAM_RECOVER,
2029
1759
  OPT_SERVER_ID,
2030
1760
  OPT_TC_HEURISTIC_RECOVER,
2031
1761
  OPT_ENGINE_CONDITION_PUSHDOWN,
2081
1811
  OPT_PLUGIN_LOAD,
2082
1812
  OPT_PLUGIN_DIR,
2083
1813
  OPT_PORT_OPEN_TIMEOUT,
2084
 
  OPT_KEEP_FILES_ON_CREATE,
2085
1814
  OPT_SECURE_FILE_PRIV,
2086
1815
  OPT_MIN_EXAMINED_ROW_LIMIT,
2087
1816
  OPT_OPTIMIZER_USE_MRR
2186
1915
   (char**) &lc_time_names_name,
2187
1916
   (char**) &lc_time_names_name,
2188
1917
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2189
 
  {"log", 'l',
2190
 
   N_("Log connections and queries to file."),
2191
 
   (char**) &opt_logname,
2192
 
   (char**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2193
 
  {"log-isam", OPT_ISAM_LOG,
2194
 
   N_("Log all MyISAM changes to file."),
2195
 
   (char**) &myisam_log_filename, (char**) &myisam_log_filename, 0, GET_STR,
2196
 
   OPT_ARG, 0, 0, 0, 0, 0, 0},
2197
1918
  {"log-warnings", 'W',
2198
1919
   N_("Log some not critical warnings to the log file."),
2199
1920
   (char**) &global_system_variables.log_warnings,
2203
1924
   N_("Lock drizzled in memory."),
2204
1925
   (char**) &locked_in_memory,
2205
1926
   (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
2206
 
  {"myisam-recover", OPT_MYISAM_RECOVER,
2207
 
   N_("Syntax: myisam-recover[=option[,option...]], where option can be "
2208
 
      "DEFAULT, BACKUP, FORCE or QUICK."),
2209
 
   (char**) &myisam_recover_options_str, (char**) &myisam_recover_options_str, 0,
2210
 
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2211
1927
  {"pid-file", OPT_PID_FILE,
2212
1928
   N_("Pid file used by safe_mysqld."),
2213
1929
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
2215
1931
  {"port", 'P',
2216
1932
   N_("Port number to use for connection or 0 for default to, in "
2217
1933
      "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
2218
 
      "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
2219
 
   (char**) &drizzled_port,
2220
 
   (char**) &drizzled_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1934
      "built-in default (" STRINGIFY_ARG(DRIZZLE_TCP_PORT) ")."),
 
1935
   (char**) &drizzled_tcp_port,
 
1936
   (char**) &drizzled_tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2221
1937
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
2222
1938
   N_("Maximum time in seconds to wait for the port to become free. "
2223
1939
      "(Default: no wait)"),
2301
2017
   (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
2302
2018
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
2303
2019
   MALLOC_OVERHEAD, IO_SIZE, 0},
2304
 
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
2305
 
   N_("Don't overwrite stale .MYD and .MYI even if no directory is specified."),
2306
 
   (char**) &global_system_variables.keep_files_on_create,
2307
 
   (char**) &max_system_variables.keep_files_on_create,
2308
 
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
2309
2020
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
2310
2021
   N_("The size of the buffer used for index blocks for MyISAM tables. "
2311
2022
      "Increase this to get better index handling (for all reads and multiple "
2380
2091
   (char**) &global_system_variables.max_sort_length,
2381
2092
   (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
2382
2093
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
2383
 
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
2384
 
   N_("Maximum number of temporary tables a client can keep open at a time."),
2385
 
   (char**) &global_system_variables.max_tmp_tables,
2386
 
   (char**) &max_system_variables.max_tmp_tables, 0, GET_UINT64,
2387
 
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
2388
2094
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
2389
2095
   N_("After this many write locks, allow some read locks to run in between."),
2390
2096
   (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
2464
2170
   (char**) &global_system_variables.preload_buff_size,
2465
2171
   (char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
2466
2172
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
2467
 
  {"protocol", OPT_PROTOCOL,
2468
 
   N_("Select protocol to be used (by default oldlibdrizzle)."),
2469
 
   (char**) &opt_protocol, (char**) &opt_protocol, 0,
2470
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2471
2173
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
2472
2174
   N_("Allocation block size for query parsing and execution"),
2473
2175
   (char**) &global_system_variables.query_alloc_block_size,
2694
2396
#ifdef FOO
2695
2397
  print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
2696
2398
  puts("");
2697
 
  set_ports();
 
2399
  set_default_port();
2698
2400
#endif
2699
2401
 
2700
2402
  /* Print out all the options including plugin supplied options */
2726
2428
{
2727
2429
  /* Things reset to zero */
2728
2430
  drizzle_home[0]= pidfile_name[0]= 0;
2729
 
  opt_logname= 0;
2730
2431
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
2731
2432
  opt_secure_file_priv= 0;
2732
2433
  segfaulted= 0;
2734
2435
  defaults_argc= 0;
2735
2436
  defaults_argv= 0;
2736
2437
  server_id_supplied= 0;
2737
 
  test_flags= select_errors= dropping_tables= ha_open_options=0;
 
2438
  test_flags= dropping_tables= ha_open_options=0;
2738
2439
  wake_thread=0;
2739
2440
  opt_endinfo= using_udf_functions= 0;
2740
2441
  abort_loop= select_thread_in_use= false;
2762
2463
  refresh_version= 1L;  /* Increments on each reload */
2763
2464
  thread_id= 1;
2764
2465
  strcpy(server_version, VERSION);
2765
 
  myisam_recover_options_str= "OFF";
2766
2466
  myisam_stats_method_str= "nulls_unequal";
2767
2467
  session_list.clear();
2768
2468
  key_caches.empty();
2933
2633
      global_system_variables.optimizer_use_mrr= (type-1);
2934
2634
      break;
2935
2635
    }
2936
 
  case OPT_MYISAM_RECOVER:
2937
 
    {
2938
 
      if (!argument)
2939
 
      {
2940
 
        myisam_recover_options=    HA_RECOVER_DEFAULT;
2941
 
        myisam_recover_options_str= myisam_recover_typelib.type_names[0];
2942
 
      }
2943
 
      else if (!argument[0])
2944
 
      {
2945
 
        myisam_recover_options= HA_RECOVER_NONE;
2946
 
        myisam_recover_options_str= "OFF";
2947
 
      }
2948
 
      else
2949
 
      {
2950
 
        myisam_recover_options_str=argument;
2951
 
        myisam_recover_options=
2952
 
          find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
2953
 
      }
2954
 
      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
2955
 
      break;
2956
 
    }
2957
2636
  case OPT_TC_HEURISTIC_RECOVER:
2958
2637
    tc_heuristic_recover= find_type_or_exit(argument,
2959
2638
                                            &tc_heuristic_recover_typelib,
3127
2806
 
3128
2807
static void fix_paths(void)
3129
2808
{
3130
 
  char buff[FN_REFLEN],*pos;
 
2809
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
3131
2810
  convert_dirname(drizzle_home,drizzle_home,NULL);
3132
2811
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
3133
 
  my_realpath(drizzle_home,drizzle_home,MYF(0));
 
2812
#if defined(HAVE_BROKEN_REALPATH)
 
2813
   my_load_path(drizzle_home, drizzle_home, NULL);
 
2814
#else
 
2815
  if (!realpath(drizzle_home,rp_buff))
 
2816
    my_load_path(rp_buff, drizzle_home, NULL);
 
2817
  rp_buff[FN_REFLEN-1]= '\0';
 
2818
  strcpy(drizzle_home,rp_buff);
3134
2819
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
3135
2820
  pos= strchr(drizzle_home, '\0');
 
2821
#endif
3136
2822
  if (pos[-1] != FN_LIBCHAR)
3137
2823
  {
3138
2824
    pos[0]= FN_LIBCHAR;
3197
2883
  }
3198
2884
}
3199
2885
 
3200
 
 
3201
 
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
3202
 
                                      const char *option)
3203
 
{
3204
 
  uint32_t res;
3205
 
 
3206
 
  const char **ptr;
3207
 
 
3208
 
  if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
3209
 
  {
3210
 
    ptr= bit_lib->type_names;
3211
 
    if (!*x)
3212
 
      fprintf(stderr, _("No option given to %s\n"), option);
3213
 
    else
3214
 
      fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
3215
 
              option, x);
3216
 
    fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
3217
 
    while (*++ptr)
3218
 
      fprintf(stderr, ",'%s'", *ptr);
3219
 
    fprintf(stderr, "\n");
3220
 
    exit(1);
3221
 
  }
3222
 
  return res;
3223
 
}
3224
 
 
3225
 
 
3226
 
/**
3227
 
  @return
3228
 
    a bitfield from a string of substrings separated by ','
3229
 
    or
3230
 
    ~(uint32_t) 0 on error.
3231
 
*/
3232
 
 
3233
 
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
3234
 
{
3235
 
  bool found_end;
3236
 
  int  found_count;
3237
 
  const char *end,*i,*j;
3238
 
  const char **array, *pos;
3239
 
  uint32_t found,found_int,bit;
3240
 
 
3241
 
  found=0;
3242
 
  found_end= 0;
3243
 
  pos=(char *) x;
3244
 
  while (*pos == ' ') pos++;
3245
 
  found_end= *pos == 0;
3246
 
  while (!found_end)
3247
 
  {
3248
 
    if ((end=strrchr(pos,',')) != NULL)         /* Let end point at fieldend */
3249
 
    {
3250
 
      while (end > pos && end[-1] == ' ')
3251
 
        end--;                                  /* Skip end-space */
3252
 
      found_end=1;
3253
 
    }
3254
 
    else
3255
 
    {
3256
 
        end=pos+strlen(pos);
3257
 
        found_end=1;
3258
 
    }
3259
 
    found_int=0; found_count=0;
3260
 
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
3261
 
    {
3262
 
      j=pos;
3263
 
      while (j != end)
3264
 
      {
3265
 
        if (my_toupper(mysqld_charset,*i++) !=
3266
 
            my_toupper(mysqld_charset,*j++))
3267
 
          goto skip;
3268
 
      }
3269
 
      found_int=bit;
3270
 
      if (! *i)
3271
 
      {
3272
 
        found_count=1;
3273
 
        break;
3274
 
      }
3275
 
      else if (j != pos)                        // Half field found
3276
 
      {
3277
 
        found_count++;                          // Could be one of two values
3278
 
      }
3279
 
skip: ;
3280
 
    }
3281
 
    if (found_count != 1)
3282
 
      return(~(uint32_t) 0);                            // No unique value
3283
 
    found|=found_int;
3284
 
    pos=end+1;
3285
 
  }
3286
 
 
3287
 
  return(found);
3288
 
} /* find_bit_type */
3289
 
 
3290
2886
/*****************************************************************************
3291
2887
  Instantiate templates
3292
2888
*****************************************************************************/