Commit 48ed060d authored by unknown's avatar unknown
Browse files

Fix for BUG#12751: Instance Manager: client hangs after

start instance; kill mysqlmanager; show ...

The problem was that Instance Manager didn't close client
sockets (sockets for client connections) on execing mysqld
instance. So, mysqld-instance inherits these descriptors.

The fix is to set close-on-exec flag for each client socket.


mysql-test/r/im_daemon_life_cycle.result:
  Updated result file.
mysql-test/t/im_daemon_life_cycle.imtest:
  Test for BUG#12751.
server-tools/instance-manager/listener.cc:
  Set close-on-exec flag for each client socket.
parent 1a22b9c1
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -8,3 +8,17 @@ mysqld2 offline
Killing the process...
Sleeping...
Success: the process was restarted.

--------------------------------------------------------------------
-- Test for BUG#12751
--------------------------------------------------------------------
START INSTANCE mysqld2;
Success: the process has been started.
Killing the process...
Sleeping...
Success: the process was restarted.
SHOW INSTANCE STATUS mysqld1;
instance_name	status	version
mysqld1	online	VERSION
STOP INSTANCE mysqld2;
Success: the process has been stopped.
+44 −0
Original line number Diff line number Diff line
@@ -14,3 +14,47 @@
# process.

--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30

###########################################################################

#
# BUG#12751: Instance Manager: client hangs
#

--echo
--echo --------------------------------------------------------------------
--echo -- Test for BUG#12751
--echo --------------------------------------------------------------------

# Give some time to begin accepting connections after restart.
# FIXME: race condition here.

--sleep 3

# 1. Start mysqld;

START INSTANCE mysqld2;
# FIXME: START INSTANCE should be synchronous.
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started

# 2. Restart IM-main: kill it and IM-angel will restart it.

--exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_PATH_PID restarted 30

# 3. Issue some statement -- connection should be re-established.

# Give some time to begin accepting connections after restart.
# FIXME: race condition here.

--sleep 3

--replace_column 3 VERSION
SHOW INSTANCE STATUS mysqld1;

# 4. Stop mysqld2, because it will not be stopped by IM, as it is nonguarded.
# So, if it we do not stop it, it will be stopped by mysql-test-run.pl with
# warning.

STOP INSTANCE mysqld2;
# FIXME: STOP INSTANCE should be synchronous.
--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped
+23 −19
Original line number Diff line number Diff line
@@ -36,6 +36,27 @@
#include "portability.h"


static void set_non_blocking(int socket)
{
#ifndef __WIN__
  int flags= fcntl(socket, F_GETFL, 0);
  fcntl(socket, F_SETFL, flags | O_NONBLOCK);
#else
  u_long arg= 1;
  ioctlsocket(socket, FIONBIO, &arg);
#endif
}


static void set_no_inherit(int socket)
{
#ifndef __WIN__
  int flags= fcntl(socket, F_GETFD, 0);
  fcntl(socket, F_SETFD, flags | FD_CLOEXEC);
#endif
}


/*
  Listener_thread - incapsulates listening functionality
*/
@@ -157,6 +178,8 @@ void Listener_thread::run()
        /* accept may return -1 (failure or spurious wakeup) */
        if (client_fd >= 0)                    // connection established
        {
          set_no_inherit(client_fd);

          Vio *vio= vio_new(client_fd, socket_index == 0 ?
                            VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
                            socket_index == 0 ? 1 : 0);
@@ -198,25 +221,6 @@ void Listener_thread::run()
  return;
}

void set_non_blocking(int socket)
{
#ifndef __WIN__
  int flags= fcntl(socket, F_GETFL, 0);
  fcntl(socket, F_SETFL, flags | O_NONBLOCK);
#else
  u_long arg= 1;
  ioctlsocket(socket, FIONBIO, &arg);
#endif
}

void set_no_inherit(int socket)
{
#ifndef __WIN__
  int flags= fcntl(socket, F_GETFD, 0);
  fcntl(socket, F_SETFD, flags | FD_CLOEXEC);
#endif
}

int Listener_thread::create_tcp_socket()
{
  /* value to be set by setsockopt */