Commit 07e9b138 authored by Sergei Golubchik's avatar Sergei Golubchik

mysqld: ignore SIGHUP sent by the kernel

SIGHUP causes debug info in the error log and reload of
logs/privileges/tables/etc. The server should only do it when
a user intentionally sends SUGHUP, not when a parent terminal gets
disconnected or something.

In particular, not ignoring kernel SIGHUP causes FLUSH PRIVILEGES
at some random point during non-systemd Debian upgrades (Debian
restarts mysqld, debian-start script runs mysql_upgrade in the background,
postinit script ends and kernel sends SIGHUP to all background processes
it has started). And during mysql_upgrade privilege tables aren't
necessarily ready to be reloaded.
parent 97dbb356
......@@ -153,6 +153,7 @@ SET(HAVE_SIGSET CACHE INTERNAL "")
SET(HAVE_SIGTERM 1 CACHE INTERNAL "")
SET(HAVE_SIGTHREADMASK CACHE INTERNAL "")
SET(HAVE_SIGWAIT CACHE INTERNAL "")
SET(HAVE_SIGWAITINFO CACHE INTERNAL "")
SET(HAVE_SIZEOF_CHARP TRUE CACHE INTERNAL "")
SET(SIZEOF_CHARP ${CMAKE_SIZEOF_VOID_P} CACHE INTERNAL "")
SET(HAVE_SIZEOF_IN6_ADDR TRUE CACHE INTERNAL "")
......
......@@ -219,6 +219,7 @@
#cmakedefine HAVE_SIGACTION 1
#cmakedefine HAVE_SIGTHREADMASK 1
#cmakedefine HAVE_SIGWAIT 1
#cmakedefine HAVE_SIGWAITINFO 1
#cmakedefine HAVE_SLEEP 1
#cmakedefine HAVE_SNPRINTF 1
#cmakedefine HAVE_STPCPY 1
......
......@@ -400,6 +400,7 @@ CHECK_FUNCTION_EXISTS (setlocale HAVE_SETLOCALE)
CHECK_FUNCTION_EXISTS (sigaction HAVE_SIGACTION)
CHECK_FUNCTION_EXISTS (sigthreadmask HAVE_SIGTHREADMASK)
CHECK_FUNCTION_EXISTS (sigwait HAVE_SIGWAIT)
CHECK_FUNCTION_EXISTS (sigwaitinfo HAVE_SIGWAITINFO)
CHECK_FUNCTION_EXISTS (sigset HAVE_SIGSET)
CHECK_FUNCTION_EXISTS (sleep HAVE_SLEEP)
CHECK_FUNCTION_EXISTS (snprintf HAVE_SNPRINTF)
......
......@@ -189,7 +189,19 @@ extern int my_pthread_create_detached;
int sigwait(sigset_t *set, int *sig);
#endif
#define my_sigwait(A,B) sigwait((A),(B))
static inline int my_sigwait(sigset_t *set, int *sig, int *code)
{
#ifdef HAVE_SIGWAITINFO
siginfo_t siginfo;
*sig= sigwaitinfo(set, &siginfo);
*code= siginfo.si_code;
return *sig < 0 ? errno : 0;
#else
#define SI_KERNEL 128
*code= 0;
return sigwait(set, sig);
#endif
}
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
......
......@@ -731,7 +731,8 @@ static void *signal_hand(void *arg __attribute__((unused)))
DBUG_PRINT("info",("Starting signal and alarm handling thread"));
for(;;)
{
while ((error=my_sigwait(&set,&sig)) == EINTR)
int code;
while ((error=my_sigwait(&set,&sig,&code)) == EINTR)
printf("sigwait restarted\n");
if (error)
{
......@@ -805,8 +806,7 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
/* Start signal thread and wait for it to start */
mysql_mutex_lock(&LOCK_thread_count);
mysql_thread_create(0,
&tid, &thr_attr, signal_hand, NULL);
mysql_thread_create(0, &tid, &thr_attr, signal_hand, NULL);
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
DBUG_PRINT("info",("signal thread created"));
......
......@@ -3402,14 +3402,15 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
(void) pthread_sigmask(SIG_BLOCK,&set,NULL);
for (;;)
{
int error; // Used when debugging
int error;
int origin;
if (shutdown_in_progress && !abort_loop)
{
sig= SIGTERM;
error=0;
}
else
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
while ((error= my_sigwait(&set, &sig, &origin)) == EINTR) /* no-op */;
if (cleanup_done)
{
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
......@@ -3449,7 +3450,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
}
break;
case SIGHUP:
if (!abort_loop)
if (!abort_loop && origin != SI_KERNEL)
{
int not_used;
mysql_print_status(); // Print some debug info
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment