Пример #1
0
ut_cleanup()
{
    os_closesocket(server_sock);
    os_closesocket(client_sock);
    os_closesocket(accept_sock);
    os_net_cleanup();
}
Пример #2
0
/** select a free connection
 *
 * \param[in] sock_xml: socket on which it receives commands.
 */
static void
handle_connection(int msg_sock)
{
  int i;
  static cl_error_desc_t busy = { .code = -EXA_ERR_ADM_BUSY,
                                  .msg  = "Too many connections."};

  /* Search free slot in connection array */
  for (i = 0; i < MAX_CONNECTION; i++)
    {
      if (connectlist[i].uid == CMD_UID_INVALID && connectlist[i].fd == -1)
	{
	  exalog_debug("CONNECTION %d: Using sock %d", i, msg_sock);

	  /* uid is set when the command is actually scheduled */
	  connectlist[i].fd = msg_sock;
	  FD_SET(msg_sock, &setSocks);
	  return;
	}
    }

  /*
   * No free connection found. We disconnect the caller now because we
   * are no room in our connectionlist
   */
  exalog_error("All connections are busy sock=%d", msg_sock);

  cli_command_end_complete(msg_sock, &busy);
  os_closesocket(msg_sock);
}

/*-------------------------------------------------------------------------*/
/** \brief Connection thread: wait on xml message to pass the command
 * to the work thread.
 *
 * \param[in] sock_xml_proto: socket xml on which it receives commands.
 * \return the selected working thread or a negative error code
 *
 */
/*-------------------------------------------------------------------------*/
static void
accept_new_client(void)
{
  int fd = os_accept(listen_fd, NULL, NULL);

  exalog_debug("Got an incoming XML Request on socket: %d", fd);
  if (fd < 0)
    {
      exalog_error("Failed during admind xml connection accept: error=%s",
                   exa_error_msg(-fd));
      return;
    }

  handle_connection(fd);
}
Пример #3
0
/*-------------------------------------------------------------------------*/
static void
close_connection(int connection_id)
{
  int cli_fd = connectlist[connection_id].fd;

  EXA_ASSERT_VERBOSE(cli_fd > 2 , "fd = %d", cli_fd);

  FD_CLR(cli_fd, &setSocks);
  os_closesocket(cli_fd);
  exalog_debug("CONNECTION: %d  Socket %d closed state_work NOT_USED",
	       connection_id, cli_fd);

  /* Do not reset uid and free field because there may be a command still
   * running on the worker thread. Those fields will be reset when it ends. */
  connectlist[connection_id].fd = -1;
}
Пример #4
0
static void __close_socket(int sock)
{
    os_shutdown(sock, SHUT_RDWR);
    os_closesocket(sock);
}
Пример #5
0
static void
check_internal_msg(void)
{
  struct timeval timeout = { .tv_sec = 0, .tv_usec = EXAMSG_TIMEOUT };
  static Examsg msg;
  command_end_t *end;
  int i, ret;

  ret = examsgWaitTimeout(cli_mh, &timeout);

  if (ret < 0 && ret != -ETIME)
    {
      exalog_error("Message wait failed %s (%d)",
	           exa_error_msg(ret), ret);
      return;
    }

  if (ret == -ETIME)
    return;

  ret = examsgRecv(cli_mh, NULL, &msg, sizeof(msg));
  if (ret == 0)
    return;

  EXA_ASSERT_VERBOSE(ret > 0, "Message receive failed: %s (%d)",
                     exa_error_msg(ret), ret);

  if (ret < 0)
    exalog_error("Message receive failed: %s (%d)",
	         exa_error_msg(ret), ret);

  /* The CLI server can only receive EXAMSG_ADM_CLUSTER_CMD_END messages for now */
  EXA_ASSERT(msg.any.type == EXAMSG_ADM_CLUSTER_CMD_END);

  end = (command_end_t *)msg.payload;
  for (i = 0; i < MAX_CONNECTION; i++)
    if (end->cuid == connectlist[i].uid)
      {
	cli_command_end_complete(connectlist[i].fd, &end->err_desc);
	connectlist[i].uid = CMD_UID_INVALID;
	break;
      }
  EXA_ASSERT(i < MAX_CONNECTION);
}

static void
check_tcp_connection(void)
{
  static struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
  fd_set setSave = setSocks;
  int ret, conn_id;

  do
    ret = os_select(FD_SETSIZE, &setSave, NULL,  NULL, &timeout);
  while (ret == -EINTR);

  if (ret < 0)
    {
      /* FIXME should assert ? */
      exalog_debug("Select failed %m");
      return;
    }

  /* Check working sockets */
  for (conn_id = 0; conn_id < MAX_CONNECTION; ++conn_id)
    {
      int sock_fd = connectlist[conn_id].fd;
      if (sock_fd >= 0 && FD_ISSET(sock_fd, &setSave))
	handle_inputdata(conn_id, sock_fd);
    }

  /* Must be done at the end to make sure messages for current
   * working threads are processed first */
  if (FD_ISSET(listen_fd, &setSave))
    accept_new_client();
}

/*-------------------------------------------------------------------------*/
/** \brief Connection thread: wait on xml message and pass the command
 * to the work thread.
 *
 * \param[in] sock_xml: socket xml on which it receives commands.
 *
 */
/*-------------------------------------------------------------------------*/
static void
cli_server(void *data)
{
  int i;

  /* Initialize exalog */
  exalog_as(EXAMSG_ADMIND_ID);
  exalog_debug("cli_server: started");

  /* Initialization */
  FD_ZERO(&setSocks);
  FD_SET(listen_fd, &setSocks);

  for (i = 0; i < MAX_CONNECTION; i++)
    {
      connectlist[i].fd  = -1;
      /* A command cannot be CMD_UID_INVALID, so CMD_UID_INVALID means here
       * no command running */
      connectlist[i].uid = CMD_UID_INVALID;
    }

  while (!stop)
    {
      check_tcp_connection();
      check_internal_msg();
    }

  os_closesocket(listen_fd);

  os_net_cleanup();

  examsgDelMbox(cli_mh, EXAMSG_ADMIND_CLISERVER_ID);
  examsgExit(cli_mh);
}

int
cli_server_start(void)
{
  listen_fd = listen_socket_port(ADMIND_SOCKET_PORT);
  if (listen_fd < 0)
    return listen_fd;

  cli_mh = examsgInit(EXAMSG_ADMIND_CLISERVER_ID);
  if (!cli_mh)
    return -EINVAL;

  /* The mailbox needs to be able to receive command end messages from the
   * event manager; as there can be at most MAX_CONNECTION client connections
   * we can receive at the time at most 10 command end messages. */
  examsgAddMbox(cli_mh, EXAMSG_ADMIND_CLISERVER_ID, MAX_CONNECTION,
	        sizeof(command_end_t));

  stop = false;

  if (!exathread_create_named(&thr_xml_proto,
                              ADMIND_THREAD_STACK_SIZE+MIN_THREAD_STACK_SIZE,
                              &cli_server, NULL, "exa_adm_xml"))
      return -EXA_ERR_DEFAULT;

  return EXA_SUCCESS;
}