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 "") ...@@ -153,6 +153,7 @@ SET(HAVE_SIGSET CACHE INTERNAL "")
SET(HAVE_SIGTERM 1 CACHE INTERNAL "") SET(HAVE_SIGTERM 1 CACHE INTERNAL "")
SET(HAVE_SIGTHREADMASK CACHE INTERNAL "") SET(HAVE_SIGTHREADMASK CACHE INTERNAL "")
SET(HAVE_SIGWAIT CACHE INTERNAL "") SET(HAVE_SIGWAIT CACHE INTERNAL "")
SET(HAVE_SIGWAITINFO CACHE INTERNAL "")
SET(HAVE_SIZEOF_CHARP TRUE CACHE INTERNAL "") SET(HAVE_SIZEOF_CHARP TRUE CACHE INTERNAL "")
SET(SIZEOF_CHARP ${CMAKE_SIZEOF_VOID_P} CACHE INTERNAL "") SET(SIZEOF_CHARP ${CMAKE_SIZEOF_VOID_P} CACHE INTERNAL "")
SET(HAVE_SIZEOF_IN6_ADDR TRUE CACHE INTERNAL "") SET(HAVE_SIZEOF_IN6_ADDR TRUE CACHE INTERNAL "")
......
...@@ -219,6 +219,7 @@ ...@@ -219,6 +219,7 @@
#cmakedefine HAVE_SIGACTION 1 #cmakedefine HAVE_SIGACTION 1
#cmakedefine HAVE_SIGTHREADMASK 1 #cmakedefine HAVE_SIGTHREADMASK 1
#cmakedefine HAVE_SIGWAIT 1 #cmakedefine HAVE_SIGWAIT 1
#cmakedefine HAVE_SIGWAITINFO 1
#cmakedefine HAVE_SLEEP 1 #cmakedefine HAVE_SLEEP 1
#cmakedefine HAVE_SNPRINTF 1 #cmakedefine HAVE_SNPRINTF 1
#cmakedefine HAVE_STPCPY 1 #cmakedefine HAVE_STPCPY 1
......
...@@ -400,6 +400,7 @@ CHECK_FUNCTION_EXISTS (setlocale HAVE_SETLOCALE) ...@@ -400,6 +400,7 @@ CHECK_FUNCTION_EXISTS (setlocale HAVE_SETLOCALE)
CHECK_FUNCTION_EXISTS (sigaction HAVE_SIGACTION) CHECK_FUNCTION_EXISTS (sigaction HAVE_SIGACTION)
CHECK_FUNCTION_EXISTS (sigthreadmask HAVE_SIGTHREADMASK) CHECK_FUNCTION_EXISTS (sigthreadmask HAVE_SIGTHREADMASK)
CHECK_FUNCTION_EXISTS (sigwait HAVE_SIGWAIT) CHECK_FUNCTION_EXISTS (sigwait HAVE_SIGWAIT)
CHECK_FUNCTION_EXISTS (sigwaitinfo HAVE_SIGWAITINFO)
CHECK_FUNCTION_EXISTS (sigset HAVE_SIGSET) CHECK_FUNCTION_EXISTS (sigset HAVE_SIGSET)
CHECK_FUNCTION_EXISTS (sleep HAVE_SLEEP) CHECK_FUNCTION_EXISTS (sleep HAVE_SLEEP)
CHECK_FUNCTION_EXISTS (snprintf HAVE_SNPRINTF) CHECK_FUNCTION_EXISTS (snprintf HAVE_SNPRINTF)
......
...@@ -189,7 +189,19 @@ extern int my_pthread_create_detached; ...@@ -189,7 +189,19 @@ extern int my_pthread_create_detached;
int sigwait(sigset_t *set, int *sig); int sigwait(sigset_t *set, int *sig);
#endif #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) #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C)) #define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
......
...@@ -731,7 +731,8 @@ static void *signal_hand(void *arg __attribute__((unused))) ...@@ -731,7 +731,8 @@ static void *signal_hand(void *arg __attribute__((unused)))
DBUG_PRINT("info",("Starting signal and alarm handling thread")); DBUG_PRINT("info",("Starting signal and alarm handling thread"));
for(;;) for(;;)
{ {
while ((error=my_sigwait(&set,&sig)) == EINTR) int code;
while ((error=my_sigwait(&set,&sig,&code)) == EINTR)
printf("sigwait restarted\n"); printf("sigwait restarted\n");
if (error) if (error)
{ {
...@@ -805,8 +806,7 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) ...@@ -805,8 +806,7 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
/* Start signal thread and wait for it to start */ /* Start signal thread and wait for it to start */
mysql_mutex_lock(&LOCK_thread_count); mysql_mutex_lock(&LOCK_thread_count);
mysql_thread_create(0, mysql_thread_create(0, &tid, &thr_attr, signal_hand, NULL);
&tid, &thr_attr, signal_hand, NULL);
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
DBUG_PRINT("info",("signal thread created")); DBUG_PRINT("info",("signal thread created"));
......
...@@ -3402,14 +3402,15 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) ...@@ -3402,14 +3402,15 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
(void) pthread_sigmask(SIG_BLOCK,&set,NULL); (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
for (;;) for (;;)
{ {
int error; // Used when debugging int error;
int origin;
if (shutdown_in_progress && !abort_loop) if (shutdown_in_progress && !abort_loop)
{ {
sig= SIGTERM; sig= SIGTERM;
error=0; error=0;
} }
else else
while ((error=my_sigwait(&set,&sig)) == EINTR) ; while ((error= my_sigwait(&set, &sig, &origin)) == EINTR) /* no-op */;
if (cleanup_done) if (cleanup_done)
{ {
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()")); DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
...@@ -3449,7 +3450,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) ...@@ -3449,7 +3450,7 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
} }
break; break;
case SIGHUP: case SIGHUP:
if (!abort_loop) if (!abort_loop && origin != SI_KERNEL)
{ {
int not_used; int not_used;
mysql_print_status(); // Print some debug info 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