Beispiel #1
0
static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int secondary_backend)
{
	int fd;

	if (secondary_backend)
	{
		if (*pool_config.secondary_backend_host_name == '\0')
			fd = connect_unix_domain_socket(1);
		else
			fd = connect_inet_domain_socket(1);
	}
	else
	{
		if (*pool_config.current_backend_host_name == '\0')
			fd = connect_unix_domain_socket(0);
		else
			fd = connect_inet_domain_socket(0);
	}

	if (fd < 0)
	{
		/* fatal error, notice to parent and exit */
		notice_backend_error(!secondary_backend);
		exit(1);
	}

	cp->con = pool_open(fd);
	cp->closetime = 0;
	return cp;
}
/*
 * create connection pool
 */
static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot)
{
	BackendInfo *b = &pool_config->backend_desc->backend_info[slot];
	int fd;

	if (*b->backend_hostname == '/')
	{
		fd = connect_unix_domain_socket(slot, TRUE);
	}
	else
	{
		fd = connect_inet_domain_socket(slot, TRUE);
	}

	if (fd < 0)
	{
		pool_error("connection to %s(%d) failed", b->backend_hostname, b->backend_port);
		return NULL;
	}

	cp->sp = NULL;
	cp->con = pool_open(fd);
	cp->closetime = 0;
	return cp;
}
Beispiel #3
0
gpointer
idle_thread_func(gpointer user_data)
{
  PluginOption *option = ((ThreadData *)user_data)->option;
  int thread_index = ((ThreadData *)user_data)->index;

  int sock_type = SOCK_STREAM;

  if (sock_type_d)
    sock_type = SOCK_DGRAM;
  if (sock_type_s)
    sock_type = SOCK_STREAM;

  int fd;
  if (unix_socket_x)
    fd = connect_unix_domain_socket(sock_type, option->target);
  else
    fd = connect_ip_socket(sock_type, option->target, option->port, option->use_ipv6);

  if (fd<0)
    {
      ERROR("can not connect to %s:%s (%p)\n",option->target, option->port,g_thread_self());
    }
  else
    {
      DEBUG("(%d) connected to server on socket %d (%p)\n",thread_index,fd,g_thread_self());
    }

  g_mutex_lock(thread_lock);
  connect_finished++;

  if (connect_finished == active_thread_count + idle_thread_count)
    g_cond_broadcast(thread_connected);

  g_mutex_unlock(thread_lock);

  DEBUG("thread (%s,%p) created. wait for start ...\n",loggen_plugin_info.name,g_thread_self());
  g_mutex_lock(thread_lock);
  while (!thread_run)
    {
      g_cond_wait(thread_start,thread_lock);
    }
  g_mutex_unlock(thread_lock);

  DEBUG("thread (%s,%p) started. (r=%d,c=%d)\n",loggen_plugin_info.name,g_thread_self(),option->rate,
        option->number_of_messages);

  while (fd > 0 && thread_run && active_thread_count>0)
    {
      g_usleep(10*1000);
    }

  g_mutex_lock(thread_lock);
  idle_thread_count--;
  g_mutex_unlock(thread_lock);

  close(fd);
  g_thread_exit(NULL);
  return NULL;
}
Beispiel #4
0
/*
 * process cancel request
 */
void cancel_request(CancelPacket *sp)
{
	int	len;
	int fd;
	POOL_CONNECTION *con;
	int i,j,k;
	ConnectionInfo *c = NULL;
	CancelPacket cp;
	bool found = false;

	pool_debug("Cancel request received");

	/* look for cancel key from shmem info */
	for (i=0;i<pool_config->num_init_children;i++)
	{
		for (j=0;j<pool_config->max_pool;j++)
		{
			for (k=0;k<NUM_BACKENDS;k++)
			{
				c = pool_coninfo(i, j, k);
				pool_debug("con_info: address:%p database:%s user:%s pid:%d key:%d i:%d",
						   c, c->database, c->user, ntohl(c->pid), ntohl(c->key),i);

				if (c->pid == sp->pid && c->key == sp->key)
				{
					pool_debug("found pid:%d key:%d i:%d",ntohl(c->pid), ntohl(c->key),i);
					c = pool_coninfo(i, j, 0);
					found = true;
					goto found;
				}
			}
		}
	}

 found:
	if (!found)
	{
		pool_error("cancel_request: invalid cancel key: pid:%d key:%d",ntohl(sp->pid), ntohl(sp->key));
		return;	/* invalid key */
	}

	for (i=0;i<NUM_BACKENDS;i++,c++)
	{
		if (!VALID_BACKEND(i))
			continue;

		if (*(BACKEND_INFO(i).backend_hostname) == '/')
			fd = connect_unix_domain_socket(i, TRUE);
		else
			fd = connect_inet_domain_socket(i, TRUE);

		if (fd < 0)
		{
			pool_error("Could not create socket for sending cancel request for backend %d", i);
			return;
		}

		con = pool_open(fd);
		if (con == NULL)
			return;

		len = htonl(sizeof(len) + sizeof(CancelPacket));
		pool_write(con, &len, sizeof(len));

		cp.protoVersion = sp->protoVersion;
		cp.pid = c->pid;
		cp.key = c->key;

		pool_log("cancel_request: canceling backend pid:%d key: %d", ntohl(cp.pid),ntohl(cp.key));

		if (pool_write_and_flush(con, &cp, sizeof(CancelPacket)) < 0)
			pool_error("Could not send cancel request packet for backend %d", i);

		pool_close(con);

		/*
		 * this is needed to ensure that the next DB node executes the
		 * query supposed to be canceled.
		 */
		sleep(1);
	}
}
Beispiel #5
0
/*
 * check if we can connect to the backend
 * returns 0 for ok. otherwise returns backend id + 1
 */
int health_check(void)
{
	int fd;
	int sts;

	/* V2 startup packet */
	typedef struct {
		int len;		/* startup packet length */
		StartupPacket_v2 sp;
	} MySp;
	MySp mysp;
	char kind;
	int i;

	if (*InRecovery)
		return 0;

	memset(&mysp, 0, sizeof(mysp));
	mysp.len = htonl(296);
	mysp.sp.protoVersion = htonl(PROTO_MAJOR_V2 << 16);
	strcpy(mysp.sp.database, "template1");
	strncpy(mysp.sp.user, pool_config->health_check_user, sizeof(mysp.sp.user) - 1);
	*mysp.sp.options = '\0';
	*mysp.sp.unused = '\0';
	*mysp.sp.tty = '\0';

	for (i=0;i<pool_config->backend_desc->num_backends;i++)
	{
		pool_debug("health_check: %d th DB node status: %d", i, BACKEND_INFO(i).backend_status);

		if (BACKEND_INFO(i).backend_status == CON_UNUSED ||
			BACKEND_INFO(i).backend_status == CON_DOWN)
			continue;

		if (*(BACKEND_INFO(i).backend_hostname) == '\0')
			fd = connect_unix_domain_socket(i);
		else
			fd = connect_inet_domain_socket(i);

		if (fd < 0)
		{
			pool_error("health check failed. %d th host %s at port %d is down",
					   i,
					   BACKEND_INFO(i).backend_hostname,
					   BACKEND_INFO(i).backend_port);

			return i+1;
		}

		if (write(fd, &mysp, sizeof(mysp)) < 0)
		{
			pool_error("health check failed during write. host %s at port %d is down. reason: %s",
					   BACKEND_INFO(i).backend_hostname,
					   BACKEND_INFO(i).backend_port,
					   strerror(errno));
			close(fd);
			return i+1;
		}

		/*
		 * Don't bother to be blocked by read(2). It will be
		 * interrupted by ALRAM anyway.
		 */
		sts = read(fd, &kind, 1);
		if (sts == -1)
		{
			pool_error("health check failed during read. host %s at port %d is down. reason: %s",
					   BACKEND_INFO(i).backend_hostname,
					   BACKEND_INFO(i).backend_port,
					   strerror(errno));
			close(fd);
			return i+1;
		}
		else if (sts == 0)
		{
			pool_error("health check failed. EOF encountered. host %s at port %d is down",
					   BACKEND_INFO(i).backend_hostname,
					   BACKEND_INFO(i).backend_port);
			close(fd);
			return i+1;
		}

		/*
		 * If a backend raised a FATAL error(max connections error or
		 * starting up error?), do not send a Terminate message.
		 */
		if ((kind != 'E') && (write(fd, "X", 1) < 0))
		{
			pool_error("health check failed during write. host %s at port %d is down. reason: %s. Perhaps wrong health check user?",
					   BACKEND_INFO(i).backend_hostname,
					   BACKEND_INFO(i).backend_port,
					   strerror(errno));
			close(fd);
			return i+1;
		}

		close(fd);
	}

	return 0;
}
Beispiel #6
0
gpointer
active_thread_func(gpointer user_data)
{
  ThreadData *thread_context = (ThreadData *)user_data;
  PluginOption *option = thread_context->option;

  int sock_type = SOCK_STREAM;

  if (sock_type_d)
    sock_type = SOCK_DGRAM;
  if (sock_type_s)
    sock_type = SOCK_STREAM;

  char *message = g_malloc0(MAX_MESSAGE_LENGTH+1);

  int fd;
  if (unix_socket_x)
    fd = connect_unix_domain_socket(sock_type, option->target);
  else
    fd = connect_ip_socket(sock_type, option->target, option->port, option->use_ipv6);

  if (fd<0)
    {
      ERROR("can not connect to %s:%s (%p)\n",option->target, option->port,g_thread_self());
    }
  else
    {
      DEBUG("(%d) connected to server on socket %d (%p)\n",thread_context->index,fd,g_thread_self());
    }

  g_mutex_lock(thread_lock);
  connect_finished++;

  if (connect_finished == active_thread_count + idle_thread_count)
    g_cond_broadcast(thread_connected);

  g_mutex_unlock(thread_lock);

  DEBUG("thread (%s,%p) created. wait for start ...\n",loggen_plugin_info.name,g_thread_self());
  g_mutex_lock(thread_lock);
  while (!thread_run)
    {
      g_cond_wait(thread_start,thread_lock);
    }
  g_mutex_unlock(thread_lock);

  DEBUG("thread (%s,%p) started. (r=%d,c=%d)\n",loggen_plugin_info.name,g_thread_self(),option->rate,
        option->number_of_messages);

  unsigned long count = 0;
  thread_context->buckets = thread_context->option->rate - (thread_context->option->rate / 10);

  gettimeofday(&thread_context->last_throttle_check, NULL);
  gettimeofday(&thread_context->start_time, NULL);

  gboolean connection_error = FALSE;

  while (fd>0 && thread_run && !connection_error)
    {
      if (thread_check_exit_criteria(thread_context))
        break;

      if (thread_check_time_bucket(thread_context))
        continue;

      if (!generate_message)
        {
          ERROR("generate_message not yet set up(%p)\n",g_thread_self());
          break;
        }

      int str_len = generate_message(message, MAX_MESSAGE_LENGTH, thread_context->index, count++);

      if (str_len < 0)
        {
          ERROR("can't generate more log lines. end of input file?\n");
          break;
        }

      ssize_t sent = 0;
      while (sent < strlen(message))
        {
          ssize_t rc = send_plain(fd, message + sent, strlen(message) - sent);
          if (rc < 0)
            {
              ERROR("error sending buffer on %d (rc=%zd)\n",fd,rc);
              errno = ECONNABORTED;
              connection_error = TRUE;
              break;
            }
          sent += rc;
        }

      thread_context->sent_messages++;
      thread_context->buckets--;
    }
  DEBUG("thread (%s,%p) finished\n",loggen_plugin_info.name,g_thread_self());

  g_free((gpointer)message);
  g_mutex_lock(thread_lock);
  active_thread_count--;
  g_mutex_unlock(thread_lock);

  close(fd);
  g_thread_exit(NULL);
  return NULL;
}