~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/drizzled.cc

  • Committer: devananda
  • Date: 2009-06-30 14:27:54 UTC
  • mfrom: (1030.2.4 trunk)
  • mto: (1093.1.7 captain)
  • mto: This revision was merged to the branch mainline in revision 1095.
  • Revision ID: devananda.vdv@gmail.com-20090630142754-vm9w374yxkf1pikc
mergeĀ fromĀ lp

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 )
1330
1172
  {"optimize",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
1331
1173
  {"release_savepoint",    (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
1332
1174
  {"rename_table",         (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
1333
 
  {"repair",               (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
1334
1175
  {"replace",              (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
1335
1176
  {"replace_select",       (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
1336
1177
  {"rollback",             (char*) offsetof(STATUS_VAR, com_stat[(uint32_t) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
1693
1534
 
1694
1535
int main(int argc, char **argv)
1695
1536
{
 
1537
  ListenHandler listen_handler;
 
1538
  Protocol *protocol;
 
1539
  Session *session;
 
1540
 
 
1541
 
1696
1542
#if defined(ENABLE_NLS)
1697
1543
# if defined(HAVE_LOCALE_H)
1698
1544
  setlocale(LC_ALL, "");
1781
1627
  if (init_server_components())
1782
1628
    unireg_abort(1);
1783
1629
 
1784
 
  network_init();
 
1630
  set_default_port();
 
1631
 
 
1632
  if (listen_handler.bindAll(my_bind_addr_str, drizzled_port_timeout))
 
1633
    unireg_abort(1);
1785
1634
 
1786
1635
  /*
1787
1636
    init signals & alarm
1789
1638
  */
1790
1639
  error_handler_hook= my_message_sql;
1791
1640
 
1792
 
  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))
1793
1643
  {
1794
1644
    abort_loop= true;
1795
1645
    select_thread_in_use=0;
1802
1652
 
1803
1653
  init_status_vars();
1804
1654
 
1805
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
1806
 
                        "", drizzled_port, COMPILATION_COMMENT);
1807
 
 
1808
 
 
1809
 
  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
 
1810
1673
  /* (void) pthread_attr_destroy(&connection_attrib); */
1811
1674
 
1812
1675
 
1879
1742
}
1880
1743
 
1881
1744
 
1882
 
        /* Handle new connections and spawn new process to handle them */
1883
 
 
1884
 
void handle_connections_sockets()
1885
 
{
1886
 
  int x;
1887
 
  int sock,new_sock;
1888
 
  uint32_t error_count=0;
1889
 
  Session *session;
1890
 
  struct sockaddr_storage cAddr;
1891
 
  Protocol *protocol;
1892
 
 
1893
 
  while (!abort_loop)
1894
 
  {
1895
 
    int number_of;
1896
 
 
1897
 
    if ((number_of= poll(fds, pollfd_count, -1)) == -1)
1898
 
    {
1899
 
      if (errno != EINTR)
1900
 
      {
1901
 
        if (!select_errors++ && !abort_loop)    /* purecov: inspected */
1902
 
                errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
1903
 
                          errno); /* purecov: inspected */
1904
 
      }
1905
 
      continue;
1906
 
    }
1907
 
    if (number_of == 0)
1908
 
      continue;
1909
 
 
1910
 
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
1911
 
    assert(number_of > 1); /* Not handling this at the moment */
1912
 
#endif
1913
 
 
1914
 
    if (abort_loop)
1915
 
    {
1916
 
      break;
1917
 
    }
1918
 
 
1919
 
    for (x= 0, sock= -1; x < pollfd_count; x++)
1920
 
    {
1921
 
      if (fds[x].revents == POLLIN)
1922
 
      {
1923
 
        sock= fds[x].fd;
1924
 
        break;
1925
 
      }
1926
 
    }
1927
 
    assert(sock != -1);
1928
 
 
1929
 
    for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
1930
 
    {
1931
 
      socklen_t length= sizeof(struct sockaddr_storage);
1932
 
      new_sock= accept(sock, (struct sockaddr *)(&cAddr),
1933
 
                       &length);
1934
 
      if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
1935
 
        break;
1936
 
    }
1937
 
 
1938
 
 
1939
 
    if (new_sock == -1)
1940
 
    {
1941
 
      if ((error_count++ & 255) == 0)           // This can happen often
1942
 
        sql_perror("Error in accept");
1943
 
      if (errno == ENFILE || errno == EMFILE)
1944
 
        sleep(1);                               // Give other threads some time
1945
 
      continue;
1946
 
    }
1947
 
 
1948
 
    {
1949
 
      socklen_t dummyLen;
1950
 
      struct sockaddr_storage dummy;
1951
 
      dummyLen = sizeof(dummy);
1952
 
      if (  getsockname(new_sock,(struct sockaddr *)&dummy,
1953
 
                        (socklen_t *)&dummyLen) < 0  )
1954
 
      {
1955
 
        sql_perror("Error on new connection socket");
1956
 
        (void) shutdown(new_sock, SHUT_RDWR);
1957
 
        (void) close(new_sock);
1958
 
        continue;
1959
 
      }
1960
 
      dummyLen = sizeof(dummy);
1961
 
      if ( getpeername(new_sock, (struct sockaddr *)&dummy,
1962
 
                       (socklen_t *)&dummyLen) < 0)
1963
 
      {
1964
 
        sql_perror("Error on new connection socket");
1965
 
        (void) shutdown(new_sock, SHUT_RDWR);
1966
 
        (void) close(new_sock);
1967
 
         continue;
1968
 
      }
1969
 
    }
1970
 
 
1971
 
    /*
1972
 
    ** Don't allow too many connections
1973
 
    */
1974
 
 
1975
 
    if (!(protocol= get_protocol()))
1976
 
    {
1977
 
      (void) shutdown(new_sock, SHUT_RDWR);
1978
 
      close(new_sock);
1979
 
      continue;
1980
 
    }
1981
 
 
1982
 
    if (!(session= new Session(protocol)))
1983
 
    {
1984
 
      delete protocol;
1985
 
      (void) shutdown(new_sock, SHUT_RDWR);
1986
 
      close(new_sock);
1987
 
      continue;
1988
 
    }
1989
 
 
1990
 
    if (protocol->setFileDescriptor(new_sock))
1991
 
    {
1992
 
      delete session;
1993
 
      continue;
1994
 
    }
1995
 
 
1996
 
    create_new_thread(session);
1997
 
  }
1998
 
 
1999
 
  for (x= 0; x < pollfd_count; x++)
2000
 
  {
2001
 
    if (fds[x].fd != -1)
2002
 
    {
2003
 
      (void) shutdown(fds[x].fd, SHUT_RDWR);
2004
 
      (void) close(fds[x].fd);
2005
 
      fds[x].fd= -1;
2006
 
    }
2007
 
  }
2008
 
 
2009
 
  /* abort_pipe[0] was closed in the for loop above in fds[] */
2010
 
  (void) close(abort_pipe[1]);
2011
 
}
2012
 
 
2013
 
 
2014
1745
/****************************************************************************
2015
1746
  Handle start options
2016
1747
******************************************************************************/
2017
1748
 
2018
1749
enum options_drizzled
2019
1750
{
2020
 
  OPT_ISAM_LOG=256,
2021
 
  OPT_SOCKET,
 
1751
  OPT_SOCKET=256,
2022
1752
  OPT_BIND_ADDRESS,            OPT_PID_FILE,
2023
1753
  OPT_STORAGE_ENGINE,          
2024
1754
  OPT_INIT_FILE,
2026
1756
  OPT_DELAY_KEY_WRITE,
2027
1757
  OPT_WANT_CORE,
2028
1758
  OPT_MEMLOCK,
2029
 
  OPT_MYISAM_RECOVER,
2030
1759
  OPT_SERVER_ID,
2031
1760
  OPT_TC_HEURISTIC_RECOVER,
2032
1761
  OPT_ENGINE_CONDITION_PUSHDOWN,
2082
1811
  OPT_PLUGIN_LOAD,
2083
1812
  OPT_PLUGIN_DIR,
2084
1813
  OPT_PORT_OPEN_TIMEOUT,
2085
 
  OPT_KEEP_FILES_ON_CREATE,
2086
1814
  OPT_SECURE_FILE_PRIV,
2087
1815
  OPT_MIN_EXAMINED_ROW_LIMIT,
2088
1816
  OPT_OPTIMIZER_USE_MRR
2187
1915
   (char**) &lc_time_names_name,
2188
1916
   (char**) &lc_time_names_name,
2189
1917
   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
2190
 
  {"log", 'l',
2191
 
   N_("Log connections and queries to file."),
2192
 
   (char**) &opt_logname,
2193
 
   (char**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2194
 
  {"log-isam", OPT_ISAM_LOG,
2195
 
   N_("Log all MyISAM changes to file."),
2196
 
   (char**) &myisam_log_filename, (char**) &myisam_log_filename, 0, GET_STR,
2197
 
   OPT_ARG, 0, 0, 0, 0, 0, 0},
2198
1918
  {"log-warnings", 'W',
2199
1919
   N_("Log some not critical warnings to the log file."),
2200
1920
   (char**) &global_system_variables.log_warnings,
2204
1924
   N_("Lock drizzled in memory."),
2205
1925
   (char**) &locked_in_memory,
2206
1926
   (char**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
2207
 
  {"myisam-recover", OPT_MYISAM_RECOVER,
2208
 
   N_("Syntax: myisam-recover[=option[,option...]], where option can be "
2209
 
      "DEFAULT, BACKUP, FORCE or QUICK."),
2210
 
   (char**) &myisam_recover_options_str, (char**) &myisam_recover_options_str, 0,
2211
 
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
2212
1927
  {"pid-file", OPT_PID_FILE,
2213
1928
   N_("Pid file used by safe_mysqld."),
2214
1929
   (char**) &pidfile_name_ptr, (char**) &pidfile_name_ptr, 0, GET_STR,
2216
1931
  {"port", 'P',
2217
1932
   N_("Port number to use for connection or 0 for default to, in "
2218
1933
      "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
2219
 
      "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ")."),
2220
 
   (char**) &drizzled_port,
2221
 
   (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},
2222
1937
  {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
2223
1938
   N_("Maximum time in seconds to wait for the port to become free. "
2224
1939
      "(Default: no wait)"),
2302
2017
   (char**) &max_system_variables.join_buff_size, 0, GET_UINT64,
2303
2018
   REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
2304
2019
   MALLOC_OVERHEAD, IO_SIZE, 0},
2305
 
  {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
2306
 
   N_("Don't overwrite stale .MYD and .MYI even if no directory is specified."),
2307
 
   (char**) &global_system_variables.keep_files_on_create,
2308
 
   (char**) &max_system_variables.keep_files_on_create,
2309
 
   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
2310
2020
  {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
2311
2021
   N_("The size of the buffer used for index blocks for MyISAM tables. "
2312
2022
      "Increase this to get better index handling (for all reads and multiple "
2381
2091
   (char**) &global_system_variables.max_sort_length,
2382
2092
   (char**) &max_system_variables.max_sort_length, 0, GET_SIZE,
2383
2093
   REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
2384
 
  {"max_tmp_tables", OPT_MAX_TMP_TABLES,
2385
 
   N_("Maximum number of temporary tables a client can keep open at a time."),
2386
 
   (char**) &global_system_variables.max_tmp_tables,
2387
 
   (char**) &max_system_variables.max_tmp_tables, 0, GET_UINT64,
2388
 
   REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
2389
2094
  {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
2390
2095
   N_("After this many write locks, allow some read locks to run in between."),
2391
2096
   (char**) &max_write_lock_count, (char**) &max_write_lock_count, 0, GET_ULL,
2465
2170
   (char**) &global_system_variables.preload_buff_size,
2466
2171
   (char**) &max_system_variables.preload_buff_size, 0, GET_ULL,
2467
2172
   REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
2468
 
  {"protocol", OPT_PROTOCOL,
2469
 
   N_("Select protocol to be used (by default oldlibdrizzle)."),
2470
 
   (char**) &opt_protocol, (char**) &opt_protocol, 0,
2471
 
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
2472
2173
  {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
2473
2174
   N_("Allocation block size for query parsing and execution"),
2474
2175
   (char**) &global_system_variables.query_alloc_block_size,
2695
2396
#ifdef FOO
2696
2397
  print_defaults(DRIZZLE_CONFIG_NAME,load_default_groups);
2697
2398
  puts("");
2698
 
  set_ports();
 
2399
  set_default_port();
2699
2400
#endif
2700
2401
 
2701
2402
  /* Print out all the options including plugin supplied options */
2727
2428
{
2728
2429
  /* Things reset to zero */
2729
2430
  drizzle_home[0]= pidfile_name[0]= 0;
2730
 
  opt_logname= 0;
2731
2431
  opt_tc_log_file= (char *)"tc.log";      // no hostname in tc_log file name !
2732
2432
  opt_secure_file_priv= 0;
2733
2433
  segfaulted= 0;
2735
2435
  defaults_argc= 0;
2736
2436
  defaults_argv= 0;
2737
2437
  server_id_supplied= 0;
2738
 
  test_flags= select_errors= dropping_tables= ha_open_options=0;
 
2438
  test_flags= dropping_tables= ha_open_options=0;
2739
2439
  wake_thread=0;
2740
2440
  opt_endinfo= using_udf_functions= 0;
2741
2441
  abort_loop= select_thread_in_use= false;
2763
2463
  refresh_version= 1L;  /* Increments on each reload */
2764
2464
  thread_id= 1;
2765
2465
  strcpy(server_version, VERSION);
2766
 
  myisam_recover_options_str= "OFF";
2767
2466
  myisam_stats_method_str= "nulls_unequal";
2768
2467
  session_list.clear();
2769
2468
  key_caches.empty();
2934
2633
      global_system_variables.optimizer_use_mrr= (type-1);
2935
2634
      break;
2936
2635
    }
2937
 
  case OPT_MYISAM_RECOVER:
2938
 
    {
2939
 
      if (!argument)
2940
 
      {
2941
 
        myisam_recover_options=    HA_RECOVER_DEFAULT;
2942
 
        myisam_recover_options_str= myisam_recover_typelib.type_names[0];
2943
 
      }
2944
 
      else if (!argument[0])
2945
 
      {
2946
 
        myisam_recover_options= HA_RECOVER_NONE;
2947
 
        myisam_recover_options_str= "OFF";
2948
 
      }
2949
 
      else
2950
 
      {
2951
 
        myisam_recover_options_str=argument;
2952
 
        myisam_recover_options=
2953
 
          find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name);
2954
 
      }
2955
 
      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
2956
 
      break;
2957
 
    }
2958
2636
  case OPT_TC_HEURISTIC_RECOVER:
2959
2637
    tc_heuristic_recover= find_type_or_exit(argument,
2960
2638
                                            &tc_heuristic_recover_typelib,
3128
2806
 
3129
2807
static void fix_paths(void)
3130
2808
{
3131
 
  char buff[FN_REFLEN],*pos;
 
2809
  char buff[FN_REFLEN],*pos,rp_buff[PATH_MAX];
3132
2810
  convert_dirname(drizzle_home,drizzle_home,NULL);
3133
2811
  /* Resolve symlinks to allow 'drizzle_home' to be a relative symlink */
3134
 
  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);
3135
2819
  /* Ensure that drizzle_home ends in FN_LIBCHAR */
3136
2820
  pos= strchr(drizzle_home, '\0');
 
2821
#endif
3137
2822
  if (pos[-1] != FN_LIBCHAR)
3138
2823
  {
3139
2824
    pos[0]= FN_LIBCHAR;
3198
2883
  }
3199
2884
}
3200
2885
 
3201
 
 
3202
 
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
3203
 
                                      const char *option)
3204
 
{
3205
 
  uint32_t res;
3206
 
 
3207
 
  const char **ptr;
3208
 
 
3209
 
  if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
3210
 
  {
3211
 
    ptr= bit_lib->type_names;
3212
 
    if (!*x)
3213
 
      fprintf(stderr, _("No option given to %s\n"), option);
3214
 
    else
3215
 
      fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
3216
 
              option, x);
3217
 
    fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
3218
 
    while (*++ptr)
3219
 
      fprintf(stderr, ",'%s'", *ptr);
3220
 
    fprintf(stderr, "\n");
3221
 
    exit(1);
3222
 
  }
3223
 
  return res;
3224
 
}
3225
 
 
3226
 
 
3227
 
/**
3228
 
  @return
3229
 
    a bitfield from a string of substrings separated by ','
3230
 
    or
3231
 
    ~(uint32_t) 0 on error.
3232
 
*/
3233
 
 
3234
 
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
3235
 
{
3236
 
  bool found_end;
3237
 
  int  found_count;
3238
 
  const char *end,*i,*j;
3239
 
  const char **array, *pos;
3240
 
  uint32_t found,found_int,bit;
3241
 
 
3242
 
  found=0;
3243
 
  found_end= 0;
3244
 
  pos=(char *) x;
3245
 
  while (*pos == ' ') pos++;
3246
 
  found_end= *pos == 0;
3247
 
  while (!found_end)
3248
 
  {
3249
 
    if ((end=strrchr(pos,',')) != NULL)         /* Let end point at fieldend */
3250
 
    {
3251
 
      while (end > pos && end[-1] == ' ')
3252
 
        end--;                                  /* Skip end-space */
3253
 
      found_end=1;
3254
 
    }
3255
 
    else
3256
 
    {
3257
 
        end=pos+strlen(pos);
3258
 
        found_end=1;
3259
 
    }
3260
 
    found_int=0; found_count=0;
3261
 
    for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
3262
 
    {
3263
 
      j=pos;
3264
 
      while (j != end)
3265
 
      {
3266
 
        if (my_toupper(mysqld_charset,*i++) !=
3267
 
            my_toupper(mysqld_charset,*j++))
3268
 
          goto skip;
3269
 
      }
3270
 
      found_int=bit;
3271
 
      if (! *i)
3272
 
      {
3273
 
        found_count=1;
3274
 
        break;
3275
 
      }
3276
 
      else if (j != pos)                        // Half field found
3277
 
      {
3278
 
        found_count++;                          // Could be one of two values
3279
 
      }
3280
 
skip: ;
3281
 
    }
3282
 
    if (found_count != 1)
3283
 
      return(~(uint32_t) 0);                            // No unique value
3284
 
    found|=found_int;
3285
 
    pos=end+1;
3286
 
  }
3287
 
 
3288
 
  return(found);
3289
 
} /* find_bit_type */
3290
 
 
3291
2886
/*****************************************************************************
3292
2887
  Instantiate templates
3293
2888
*****************************************************************************/