Пример #1
0
/*
 * send frontend exiting messages to all connections.  this is called
 * in any case when child process exits, for example failover, child
 * life time expires or child max connections expires.
 */
static void send_frontend_exits(void)
{
	int i;
	POOL_CONNECTION_POOL *p = pool_connection_pool;

#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	POOL_SETMASK2(&BlockSig, &oldmask);

	for (i=0;i<pool_config->max_pool;i++, p++)
	{
		if (!MASTER_CONNECTION(p))
			continue;
		if (!MASTER_CONNECTION(p)->sp)
			continue;
		if (MASTER_CONNECTION(p)->sp->user == NULL)
			continue;
		pool_send_frontend_exits(p);
	}

	POOL_SETMASK(&oldmask);
}
Пример #2
0
/*
* find connection by user and database
*/
POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket)
{
#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	int i;

	POOL_CONNECTION_POOL *p = pool_connection_pool;

	if (p == NULL)
	{
		pool_error("pool_get_cp: pool_connection_pool is not initialized");
		return NULL;
	}

	POOL_SETMASK2(&BlockSig, &oldmask);

	for (i=0;i<pool_config.max_pool;i++)
	{
		if (MASTER_CONNECTION(p) &&
			MASTER_CONNECTION(p)->sp->major == protoMajor &&
			MASTER_CONNECTION(p)->sp->user != NULL &&
			strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 &&
			strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0)
		{
			/* mark this connection is under use */
			MASTER_CONNECTION(p)->closetime = 0;
			POOL_SETMASK(&oldmask);

			if (check_socket &&
				(check_socket_status(MASTER(p)->fd) < 0 ||
				 (DUAL_MODE && check_socket_status(MASTER(p)->fd) < 0)))
			{
				pool_log("connection closed. retry to create new connection pool.");
				pool_free_startup_packet(MASTER_CONNECTION(p)->sp);
				pool_close(MASTER_CONNECTION(p)->con);
				free(MASTER_CONNECTION(p));

				if (DUAL_MODE)
				{
					pool_close(SECONDARY_CONNECTION(p)->con);
					free(SECONDARY_CONNECTION(p));
				}

				memset(p, 0, sizeof(POOL_CONNECTION_POOL));
				return NULL;
			}

			return p;
		}
		p++;
	}

	POOL_SETMASK(&oldmask);
	return NULL;
}
Пример #3
0
void pool_debug(const char *fmt,...)
{
	va_list		ap;
#ifdef HAVE_ASPRINTF
	char		*fmt2;
    int         len;
#endif

#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	if (run_as_pcp_child)
	{
		if (!debug)
			return;
	}
	else
	{
		if (pool_config->debug_level <= 0)
			return;
	}

	POOL_SETMASK2(&BlockSig, &oldmask);

	/* Write message to syslog */
	if (pool_config->logsyslog == 1)
	{
		va_start(ap, fmt);
		vsyslog(pool_config->syslog_facility | LOG_DEBUG, fmt, ap);
		va_end(ap);
		POOL_SETMASK(&oldmask);
		return;
	}

#ifdef HAVE_ASPRINTF
	len = asprintf(&fmt2, "%s %s\n", optstring(1), fmt);

	if (len >= 0 && fmt2)
	{
		va_start(ap, fmt);
		vfprintf(stderr, fmt2, ap);
		va_end(ap);
		fflush(stderr);
		free(fmt2);
	}
#else
	fprintf(stderr, "%s %s", optstring(1));

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, "\n");
#endif

	POOL_SETMASK(&oldmask);
}
Пример #4
0
/*
 * Count up connection counter (from frontend to pgpool)
 * in shared memory
 */
static void connection_count_up(void)
{
#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	POOL_SETMASK2(&BlockSig, &oldmask);
	pool_semaphore_lock(CONN_COUNTER_SEM);
	Req_info->conn_counter++;
	pool_semaphore_unlock(CONN_COUNTER_SEM);
	POOL_SETMASK(&oldmask);
}
Пример #5
0
void pool_error(const char *fmt,...)
{
	va_list		ap;
#ifdef HAVE_ASPRINTF
	char		*fmt2;
    int         len;
#endif

#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif
	POOL_SETMASK2(&BlockSig, &oldmask);

	/* Write error message to syslog */
	if (pool_config->logsyslog == 1) {
	   va_start(ap, fmt);
	   vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap);
	   va_end(ap);
	   POOL_SETMASK(&oldmask);
	   return;
	}

	if (pool_config->print_timestamp)
#ifdef HAVE_ASPRINTF
	  len = asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int)getpid(), fmt);
	else
	  len = asprintf(&fmt2, "ERROR: pid %d: %s\n", (int)getpid(), fmt);

   if (len >= 0 && fmt2)
   {
     va_start(ap, fmt);
     vfprintf(stderr, fmt2, ap);
     va_end(ap);
     fflush(stderr);
	 free(fmt2);
   }
#else
	  fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int)getpid());
	else
Пример #6
0
/*
 * Count down connection counter (from frontend to pgpool)
 * in shared memory
 */
static void connection_count_down(void)
{
#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	POOL_SETMASK2(&BlockSig, &oldmask);
	pool_semaphore_lock(CONN_COUNTER_SEM);
	/*
	 * Make sure that we do not decrement too much.  If failed to read
	 * a start up packet, or receive cancel request etc.,
	 * connection_count_down() is called and goes back to the
	 * connection accept loop. Problem is, at the very beginning of
	 * the connection accept loop, if we have received a signal, we
	 * call child_exit() which calls connection_count_down() again.
	 */
	if (Req_info->conn_counter > 0)
		Req_info->conn_counter--;
	pool_semaphore_unlock(CONN_COUNTER_SEM);
	POOL_SETMASK(&oldmask);
}
Пример #7
0
/*
* find connection by user and database
*/
POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket)
{
#ifdef HAVE_SIGPROCMASK
	sigset_t oldmask;
#else
	int	oldmask;
#endif

	int i, freed = 0;
	ConnectionInfo *info;

	POOL_CONNECTION_POOL *p = pool_connection_pool;

	if (p == NULL)
	{
		pool_error("pool_get_cp: pool_connection_pool is not initialized");
		return NULL;
	}

	POOL_SETMASK2(&BlockSig, &oldmask);

	for (i=0;i<pool_config->max_pool;i++)
	{
		if (MASTER_CONNECTION(p) &&
			MASTER_CONNECTION(p)->sp &&
			MASTER_CONNECTION(p)->sp->major == protoMajor &&
			MASTER_CONNECTION(p)->sp->user != NULL &&
			strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 &&
			strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0)
		{
			int sock_broken = 0;
			int j;

			/* mark this connection is under use */
			MASTER_CONNECTION(p)->closetime = 0;
			for (j=0;j<NUM_BACKENDS;j++)
			{
				p->info[j].counter++;
			}
			POOL_SETMASK(&oldmask);

			if (check_socket)
			{
				for (j=0;j<NUM_BACKENDS;j++)
				{
					if (!VALID_BACKEND(j))
						continue;

					if  (CONNECTION_SLOT(p, j))
					{
						sock_broken = check_socket_status(CONNECTION(p, j)->fd);
						if (sock_broken < 0)
							break;
					}
					else
					{
						sock_broken = -1;
						break;
					}
				}

				if (sock_broken < 0)
				{
					pool_log("connection closed. retry to create new connection pool.");
					for (j=0;j<NUM_BACKENDS;j++)
					{
						if (!VALID_BACKEND(j) || (CONNECTION_SLOT(p, j) == NULL))
							continue;

						if (!freed)
						{
							pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp);
							freed = 1;
						}

						pool_close(CONNECTION(p, j));
						free(CONNECTION_SLOT(p, j));
					}
					info = p->info;
					memset(p, 0, sizeof(POOL_CONNECTION_POOL_SLOT));
					p->info = info;
					memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
					POOL_SETMASK(&oldmask);
					return NULL;
				}
			}
			POOL_SETMASK(&oldmask);
			pool_index = i;
			return p;
		}
		p++;
	}

	POOL_SETMASK(&oldmask);
	return NULL;
}