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 )
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},
1803
1653
init_status_vars();
1805
errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)),my_progname,server_version,
1806
"", drizzled_port, COMPILATION_COMMENT);
1809
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);
1810
1673
/* (void) pthread_attr_destroy(&connection_attrib); */
1882
/* Handle new connections and spawn new process to handle them */
1884
void handle_connections_sockets()
1888
uint32_t error_count=0;
1890
struct sockaddr_storage cAddr;
1897
if ((number_of= poll(fds, pollfd_count, -1)) == -1)
1901
if (!select_errors++ && !abort_loop) /* purecov: inspected */
1902
errmsg_printf(ERRMSG_LVL_ERROR, _("drizzled: Got error %d from select"),
1903
errno); /* purecov: inspected */
1910
#ifdef FIXME_IF_WE_WERE_KEEPING_THIS
1911
assert(number_of > 1); /* Not handling this at the moment */
1919
for (x= 0, sock= -1; x < pollfd_count; x++)
1921
if (fds[x].revents == POLLIN)
1929
for (uint32_t retry=0; retry < MAX_ACCEPT_RETRY; retry++)
1931
socklen_t length= sizeof(struct sockaddr_storage);
1932
new_sock= accept(sock, (struct sockaddr *)(&cAddr),
1934
if (new_sock != -1 || (errno != EINTR && errno != EAGAIN))
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
1950
struct sockaddr_storage dummy;
1951
dummyLen = sizeof(dummy);
1952
if ( getsockname(new_sock,(struct sockaddr *)&dummy,
1953
(socklen_t *)&dummyLen) < 0 )
1955
sql_perror("Error on new connection socket");
1956
(void) shutdown(new_sock, SHUT_RDWR);
1957
(void) close(new_sock);
1960
dummyLen = sizeof(dummy);
1961
if ( getpeername(new_sock, (struct sockaddr *)&dummy,
1962
(socklen_t *)&dummyLen) < 0)
1964
sql_perror("Error on new connection socket");
1965
(void) shutdown(new_sock, SHUT_RDWR);
1966
(void) close(new_sock);
1972
** Don't allow too many connections
1975
if (!(protocol= get_protocol()))
1977
(void) shutdown(new_sock, SHUT_RDWR);
1982
if (!(session= new Session(protocol)))
1985
(void) shutdown(new_sock, SHUT_RDWR);
1990
if (protocol->setFileDescriptor(new_sock))
1996
create_new_thread(session);
1999
for (x= 0; x < pollfd_count; x++)
2001
if (fds[x].fd != -1)
2003
(void) shutdown(fds[x].fd, SHUT_RDWR);
2004
(void) close(fds[x].fd);
2009
/* abort_pipe[0] was closed in the for loop above in fds[] */
2010
(void) close(abort_pipe[1]);
2014
1745
/****************************************************************************
2015
1746
Handle start options
2016
1747
******************************************************************************/
2018
1749
enum options_drizzled
2022
1752
OPT_BIND_ADDRESS, OPT_PID_FILE,
2023
1753
OPT_STORAGE_ENGINE,
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 },
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,
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,
3129
2807
static void fix_paths(void)
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);
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');
3137
2822
if (pos[-1] != FN_LIBCHAR)
3139
2824
pos[0]= FN_LIBCHAR;
3202
static uint32_t find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
3209
if ((res= find_bit_type(x, bit_lib)) == ~(uint32_t) 0)
3211
ptr= bit_lib->type_names;
3213
fprintf(stderr, _("No option given to %s\n"), option);
3215
fprintf(stderr, _("Wrong option to %s. Option(s) given: %s\n"),
3217
fprintf(stderr, _("Alternatives are: '%s'"), *ptr);
3219
fprintf(stderr, ",'%s'", *ptr);
3220
fprintf(stderr, "\n");
3229
a bitfield from a string of substrings separated by ','
3231
~(uint32_t) 0 on error.
3234
static uint32_t find_bit_type(const char *x, TYPELIB *bit_lib)
3238
const char *end,*i,*j;
3239
const char **array, *pos;
3240
uint32_t found,found_int,bit;
3245
while (*pos == ' ') pos++;
3246
found_end= *pos == 0;
3249
if ((end=strrchr(pos,',')) != NULL) /* Let end point at fieldend */
3251
while (end > pos && end[-1] == ' ')
3252
end--; /* Skip end-space */
3257
end=pos+strlen(pos);
3260
found_int=0; found_count=0;
3261
for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
3266
if (my_toupper(mysqld_charset,*i++) !=
3267
my_toupper(mysqld_charset,*j++))
3276
else if (j != pos) // Half field found
3278
found_count++; // Could be one of two values
3282
if (found_count != 1)
3283
return(~(uint32_t) 0); // No unique value
3289
} /* find_bit_type */
3291
2886
/*****************************************************************************
3292
2887
Instantiate templates
3293
2888
*****************************************************************************/