275
270
#ifdef HAVE_INITGROUPS
276
271
static bool calling_initgroups= false; /**< Used in SIGSEGV handler. */
278
uint32_t drizzled_port, test_flags, select_errors, dropping_tables, ha_open_options;
275
This needs to be a uint32_t and not a in_port_t because the config system
276
requires a 4-byte integer.
278
uint32_t drizzled_tcp_port;
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;
634
/****************************************************************************
635
** Init IP and UNIX socket
636
****************************************************************************/
638
static void set_ports()
625
* Setup default port value from (in order or precedence):
626
* - Command line option
627
* - DRIZZLE_TCP_PORT environment variable
629
* - Lookup in /etc/services
632
static void set_default_port()
642
{ // Get port if not from commandline
643
drizzled_port= DRIZZLE_PORT;
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
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;
637
if (drizzled_tcp_port == 0)
639
drizzled_tcp_port= DRIZZLE_TCP_PORT;
641
if (DRIZZLE_TCP_PORT_DEFAULT == 0)
643
if ((serv_ptr= getservbyname("drizzle", "tcp")))
644
drizzled_tcp_port= ntohs((u_short) serv_ptr->s_port);
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);
662
assert(drizzled_port);
650
assert(drizzled_tcp_port != 0);
788
static void network_init(void)
794
char port_buf[NI_MAXSERV];
796
struct addrinfo *next;
797
struct addrinfo hints;
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;
808
snprintf(port_buf, NI_MAXSERV, "%d", drizzled_port);
809
error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
812
sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
813
unireg_abort(1); /* purecov: tested */
816
for (next= ai, pollfd_count= 0; next; next= next->ai_next)
818
ip_sock= socket(next->ai_family, next->ai_socktype, next->ai_protocol);
821
/* getaddrinfo can return bad results, skip them here and error later if
822
we didn't find anything to bind to. */
826
fds[pollfd_count].fd= ip_sock;
827
fds[pollfd_count].events= POLLIN | POLLERR;
830
/* Add options for our listening socket */
832
struct linger ling = {0, 0};
836
if (next->ai_family == AF_INET6)
838
error= setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
841
perror("setsockopt");
846
error= setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof(flags));
849
perror("setsockopt");
852
error= setsockopt(ip_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
855
perror("setsockopt");
858
error= setsockopt(ip_sock, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
861
perror("setsockopt");
864
error= setsockopt(ip_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
867
perror("setsockopt");
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=#).
881
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
883
if (((ret= ::bind(ip_sock, next->ai_addr, next->ai_addrlen)) >= 0 ) ||
884
(errno != EADDRINUSE) ||
885
(waited >= drizzled_port_timeout))
887
errmsg_printf(ERRMSG_LVL_INFO, _("Retrying bind on TCP/IP port %u"), drizzled_port);
888
this_wait= retry * retry / 3 + 1;
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);
898
if (listen(ip_sock,(int) back_log) < 0)
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"),
907
if (pollfd_count == 0 && ai != NULL)
909
sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
910
unireg_abort(1); /* purecov: tested */
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)
919
sql_perror(_("Can't open abort pipet"));
920
errmsg_printf(ERRMSG_LVL_ERROR,
921
_("pipe() on abort_pipe failed with error %d"), errno);
925
fds[pollfd_count].fd= abort_pipe[0];
926
fds[pollfd_count].events= POLLIN | POLLERR;
934
776
/** Called when a thread is aborted. */
936
778
extern "C" void end_thread_signal(int )
1802
1653
init_status_vars();
1804
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
1805
"", drizzled_port, COMPILATION_COMMENT);
1808
handle_connections_sockets();
1655
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), my_progname, server_version,
1656
COMPILATION_COMMENT);
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)
1664
if (!(session= new Session(protocol)))
1670
create_new_thread(session);
1809
1673
/* (void) pthread_attr_destroy(&connection_attrib); */
1881
/* Handle new connections and spawn new process to handle them */
1883
void handle_connections_sockets()
1887
uint32_t error_count=0;
1889
struct sockaddr_storage cAddr;
1896
if ((number_of= poll(fds, pollfd_count, -1)) == -1)
1900
if (!select_errors++ && !abort_loop) /* purecov: inspected */
1901
errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
1902
errno); /* purecov: inspected */
1909
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
1910
assert(number_of > 1); /* Not handling this at the moment */
1918
for (x= 0, sock= -1; x < pollfd_count; x++)
1920
if (fds[x].revents == POLLIN)
1928
for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
1930
socklen_t length= sizeof(struct sockaddr_storage);
1931
new_sock= accept(sock, (struct sockaddr *)(&cAddr),
1933
if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
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
1949
struct sockaddr_storage dummy;
1950
dummyLen = sizeof(dummy);
1951
if ( getsockname(new_sock,(struct sockaddr *)&dummy,
1952
(socklen_t *)&dummyLen) < 0 )
1954
sql_perror("Error on new connection socket");
1955
(void) shutdown(new_sock, SHUT_RDWR);
1956
(void) close(new_sock);
1959
dummyLen = sizeof(dummy);
1960
if ( getpeername(new_sock, (struct sockaddr *)&dummy,
1961
(socklen_t *)&dummyLen) < 0)
1963
sql_perror("Error on new connection socket");
1964
(void) shutdown(new_sock, SHUT_RDWR);
1965
(void) close(new_sock);
1971
** Don't allow too many connections
1974
if (!(protocol= get_protocol()))
1976
(void) shutdown(new_sock, SHUT_RDWR);
1981
if (!(session= new Session(protocol)))
1984
(void) shutdown(new_sock, SHUT_RDWR);
1989
if (protocol->setFileDescriptor(new_sock))
1995
create_new_thread(session);
1998
for (x= 0; x < pollfd_count; x++)
2000
if (fds[x].fd != -1)
2002
(void) shutdown(fds[x].fd, SHUT_RDWR);
2003
(void) close(fds[x].fd);
2008
/* abort_pipe[0] was closed in the for loop above in fds[] */
2009
(void) close(abort_pipe[1]);
2013
1745
/****************************************************************************
2014
1746
Handle start options
2015
1747
******************************************************************************/
2017
1749
enum options_drizzled
2021
1752
OPT_BIND_ADDRESS, OPT_PID_FILE,
2022
1753
OPT_STORAGE_ENGINE,
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 },
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,
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,
3128
2807
static void fix_paths(void)
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);
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');
3136
2822
if (pos[-1] != FN_LIBCHAR)
3138
2824
pos[0]= FN_LIBCHAR;
3201
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
3208
if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
3210
ptr= bit_lib->type_names;
3212
fprintf(stderr, _("No option given to %s\n"), option);
3214
fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
3216
fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
3218
fprintf(stderr, ",'%s'", *ptr);
3219
fprintf(stderr, "\n");
3228
a bitfield from a string of substrings separated by ','
3230
~(uint32_t) 0 on error.
3233
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
3237
const char *end,*i,*j;
3238
const char **array, *pos;
3239
uint32_t found,found_int,bit;
3244
while (*pos == ' ') pos++;
3245
found_end= *pos == 0;
3248
if ((end=strrchr(pos,',')) != NULL) /* Let end point at fieldend */
3250
while (end > pos && end[-1] == ' ')
3251
end--; /* Skip end-space */
3256
end=pos+strlen(pos);
3259
found_int=0; found_count=0;
3260
for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
3265
if (my_toupper(mysqld_charset,*i++) !=
3266
my_toupper(mysqld_charset,*j++))
3275
else if (j != pos) // Half field found
3277
found_count++; // Could be one of two values
3281
if (found_count != 1)
3282
return(~(uint32_t) 0); // No unique value
3288
} /* find_bit_type */
3290
2886
/*****************************************************************************
3291
2887
Instantiate templates
3292
2888
*****************************************************************************/