Skip to content

File master_request.c

File List > cubrid > src > executables > master_request.c

Go to the documentation of this file

/*
 * Copyright 2008 Search Solution Corporation
 * Copyright 2016 CUBRID Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

/*
 * master_request.c - master request handling module
 */

#ident "$Id$"

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#if defined(WINDOWS)
#include <winsock2.h>
#include <time.h>
#else /* ! WINDOWS */
#include <sys/time.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <pthread.h>
#endif /* ! WINDOWS */

#include "system_parameter.h"
#include "connection_globals.h"
#include "client_support.h"
#include "error_manager.h"
#include "utility.h"
#include "message_catalog.h"
#include "memory_alloc.h"
#include "porting.h"
#include "release_string.h"
#if !defined(WINDOWS)
#include "tcp.h"
#else /* ! WINDOWS */
#include "wintcp.h"
#endif /* ! WINDOWS */
#include "master_util.h"
#include "master_request.h"
#include "master_heartbeat.h"
#include "master_server_monitor.hpp"

#if defined (SUPPRESS_STRLEN_WARNING)
#define strlen(s1)  ((int) strlen(s1))
#endif /* defined (SUPPRESS_STRLEN_WARNING) */

#define IS_MASTER_SOCKET_FD(FD)         \
      ((FD) == css_Master_socket_fd[0] || (FD) == css_Master_socket_fd[1])

#define SERVER_FORMAT_STRING " Server %s (rel %s, pid %d)\n"
#define HA_SERVER_FORMAT_STRING " HA-Server %s (rel %s, pid %d)\n"
#define HA_COPYLOGDB_FORMAT_STRING " HA-copylogdb %s (rel %s, pid %d)\n"
#define HA_APPLYLOGDB_FORMAT_STRING " HA-applylogdb %s (rel %s, pid %d)\n"

static void css_send_command_to_server (const SOCKET_QUEUE_ENTRY * sock_entry, int command);
static void css_send_message_to_server (const SOCKET_QUEUE_ENTRY * sock_entry, const char *message);
static void css_cleanup_info_connection (CSS_CONN_ENTRY * conn);
static void css_process_start_time_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_shutdown_time_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_server_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_all_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_server_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_all_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_kill_slave (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name);
static void css_process_kill_immediate (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name);
static void css_send_term_signal (int pid);
static void css_process_kill_master (void);
static void css_process_request_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_shutdown (char *time_buffer);
static void css_process_get_server_ha_mode (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name);
static void css_process_get_eof (CSS_CONN_ENTRY * conn);
static void css_process_ha_node_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id, bool verbose_yn);
static void css_process_ha_process_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id, bool verbose_yn);

static void css_process_kill_all_ha_process (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_is_registered_ha_proc (CSS_CONN_ENTRY * conn, unsigned short request_id, char *buf);
static void css_process_ha_deregister_by_pid (CSS_CONN_ENTRY * conn, unsigned short request_id, char *pid_p);
static void css_process_ha_deregister_by_args (CSS_CONN_ENTRY * conn, unsigned short request_id, char *args);
static void css_process_reconfig_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_deact_stop_all (CSS_CONN_ENTRY * conn, unsigned short request_id, char *deact_immediately);
static void css_process_deact_confirm_stop_all (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_deactivate_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_deact_confirm_no_server (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_activate_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id);

static void css_process_register_ha_process (CSS_CONN_ENTRY * conn);
static void css_process_deregister_ha_process (CSS_CONN_ENTRY * conn);
static void css_process_change_ha_mode (CSS_CONN_ENTRY * conn);
static void css_process_ha_ping_host_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_ha_admin_info (CSS_CONN_ENTRY * conn, unsigned short request_id);
static void css_process_ha_start_util_process (CSS_CONN_ENTRY * conn, unsigned short request_id, char *args);

static void css_process_server_state (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name);

/*
 * css_send_command_to_server()
 *   return: none
 *   sock_entry(in)
 *   command(in)
 */
static void
css_send_command_to_server (const SOCKET_QUEUE_ENTRY * sock_entry, int command)
{
  int request;

  request = htonl (command);
  if (sock_entry->conn_ptr && !sock_entry->info_p && !IS_MASTER_SOCKET_FD (sock_entry->conn_ptr->fd)
      && !IS_INVALID_SOCKET (sock_entry->conn_ptr->fd))
    {
      send (sock_entry->conn_ptr->fd, (char *) &request, sizeof (int), 0);
    }
}

/*
 * css_send_message_to_server()
 *   return: none
 *   sock_entry(in)
 *   message(in)
 */
static void
css_send_message_to_server (const SOCKET_QUEUE_ENTRY * sock_entry, const char *message)
{
  if (sock_entry->conn_ptr && !sock_entry->info_p && !IS_MASTER_SOCKET_FD (sock_entry->conn_ptr->fd)
      && !IS_INVALID_SOCKET (sock_entry->conn_ptr->fd))
    {
      send (sock_entry->conn_ptr->fd, message, MASTER_TO_SRV_MSG_SIZE, 0);
    }
}

/*
 * css_cleanup_info_connection()
 *   return: none
 *   conn(in)
 */
static void
css_cleanup_info_connection (CSS_CONN_ENTRY * conn)
{
  css_remove_entry_by_conn (conn, &css_Master_socket_anchor);
}

/*
 * css_process_start_time_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_start_time_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  char *my_time;

  my_time = ctime (&css_Start_time);
  if (css_send_data (conn, request_id, my_time, 26) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_shutdown_time_info() - send a remaining shutdown time
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_shutdown_time_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  struct timeval timeout;
  int time_left;
  char time_string[1028];
  char *master_release = (char *) rel_release_string ();

  if (css_Master_timeout == NULL)
    {
      if (css_send_data (conn, request_id, master_release, strlen (master_release) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
      return;
    }

  if (time ((time_t *) (&timeout.tv_sec)) == (time_t) (-1))
    {
      if (css_send_data (conn, request_id, master_release, strlen (master_release) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
    }

  if ((time_left = css_Master_timeout->tv_sec - timeout.tv_sec) > 0)
    {
      time_left = time_left / 60;
      sprintf (time_string, "%d", time_left);
      if (css_send_data (conn, request_id, time_string, strlen (time_string) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
    }
  else if (css_send_data (conn, request_id, master_release, strlen (master_release) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_server_count_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_server_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  int count = 0;
  SOCKET_QUEUE_ENTRY *temp;

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name
      && !IS_MASTER_CONN_NAME_DRIVER (temp->name) && !IS_MASTER_CONN_NAME_HA_COPYLOG (temp->name)
      && !IS_MASTER_CONN_NAME_HA_APPLYLOG (temp->name))
    {
      count++;
    }
    }

  count = htonl (count);
  if (css_send_data (conn, request_id, (char *) &count, sizeof (int)) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_all_count_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_all_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  int count = 0;
  SOCKET_QUEUE_ENTRY *temp;

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name)
    {
      count++;
    }
    }

  count = htonl (count);
  if (css_send_data (conn, request_id, (char *) &count, sizeof (int)) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_server_list_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_server_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  int bufsize = 0, required_size;
  char *buffer = NULL;
  SOCKET_QUEUE_ENTRY *temp;

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name != NULL
      && !IS_MASTER_CONN_NAME_DRIVER (temp->name) && !IS_MASTER_CONN_NAME_HA_COPYLOG (temp->name)
      && !IS_MASTER_CONN_NAME_HA_APPLYLOG (temp->name))
    {
      required_size = 0;

      /* if HA mode server */
      if (IS_MASTER_CONN_NAME_HA_SERVER (temp->name))
        {
          required_size += strlen (HA_SERVER_FORMAT_STRING);
        }
      else
        {
          required_size += strlen (SERVER_FORMAT_STRING);
        }
      required_size += strlen (temp->name);
      if (temp->version_string != NULL)
        {
          required_size += strlen (temp->version_string);
        }
      required_size += 5;   /* length of pid string */

      bufsize += required_size;

      if (buffer == NULL)
        {
          buffer = (char *) malloc (bufsize * sizeof (char));
          if (buffer == NULL)
        {
          goto error_return;
        }
          buffer[0] = '\0';
        }
      else
        {
          char *oldbuffer = buffer; /* save pointer in case realloc fails */
          buffer = (char *) realloc (buffer, bufsize * sizeof (char));
          if (buffer == NULL)
        {
          free_and_init (oldbuffer);
          goto error_return;
        }
        }

      /* if HA mode server */
      if (IS_MASTER_CONN_NAME_HA_SERVER (temp->name))
        {
          snprintf (buffer + strlen (buffer), required_size, HA_SERVER_FORMAT_STRING, temp->name + 1,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);
        }
      else
        {
          snprintf (buffer + strlen (buffer), required_size, SERVER_FORMAT_STRING, temp->name,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);

        }
    }
    }

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  free_and_init (buffer);
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
}

/*
 * css_process_all_list_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_all_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  int bufsize = 0, required_size;
  char *buffer = NULL;
  SOCKET_QUEUE_ENTRY *temp;

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name != NULL)
    {
      required_size = 0;

      switch (temp->name[0])
        {
        case '#':
          required_size += strlen (HA_SERVER_FORMAT_STRING);
          break;
        case '$':
          required_size += strlen (HA_COPYLOGDB_FORMAT_STRING);
          break;
        case '%':
          required_size += strlen (HA_APPLYLOGDB_FORMAT_STRING);
          break;
        default:
          required_size += strlen (SERVER_FORMAT_STRING);
          break;
        }
      required_size += strlen (temp->name);
      if (temp->version_string != NULL)
        {
          required_size += strlen (temp->version_string);
        }
      required_size += 5;   /* length of pid string */

      bufsize += required_size;

      if (buffer == NULL)
        {
          buffer = (char *) malloc (bufsize * sizeof (char));
          if (buffer == NULL)
        {
          goto error_return;
        }
          buffer[0] = '\0';
        }
      else
        {
          char *oldbuffer = buffer; /* save pointer in case realloc fails */
          buffer = (char *) realloc (buffer, bufsize * sizeof (char));
          if (buffer == NULL)
        {
          free_and_init (oldbuffer);
          goto error_return;
        }
        }

      switch (temp->name[0])
        {
        case '#':
          snprintf (buffer + strlen (buffer), required_size, HA_SERVER_FORMAT_STRING, temp->name + 1,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);
          break;
        case '$':
          snprintf (buffer + strlen (buffer), required_size, HA_COPYLOGDB_FORMAT_STRING, temp->name + 1,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);
          break;
        case '%':
          snprintf (buffer + strlen (buffer), required_size, HA_APPLYLOGDB_FORMAT_STRING, temp->name + 1,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);
          break;
        default:
          snprintf (buffer + strlen (buffer), required_size, SERVER_FORMAT_STRING, temp->name,
            (temp->version_string == NULL ? "?" : temp->version_string), temp->pid);
          break;
        }
    }
    }

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  free_and_init (buffer);
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
}

/*
 * css_process_kill_slave()
 *   return: none
 *   conn(in)
 *   request_id(in)
 *   server_name(in/out)
 */
static void
css_process_kill_slave (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name)
{
  int timeout;
  SOCKET_QUEUE_ENTRY *temp;
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  char *time_buffer = NULL;
  int time_size = 0;
  int rc;

  rc = __gv_cvar.css_receive_data (conn, request_id, &time_buffer, &time_size, -1);
  if (rc == NO_ERRORS && time_buffer != NULL)
    {
      timeout = ntohl ((int) *(int *) time_buffer);
      free_and_init (time_buffer);

      for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if ((temp->name != NULL) && ((strcmp (temp->name, server_name) == 0)
#if !defined(WINDOWS)
                       || (IS_MASTER_CONN_NAME_HA_SERVER (temp->name)
                       && (strcmp (temp->name + 1, server_name) == 0))
#endif
          ))
        {
#if !defined(WINDOWS)
          if (IS_MASTER_CONN_NAME_HA_SERVER (temp->name))
        {
          hb_deregister_by_pid (temp->pid);
        }
          else
#endif
        {
          memset (buffer, 0, sizeof (buffer));
          snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
                msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_STATUS),
                server_name, timeout);
#if !defined(WINDOWS)
          if (auto_Restart_server)
            {
              /* *INDENT-OFF* */
              master_Server_monitor->produce_job (server_monitor::job_type::UNREGISTER_SERVER, -1, "", "", server_name);
              /* *INDENT-ON* */
            }
#endif
          css_process_start_shutdown (temp, timeout * 60, buffer);
        }
          snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
            msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_NOTIFIED),
            server_name);

          if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
        {
          css_cleanup_info_connection (conn);
        }
          break;
        }
    }
    }

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_NOT_FOUND), server_name);

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (time_buffer != NULL)
    {
      free_and_init (time_buffer);
    }
}

/*
 * css_process_kill_immediate()
 *   return: none
 *   conn(in)
 *   request_id(in)
 *   server_name(in/out)
 */
static void
css_process_kill_immediate (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name)
{
  SOCKET_QUEUE_ENTRY *temp;
  char buffer[512];

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if ((temp->name != NULL) && (strcmp (temp->name, server_name) == 0) && !IS_MASTER_CONN_NAME_HA_SERVER (temp->name)
      && !IS_MASTER_CONN_NAME_HA_COPYLOG (temp->name) && !IS_MASTER_CONN_NAME_HA_APPLYLOG (temp->name))
    {
      css_send_command_to_server (temp, SERVER_SHUTDOWN_IMMEDIATE);

      snprintf (buffer, 512,
            msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_NOTIFIED),
            server_name);
      if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
        {
          css_cleanup_info_connection (conn);
        }
      return;
    }
    }
  snprintf (buffer, 512, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_NOT_FOUND),
        server_name);
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_start_shutdown_by_name()
 *   return: none
 *   server_name(in/out)
 */
void
css_process_start_shutdown_by_name (char *server_name)
{
#if !defined(WINDOWS)
  SOCKET_QUEUE_ENTRY *temp;
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  (void) pthread_mutex_lock (&css_Master_socket_anchor_lock);

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if ((temp->name != NULL) && (strcmp (temp->name, server_name) == 0))
    {
      /* Send a shutdown request to the specified cub_server with a timeout of 0. 
       * Buffer will be unused in the receiving function (css_process_shutdown_request). */
      css_process_start_shutdown (temp, 0, buffer);
    }
    }
  (void) pthread_mutex_unlock (&css_Master_socket_anchor_lock);
#endif
}


/*
 * css_process_shutdown_reviving_server()
 *   return: none
 *   conn(in)
 *   request_id(in)
 *   server_name(in/out)
 */
static void
css_process_shutdown_reviving_server (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name)
{
#if !defined(WINDOWS)
  if (auto_Restart_server)
    {
      /* *INDENT-OFF* */
      master_Server_monitor->produce_job (server_monitor::job_type::SHUTDOWN_SERVER, -1, "", "", server_name);
      /* *INDENT-ON* */
    }
#endif
}

/*
 * css_send_term_signal() - send a signal to the target process
 *   return: none
 *   pid(in)
 *     This function is created to send a SIGTERM to the processe.
 */
static void
css_send_term_signal (int pid)
{

#if defined(WINDOWS)
  HANDLE phandle;

  phandle = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
  if (phandle)
    {
      TerminateProcess (phandle, 0);
      CloseHandle (phandle);
    }
#else /* ! WINDOWS */
  kill (pid, SIGTERM);
#endif /* ! WINDOWS */
}

/*
 * css_process_kill_master()
 *   return: none
 */
static void
css_process_kill_master (void)
{
  css_shutdown_socket (css_Master_socket_fd[0]);
  css_shutdown_socket (css_Master_socket_fd[1]);

#if !defined(WINDOWS)
  unlink (css_get_master_domain_path ());

  if (hb_Resource && resource_Jobs)
    {
      hb_resource_shutdown_and_cleanup ();
    }

  if (hb_Cluster && cluster_Jobs)
    {
      hb_cluster_shutdown_and_cleanup ();
    }

  if (!HA_DISABLED ())
    {
      MASTER_ER_SET (ER_NOTIFICATION_SEVERITY, ARG_FILE_LINE, ER_HB_STOPPED, 0);
    }
#endif

  er_final (ER_ALL_FINAL);

  exit (1);
}

/*
 * css_process_request_count_info()
 *   return: none
 *   conn(in)
 *   request_id(in)
 */
static void
css_process_request_count_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
  int count;

  count = htonl (css_Total_request_count);
  if (css_send_data (conn, request_id, (char *) &count, sizeof (int)) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_start_shutdown()
 *   return: none
 *   sock_entq(in)
 *   timeout(in) : sec
 *   buffer(in)
 */
void
css_process_start_shutdown (SOCKET_QUEUE_ENTRY * sock_entq, int timeout, char *buffer)
{
  css_send_command_to_server (sock_entq, SERVER_START_SHUTDOWN);

  /* Send timeout delay period (in seconds) */
  css_send_command_to_server (sock_entq, timeout);

  /* Send shutdown message to server */
  css_send_message_to_server (sock_entq, buffer);
}

/*
 * css_process_shutdown()
 *   return: none
 *   time_buffer(in/out)
 */
static void
css_process_shutdown (char *time_buffer)
{
  int timeout;
  SOCKET_QUEUE_ENTRY *temp;
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  timeout = ntohl ((int) *(int *) time_buffer);

  memset (buffer, 0, sizeof (buffer));
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_GOING_DOWN), timeout);
#if !defined(WINDOWS)
  if (auto_Restart_server)
    {
      /* INDENT-OFF */
      master_Server_monitor.reset ();
      /* INDENT-ON */
    }
#endif

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      /* do not send shutdown command to master and connector, only to servers: cause connector crash */
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name
      && !IS_MASTER_CONN_NAME_DRIVER (temp->name) && !IS_MASTER_CONN_NAME_HA_SERVER (temp->name)
      && !IS_MASTER_CONN_NAME_HA_COPYLOG (temp->name) && !IS_MASTER_CONN_NAME_HA_APPLYLOG (temp->name))
    {
      css_process_start_shutdown (temp, timeout * 60, buffer);

      /* wait process terminated */
      master_util_wait_proc_terminate (temp->pid);
    }
    }

  if (css_Master_timeout == NULL)
    {
      css_Master_timeout = (struct timeval *) malloc (sizeof (struct timeval));
    }

  /* check again to be sure allocation was successful */
  if (css_Master_timeout)
    {
      css_Master_timeout->tv_sec = 0;
      css_Master_timeout->tv_usec = 0;

      if (time ((time_t *) (&css_Master_timeout->tv_sec)) == (time_t) (-1))
    {
      free_and_init (css_Master_timeout);
      return;
    }
      css_Master_timeout->tv_sec += timeout * 60;
    }
  MASTER_ER_SET (ER_WARNING_SEVERITY, ARG_FILE_LINE, ERR_CSS_MINFO_MESSAGE, 1, buffer);
}

/*
 * css_process_stop_shutdown()
 *   return: none
 */
void
css_process_stop_shutdown (void)
{
  SOCKET_QUEUE_ENTRY *temp;

  if (css_Master_timeout != NULL)
    {
      free_and_init (css_Master_timeout);
    }

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      /* do not send shutdown command to master and connector, only to servers: cause connector crash */
      if (!IS_INVALID_SOCKET (temp->fd) && !IS_MASTER_SOCKET_FD (temp->fd) && temp->name
      && !IS_MASTER_CONN_NAME_DRIVER (temp->name) && !IS_MASTER_CONN_NAME_HA_SERVER (temp->name)
      && !IS_MASTER_CONN_NAME_HA_COPYLOG (temp->name) && !IS_MASTER_CONN_NAME_HA_APPLYLOG (temp->name))
    {
      css_send_command_to_server (temp, SERVER_STOP_SHUTDOWN);
    }
    }
}

/*
 * css_process_get_server_ha_mode
 *   return: none
 *   conn(in)
 *   request_id(in)
 *   server_name(in/out)
 */
static void
css_process_get_server_ha_mode (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name)
{
  SOCKET_QUEUE_ENTRY *temp;
  char ha_state_str[64];
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  int len;
  int response;
  HA_SERVER_STATE ha_state;

  for (temp = css_Master_socket_anchor; temp; temp = temp->next)
    {
      if ((temp->name != NULL) && (strcmp (temp->name, server_name) == 0))
    {
      css_send_command_to_server (temp, SERVER_GET_HA_MODE);

      len = css_readn (temp->conn_ptr->fd, (char *) &response, sizeof (int), -1);
      if (len < 0)
        {
          return;
        }

      ha_state = (HA_SERVER_STATE) htonl (response);

      if (ha_state == HA_SERVER_STATE_NA)
        {
          snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
            msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CHANGEMODE, CHANGEMODE_MSG_NOT_HA_MODE));
        }
      else if ((ha_state >= HA_SERVER_STATE_IDLE) && (ha_state <= HA_SERVER_STATE_DEAD))
        {
          strncpy (ha_state_str, css_ha_server_state_string (ha_state), sizeof (ha_state_str) - 1);
          snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
            msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CHANGEMODE, CHANGEMODE_MSG_SERVER_MODE),
            temp->name, ha_state_str);
        }
      else
        {
          snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
            msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CHANGEMODE, CHANGEMODE_MSG_BAD_MODE),
            "unknown");
        }

      if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
        {
          css_cleanup_info_connection (conn);
        }
      return;
    }
    }

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_SERVER_NOT_FOUND), server_name);

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_register_ha_process()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_register_ha_process (CSS_CONN_ENTRY * conn)
{
#if !defined(WINDOWS)
  hb_register_new_process (conn);
#endif
}

/*
 * css_process_deregister_ha_process()
 *   return: none
 *   conn(in):
 *
 *   NOTE: this deregistration is requested directly by HA process itself
 *   , not by commdb
 */
static void
css_process_deregister_ha_process (CSS_CONN_ENTRY * conn)
{
#if !defined(WINDOWS)
  int rv, pid;

  rv = css_receive_heartbeat_data (conn, (char *) &pid, sizeof (pid));
  if (rv != NO_ERRORS)
    {
      return;
    }

  pid = ntohl (pid);
  hb_deregister_by_pid (pid);

  /* deregister will clean up this connection */
#else /* !WINDOWS */
  css_cleanup_info_connection (conn);
#endif /* WINDOWS */
}

/*
 * css_process_register_ha_process()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_change_ha_mode (CSS_CONN_ENTRY * conn)
{
#if !defined(WINDOWS)
  hb_resource_receive_changemode (conn);
#endif
}

/*
 * css_process_ha_ping_hosts_info()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_ha_ping_host_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  char *buffer = NULL;
  int result;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

  if (prm_get_string_value (PRM_ID_HA_PING_HOSTS))
    {
      hb_get_ping_host_info_string (&buffer);
    }
  else
    {
      hb_get_tcp_ping_host_info_string (&buffer);
    }

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_ha_admin_info()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_ha_admin_info (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  char *buffer = NULL;
  int result;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

  hb_get_admin_info_string (&buffer);

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}


/*
 * css_process_get_eof()
 *   return: none
 *   conn(in):
 */
static void
css_process_get_eof (CSS_CONN_ENTRY * conn)
{
#if !defined(WINDOWS)
  hb_resource_receive_get_eof (conn);
#endif
}

/*
 * css_process_ha_node_list_info()
 *   return: none
 *   conn(in):
 *   request_id(in):
 *   verbose_yn(in):
 */
static void
css_process_ha_node_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id, bool verbose_yn)
{
#if !defined(WINDOWS)
  char *buffer = NULL;
  int result;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

  hb_get_node_info_string (&buffer, verbose_yn);

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif

}

/*
 * css_process_ha_process_list_info()
 *   return: none
 *   conn(in):
 *   request_id(in):
 *   verbose_yn(in):
 */
static void
css_process_ha_process_list_info (CSS_CONN_ENTRY * conn, unsigned short request_id, bool verbose_yn)
{
#if !defined(WINDOWS)
  char *buffer = NULL;
  int result;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

  hb_get_process_info_string (&buffer, verbose_yn);

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_kill_all_ha_process()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_kill_all_ha_process (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  char *buffer = NULL;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  hb_kill_all_heartbeat_process (&buffer);

  if (buffer == NULL)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_is_registered_ha_proc()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_is_registered_ha_proc (CSS_CONN_ENTRY * conn, unsigned short request_id, char *buf)
{
#if !defined(WINDOWS)
  if (!HA_DISABLED ())
    {
      if (hb_is_registered_process (conn, buf))
    {
      if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
        {
          css_cleanup_info_connection (conn);
        }
      return;
    }
    }

  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_ha_deregister_by_pid()
 *   return: none
 *   conn(in):
 *   request_id(in):
 *   pid_p(in):
 */
static void
css_process_ha_deregister_by_pid (CSS_CONN_ENTRY * conn, unsigned short request_id, char *pid_p)
{
#if !defined(WINDOWS)
  pid_t pid;
  int result;

  if (!HA_DISABLED ())
    {
      result = hb_check_request_eligibility (conn->fd);
      if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

      pid = ntohl (*((int *) pid_p));
      hb_deregister_by_pid (pid);
    }
  else
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_ha_deregister_by_args()
 *   return: none
 *   conn(in):
 *   request_id(in):
 *   pid_p(in):
 */
static void
css_process_ha_deregister_by_args (CSS_CONN_ENTRY * conn, unsigned short request_id, char *args)
{
#if !defined(WINDOWS)
  int result;

  if (!HA_DISABLED ())
    {
      result = hb_check_request_eligibility (conn->fd);
      if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

      hb_deregister_by_args (args);
    }
  else
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}



/*
 * css_process_reconfig_heartbeat()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_reconfig_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  char *buffer = NULL;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  hb_reconfig_heartbeat (&buffer);
  if (buffer == NULL)
    {
      goto error_return;
    }
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_deactivate_heartbeat()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_deactivate_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  int error = NO_ERROR;
  int result;
  char *message;
  char error_string[LINE_MAX];
  char request_from[CUB_MAXHOSTNAMELEN] = "";

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL)
    {
      if (css_get_peer_name (conn->fd, request_from, sizeof (request_from)) != 0)
    {
      snprintf (request_from, sizeof (request_from), "UNKNOWN");
    }
    }

  if (result == HB_HC_FAILED)
    {
      snprintf (error_string, LINE_MAX, "%s.(failed to check eligibility of request)", HB_RESULT_FAILURE_STR);
      MASTER_ER_SET (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HB_COMMAND_EXECUTION, 2, HB_CMD_DEACTIVATE_STR, error_string);
      goto error_return;
    }
  else if (result == HB_HC_UNAUTHORIZED)
    {
      snprintf (error_string, LINE_MAX, "%s.(request from unauthorized host %s)", HB_RESULT_FAILURE_STR, request_from);
      MASTER_ER_SET (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HB_COMMAND_EXECUTION, 2, HB_CMD_DEACTIVATE_STR, error_string);
      goto error_return;
    }
  else if (result == HB_HC_ELIGIBLE_REMOTE)
    {
      hb_disable_er_log (HB_NOLOG_REMOTE_STOP, "deactivation request from %s", request_from);
    }

  error = hb_deactivate_heartbeat ();
  if (error != NO_ERROR)
    {
      goto error_return;
    }

  if (hb_get_deactivating_server_count () > 0)
    {
      message = msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_FAILOVER_FINISHED);

      if (css_send_data (conn, request_id, message, strlen (message) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
      return;
    }
    }
  else
    {
      if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
      return;
    }
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, "\0", 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
      return;
    }

  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

static void
css_process_deact_confirm_no_server (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  int error;

  if (hb_get_deactivating_server_count () == 0)
    {
      error = css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE);

      hb_finish_deactivate_server_info ();
    }
  else
    {
      error = css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE);
    }

  if (error != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

static void
css_process_deact_confirm_stop_all (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  int error;

  if (hb_is_deactivation_ready () == true)
    {
      error = css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE);
    }
  else
    {
      error = css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE);
    }

  if (error != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

static void
css_process_deact_stop_all (CSS_CONN_ENTRY * conn, unsigned short request_id, char *deact_immediately)
{
#if !defined(WINDOWS)
  int result;
  char error_string[LINE_MAX];
  char request_from[CUB_MAXHOSTNAMELEN] = "";

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);

  if (result != HB_HC_ELIGIBLE_LOCAL)
    {
      if (css_get_peer_name (conn->fd, request_from, sizeof (request_from)) != 0)
    {
      snprintf (request_from, sizeof (request_from), "UNKNOWN");
    }
    }

  if (result == HB_HC_FAILED)
    {
      snprintf (error_string, LINE_MAX, "%s.(failed to check eligibility of request)", HB_RESULT_FAILURE_STR);
      MASTER_ER_SET (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HB_COMMAND_EXECUTION, 2, HB_CMD_DEACTIVATE_STR, error_string);
      goto error_return;
    }
  else if (result == HB_HC_UNAUTHORIZED)
    {
      snprintf (error_string, LINE_MAX, "%s.(request from unauthorized host %s)", HB_RESULT_FAILURE_STR, request_from);
      MASTER_ER_SET (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HB_COMMAND_EXECUTION, 2, HB_CMD_DEACTIVATE_STR, error_string);
      goto error_return;
    }
  else if (result == HB_HC_ELIGIBLE_REMOTE)
    {
      hb_disable_er_log (HB_NOLOG_REMOTE_STOP, "deactivation request from %s", request_from);
    }

  if (hb_is_deactivation_started () == false)
    {
      hb_start_deactivate_server_info ();

      if (deact_immediately != NULL && *((bool *) deact_immediately) == true)
    {
      hb_Deactivate_immediately = true;
    }
      else
    {
      hb_Deactivate_immediately = false;
    }

      result = hb_prepare_deactivate_heartbeat ();
      if (result != NO_ERROR)
    {
      goto error_return;
    }
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_activate_heartbeat()
 *   return: none
 *   conn(in):
 *   request_id(in):
 */
static void
css_process_activate_heartbeat (CSS_CONN_ENTRY * conn, unsigned short request_id)
{
#if !defined(WINDOWS)
  int error = NO_ERROR;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  error = hb_activate_heartbeat ();
  if (error != NO_ERROR)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];
  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));
  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
#endif
}

/*
 * css_process_ha_start_util_process()
 *   return: none
 *   conn(in):
 *   request_id(in):
 *   args(in):
 */
static void
css_process_ha_start_util_process (CSS_CONN_ENTRY * conn, unsigned short request_id, char *args)
{
#if !defined(WINDOWS)
  int error = NO_ERROR;
  int result;

  if (HA_DISABLED ())
    {
      goto error_return;
    }

  result = hb_check_request_eligibility (conn->fd);
  if (result != HB_HC_ELIGIBLE_LOCAL && result != HB_HC_ELIGIBLE_REMOTE)
    {
      goto error_return;
    }

  error = hb_start_util_process (args);
  if (error != NO_ERROR)
    {
      goto error_return;
    }

  if (css_send_data (conn, request_id, HA_REQUEST_SUCCESS, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;

error_return:
  if (css_send_data (conn, request_id, HA_REQUEST_FAILURE, HA_REQUEST_RESULT_SIZE) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#else
  char buffer[MASTER_TO_SRV_MSG_SIZE];

  snprintf (buffer, MASTER_TO_SRV_MSG_SIZE,
        msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_MASTER, MASTER_MSG_PROCESS_ERROR));

  if (css_send_data (conn, request_id, buffer, strlen (buffer) + 1) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }

  return;
#endif
}

/*
 * css_process_server_state()
 *   return: none
 *   conn(in)
 *   request_id(in)
 *   server_name(in)
 */
static void
css_process_server_state (CSS_CONN_ENTRY * conn, unsigned short request_id, char *server_name)
{
  int state = 0;
#if !defined(WINDOWS)
  SOCKET_QUEUE_ENTRY *temp;

  temp = css_return_entry_of_server (server_name, css_Master_socket_anchor);
  if (temp == NULL || IS_INVALID_SOCKET (temp->fd))
    {
      state = HB_PSTATE_DEAD;
      goto send_to_client;
    }

  if (!temp->ha_mode)
    {
      state = HB_PSTATE_UNKNOWN;
      goto send_to_client;
    }

  state = hb_return_proc_state_by_fd (temp->fd);
send_to_client:
#endif

  state = htonl (state);
  if (css_send_data (conn, request_id, (char *) &state, sizeof (int)) != NO_ERRORS)
    {
      css_cleanup_info_connection (conn);
    }
}

/*
 * css_process_info_request() - information server main loop
 *   return: none
 *   conn(in)
 */
void
css_process_info_request (CSS_CONN_ENTRY * conn)
{
  int rc;
  int buffer_size;
  int request;
  unsigned short request_id;
  char *buffer = NULL;

  rc = __gv_cvar.css_receive_request (conn, &request_id, &request, &buffer_size);
  if (rc == NO_ERRORS)
    {
      if (buffer_size && __gv_cvar.css_receive_data (conn, request_id, &buffer, &buffer_size, -1) != NO_ERRORS)
    {
      if (buffer != NULL)
        {
          free_and_init (buffer);
        }
      css_cleanup_info_connection (conn);
      return;
    }
      switch (request)
    {
    case GET_START_TIME:
      css_process_start_time_info (conn, request_id);
      break;
    case GET_SHUTDOWN_TIME:
      css_process_shutdown_time_info (conn, request_id);
      break;
    case GET_SERVER_COUNT:
      css_process_server_count_info (conn, request_id);
      break;
    case GET_REQUEST_COUNT:
      css_process_request_count_info (conn, request_id);
      break;
    case GET_SERVER_LIST:
      css_process_server_list_info (conn, request_id);
      break;
    case KILL_SLAVE_SERVER:
      if (buffer != NULL)
        {
          css_process_kill_slave (conn, request_id, buffer);
        }
      break;
    case KILL_MASTER_SERVER:
      css_process_kill_master ();
      break;
    case START_SHUTDOWN:
      if (buffer != NULL)
        {
          css_process_shutdown (buffer);
        }
      css_process_kill_master ();
      break;
    case CANCEL_SHUTDOWN:
      css_process_stop_shutdown ();
      break;
    case KILL_SERVER_IMMEDIATE:
      if (buffer != NULL)
        {
          css_process_kill_immediate (conn, request_id, buffer);
        }
      break;
    case SHUTDOWN_REVIVING_SERVER:
      if (buffer != NULL)
        {
          css_process_shutdown_reviving_server (conn, request_id, buffer);
        }
      break;
    case GET_ALL_COUNT:
      css_process_all_count_info (conn, request_id);
      break;
    case GET_ALL_LIST:
      css_process_all_list_info (conn, request_id);
      break;
    case GET_SERVER_HA_MODE:
      if (buffer != NULL)
        {
          css_process_get_server_ha_mode (conn, request_id, buffer);
        }
      break;
    case GET_HA_PING_HOST_INFO:
      css_process_ha_ping_host_info (conn, request_id);
      break;
    case GET_HA_NODE_LIST:
      css_process_ha_node_list_info (conn, request_id, false);
      break;
    case GET_HA_NODE_LIST_VERBOSE:
      css_process_ha_node_list_info (conn, request_id, true);
      break;
    case GET_HA_PROCESS_LIST:
      css_process_ha_process_list_info (conn, request_id, false);
      break;
    case GET_HA_PROCESS_LIST_VERBOSE:
      css_process_ha_process_list_info (conn, request_id, true);
      break;
    case GET_HA_ADMIN_INFO:
      css_process_ha_admin_info (conn, request_id);
      break;
    case KILL_ALL_HA_PROCESS:
      css_process_kill_all_ha_process (conn, request_id);
      break;
    case IS_REGISTERED_HA_PROC:
      css_process_is_registered_ha_proc (conn, request_id, buffer);
      break;
    case DEREGISTER_HA_PROCESS_BY_PID:
      css_process_ha_deregister_by_pid (conn, request_id, buffer);
      break;
    case DEREGISTER_HA_PROCESS_BY_ARGS:
      css_process_ha_deregister_by_args (conn, request_id, buffer);
      break;
    case RECONFIG_HEARTBEAT:
      css_process_reconfig_heartbeat (conn, request_id);
      break;
    case DEACTIVATE_HEARTBEAT:
      css_process_deactivate_heartbeat (conn, request_id);
      break;
    case DEACT_STOP_ALL:
      css_process_deact_stop_all (conn, request_id, buffer);
      break;
    case DEACT_CONFIRM_STOP_ALL:
      css_process_deact_confirm_stop_all (conn, request_id);
      break;
    case DEACT_CONFIRM_NO_SERVER:
      css_process_deact_confirm_no_server (conn, request_id);
      break;
    case ACTIVATE_HEARTBEAT:
      css_process_activate_heartbeat (conn, request_id);
      break;
    case GET_SERVER_STATE:
      if (buffer != NULL)
        {
          css_process_server_state (conn, request_id, buffer);
        }
      break;
    case START_HA_UTIL_PROCESS:
      css_process_ha_start_util_process (conn, request_id, buffer);
      break;
    default:
      if (buffer != NULL)
        {
          free_and_init (buffer);
        }
      return;
    }
    }
  else
    {
      css_cleanup_info_connection (conn);
    }
  if (buffer != NULL)
    {
      free_and_init (buffer);
    }
}


/*
 * css_process_heartbeat_request() -
 *   return: none
 *   conn(in)
 */
void
css_process_heartbeat_request (CSS_CONN_ENTRY * conn)
{
#if !defined(WINDOWS)
  int error, request;
  int rfd = (conn) ? conn->fd : INVALID_SOCKET;
  char *buffer = NULL;

  error = css_receive_heartbeat_request (conn, &request);
  if (error == NO_ERRORS)
    {
      switch (request)
    {
    case SERVER_REGISTER_HA_PROCESS:
      css_process_register_ha_process (conn);
      break;
    case SERVER_DEREGISTER_HA_PROCESS:
      css_process_deregister_ha_process (conn);
      break;
    case SERVER_CHANGE_HA_MODE:
      css_process_change_ha_mode (conn);
      break;
    case SERVER_GET_EOF:
      css_process_get_eof (conn);
      break;
    default:
      MASTER_ER_LOG_DEBUG (ARG_FILE_LINE, "receive unexpected request. (request:%d).\n", request);
      break;
    }
    }
  else
    {
      MASTER_ER_LOG_DEBUG (ARG_FILE_LINE, "receive error request. (error:%d). \n", error);
      hb_cleanup_conn_and_start_process (conn, rfd);
    }
#else
  css_cleanup_info_connection (conn);
#endif

  return;
}