pgpool2.git / summary / log / commit / refs
commit bc03514b124de01176d5ded220f33cabff742ade
Author: Masaya Kawamoto <kawamoto@sraoss.co.jp>
Date: Wed Jul 20 07:13:27 2022 +0000
Support for unix_socket_directories and related parameters
Support for unix_socket_directories, unix_socket_group and
unix_socket_permissions.
doc.ja/src/sgml/connection-settings.sgml | 97 ++++++++++++++++--
doc/src/sgml/connection-settings.sgml | 67 +++++++++++--
src/config/pool_config_variables.c | 50 +++++++++-
src/include/pool_config.h | 5 +-
src/main/pgpool_main.c | 109 +++++++++++++++++---
src/protocol/child.c | 18 +++-
src/sample/pgpool.conf.sample-stream | 10 +-
src/test/pgpool_setup.in | 2 +-
.../tests/035.unix_socket_directories/test.sh | 110 +++++++++++++++++++++
src/test/watchdog_setup.in | 2 +-
src/utils/pool_process_reporting.c | 25 ++++-
11 files changed, 448 insertions(+), 47 deletions(-)
diff --git a/doc.ja/src/sgml/connection-settings.sgml b/doc.ja/src/sgml/connection-settings.sgml
index 53b7dbbd2..079bf4442 100644
--- a/doc.ja/src/sgml/connection-settings.sgml
+++ b/doc.ja/src/sgml/connection-settings.sgml
@@ -93,25 +93,27 @@
</listitem>
</varlistentry>
- <varlistentry id="guc-socket-dir" xreflabel="socket_dir">
- <term><varname>socket_dir</varname> (<type>string</type>)
+ <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
+ <term><varname>unix_socket_directories</varname> (<type>string</type>)
<indexterm>
<!--
- <primary><varname>socket_dir</varname> configuration parameter</primary>
+ <primary><varname>unix_socket_directories</varname> configuration parameter</primary>
-->
- <primary><varname>socket_dir</varname> 設定パラメータ</primary>
+ <primary><varname>unix_socket_directories</varname> 設定パラメータ</primary>
</indexterm>
</term>
<listitem>
<para>
<!--
- The directory where the UNIX domain socket accepting connections for
- <productname>Pgpool-II</productname> will be
- created. Default is <literal>/tmp</literal>. Be aware that this
- socket might be deleted by a cron job. We recommend to set this
- value to <literal>/var/run</literal> or such directory.
+ The directory where the UNIX domain socket(s) accepting connections for
+ <productname>Pgpool-II</productname> will be created. Multiple sockets
+ can be created by listing multiple directories separated by commas. Default
+ is <literal>/tmp</literal>. Be aware that this sockets might be deleted
+ by a cron job. We recommend to set this value to <literal>/var/run</literal>
+ or such directory.
-->
<productname>Pgpool-II</productname>が接続を受け付けるUNIXドメインソケットを置くディレクトリです。
+ コンマで区切った複数のディレクトリのリストを設定すると複数のUNIXドメインソケットファイルを作成します。
デフォルト値は<literal>/tmp</literal>です。
このソケットは、cron によって削除されることがあるので注意してください。
<literal>/var/run</literal>などのディレクトリに変更することをお勧めします。
@@ -125,6 +127,83 @@
</listitem>
</varlistentry>
+ <varlistentry id="guc-unix-socket-group" xreflabel="unix_socket_group">
+ <term><varname>unix_socket_group</varname> (<type>string</type>)
+ <indexterm>
+ <!--
+ <primary><varname>unix_socket_group</varname> configuration parameter</primary>
+ -->
+ <primary><varname>unix_socket_group</varname> 設定パラメータ</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <!--
+ Sets the owning group of the Unix-domain socket(s). (The owning user of
+ the sockets is always the user that starts the server.) In combination
+ with the parameter <varname>unix_socket_permissions</varname> this can be
+ used as an additional access control mechanism for Unix-domain connections.
+ By default this is the empty string, which uses the default group of the
+ server user.
+ -->
+ UNIXドメインソケット(複数も)を所有するグループを設定します(ソケットを所有するユーザは常にサーバを起動するユーザです)。
+ <varname>unix_socket_permissions</varname>パラメータとの組合せで、UNIXドメインソケット接続の追加的アクセス管理機構として使うことができます。
+ デフォルトでは空文字列で、サーバユーザのデフォルトグループを使用します。
+ </para>
+ <para>
+ <!--
+ This parameter can only be set at server start.
+ -->
+ このパラメータはサーバ起動時にのみ設定可能です。
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-permissions" xreflabel="unix_socket_permissions">
+ <term><varname>unix_socket_permissions</varname> (<type>integer</type>)
+ <indexterm>
+ <!--
+ <primary><varname>unix_socket_permissions</varname> configuration parameter</primary>
+ -->
+ <primary><varname>unix_socket_permissions</varname> 設定パラメータ</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <!--
+ Sets the access permissions of the Unix-domain socket(s). Unix-domain
+ sockets use the usual Unix file system permission set. The parameter value
+ is expected to be a numeric mode specified in the format accepted by the
+ chmod and umask system calls. (To use the customary octal format the number
+ must start with a <literal>0</literal> (zero).)
+ -->
+ UNIXドメインソケット(複数も)のアクセスパーミッションを設定します。
+ UNIXドメインソケットは通常のUNIXファイルシステムパーミッション設定の一式を使用します。
+ パラメータ値は、<command>chmod</command>および<command>umask</command>システムコールが受け付ける数値形式での指定を想定しています。
+ (通常使われる8進数形式を使用するのであれば、<literal>0</literal>(ゼロ)で始まらなければなりません。)
+ </para>
+ <para>
+ <!--
+ The default permissions are <literal>0777</literal>, meaning anyone can
+ connect. Reasonable alternatives are <literal>0770</literal> (only user
+ and group, see also <varname>unix_socket_group</varname>) and
+ <literal>0700</literal> (only user). (Note that for a Unix-domain socket,
+ only write permission matters, so there is no point in setting or revoking
+ read or execute permissions.)
+ -->
+ デフォルトのパーミッションは、誰でも接続できる0777になっています。
+ 変更するならば<literal>0770</literal>(ユーザとグループのみです。<varname>unix_socket_group</varname>も参照してください)や<literal>0700</literal>(ユーザのみ)が適切です。
+ (UNIXドメインソケットでは書き込み権限だけが問題になるため、読み込みや実行のパーミッションを設定または解除する意味はありません。)
+ </para>
+ <para>
+ <!--
+ This parameter can only be set at server start.
+ -->
+ このパラメータはサーバ起動時にのみ設定可能です。
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-pcp-listen-addresses" xreflabel="pcp_listen_addresses">
<term><varname>pcp_listen_addresses</varname> (<type>string</type>)
<indexterm>
diff --git a/doc/src/sgml/connection-settings.sgml b/doc/src/sgml/connection-settings.sgml
index 41c4b631c..78a2540b5 100644
--- a/doc/src/sgml/connection-settings.sgml
+++ b/doc/src/sgml/connection-settings.sgml
@@ -61,20 +61,69 @@
</listitem>
</varlistentry>
- <varlistentry id="guc-socket-dir" xreflabel="socket_dir">
- <term><varname>socket_dir</varname> (<type>string</type>)
+ <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
+ <term><varname>unix_socket_directories</varname> (<type>string</type>)
<indexterm>
- <primary><varname>socket_dir</varname> configuration parameter</primary>
+ <primary><varname>unix_socket_directories</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
- The directory where the UNIX domain socket accepting connections for
- <productname>Pgpool-II</productname> will be
- created. Default is <literal>/tmp</literal>. Be aware that
- this socket might be deleted by a cron job. We recommend
- to set this value to <literal>/var/run</literal> or such
- directory.
+ The directory where the UNIX domain socket(s) accepting connections for
+ <productname>Pgpool-II</productname> will be created. Multiple sockets
+ can be created by listing multiple directories separated by commas. Default
+ is <literal>/tmp</literal>. Be aware that this sockets might be deleted
+ by a cron job. We recommend to set this value to <literal>/var/run</literal>
+ or such directory.
+ </para>
+ <para>
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-group" xreflabel="unix_socket_group">
+ <term><varname>unix_socket_group</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>unix_socket_group</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the owning group of the Unix-domain socket(s). (The owning user of
+ the sockets is always the user that starts the server.) In combination
+ with the parameter <varname>unix_socket_permissions</varname> this can be
+ used as an additional access control mechanism for Unix-domain connections.
+ By default this is the empty string, which uses the default group of the
+ server user.
+ </para>
+ <para>
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-permissions" xreflabel="unix_socket_permissions">
+ <term><varname>unix_socket_permissions</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>unix_socket_permissions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the access permissions of the Unix-domain socket(s). Unix-domain
+ sockets use the usual Unix file system permission set. The parameter value
+ is expected to be a numeric mode specified in the format accepted by the
+ chmod and umask system calls. (To use the customary octal format the number
+ must start with a <literal>0</literal> (zero).)
+ </para>
+ <para>
+ The default permissions are <literal>0777</literal>, meaning anyone can
+ connect. Reasonable alternatives are <literal>0770</literal> (only user
+ and group, see also <varname>unix_socket_group</varname>) and
+ <literal>0700</literal> (only user). (Note that for a Unix-domain socket,
+ only write permission matters, so there is no point in setting or revoking
+ read or execute permissions.)
</para>
<para>
This parameter can only be set at server start.
diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c
index 90446bd79..fe1bfd718 100644
--- a/src/config/pool_config_variables.c
+++ b/src/config/pool_config_variables.c
@@ -51,6 +51,7 @@
#define default_reset_query_list "ABORT;DISCARD ALL"
#define default_listen_addresses_list "localhost"
#define default_pcp_listen_addresses_list "localhost"
+#define default_unix_socket_directories_list "/tmp"
#define default_read_only_function_list ""
#define default_write_function_list ""
@@ -107,6 +108,8 @@ static char **get_list_from_string_regex_delim(const char *str, const char *deli
/*show functions */
static const char *IntValueShowFunc(int value);
+static const char *FilePermissionShowFunc(int value);
+static const char *UnixSockPermissionsShowFunc(void);
static const char *HBDestinationPortShowFunc(int index);
static const char *HBDeviceShowFunc(int index);
static const char *HBHostnameShowFunc(int index);
@@ -815,12 +818,12 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"socket_dir", CFGCXT_INIT, CONNECTION_CONFIG,
- "The directory to create the UNIX domain socket for accepting pgpool-II client connections.",
+ {"unix_socket_group", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The owning user of the sockets that always starts the server.",
CONFIG_VAR_TYPE_STRING, false, 0
},
- &g_pool_config.socket_dir,
- DEFAULT_SOCKET_DIR,
+ &g_pool_config.unix_socket_group,
+ "",
NULL, NULL, NULL, NULL
},
@@ -1353,6 +1356,19 @@ static struct config_string_list ConfigureNamesStringList[] =
NULL, NULL, NULL
},
+ {
+ {"unix_socket_directories", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The directories to create the UNIX domain sockets for accepting pgpool-II client connections.",
+ CONFIG_VAR_TYPE_STRING_LIST, false, 0
+ },
+ &g_pool_config.unix_socket_directories,
+ &g_pool_config.num_unix_socket_directories,
+ (const char *) default_unix_socket_directories_list,
+ ",",
+ false,
+ NULL, NULL, NULL
+ },
+
{
{"read_only_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG,
"list of functions that does not writes to database.",
@@ -1857,6 +1873,17 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"unix_socket_permissions", CFGCXT_INIT, CONNECTION_CONFIG,
+ "The access permissions of the Unix domain sockets.",
+ CONFIG_VAR_TYPE_INT, false, 0
+ },
+ &g_pool_config.unix_socket_permissions,
+ 0777,
+ 0000, 0777,
+ NULL, NULL, UnixSockPermissionsShowFunc
+ },
+
{
{"num_init_children", CFGCXT_INIT, CONNECTION_POOL_CONFIG,
"Number of children pre-forked for client connections.",
@@ -4320,6 +4347,21 @@ IntValueShowFunc(int value)
return buffer;
}
+static const char *
+FilePermissionShowFunc(int value)
+{
+ static char buffer[10];
+
+ snprintf(buffer, sizeof(buffer), "%04o", value);
+ return buffer;
+}
+
+static const char *
+UnixSockPermissionsShowFunc(void)
+{
+ return FilePermissionShowFunc(g_pool_config.unix_socket_permissions);
+}
+
static const char *
BackendWeightShowFunc(int index)
{
diff --git a/src/include/pool_config.h b/src/include/pool_config.h
index 13b3aa3d7..b6967cf28 100644
--- a/src/include/pool_config.h
+++ b/src/include/pool_config.h
@@ -207,7 +207,9 @@ typedef struct
int port; /* port # to bind */
char **pcp_listen_addresses; /* PCP listen address to listen on */
int pcp_port; /* PCP port # to bind */
- char *socket_dir; /* pgpool socket directory */
+ char **unix_socket_directories; /* pgpool socket directories */
+ char *unix_socket_group; /* owner group of pgpool sockets */
+ int unix_socket_permissions; /* pgpool sockets permissions */
char *wd_ipc_socket_dir; /* watchdog command IPC socket directory */
char *pcp_socket_dir; /* PCP socket directory */
int num_init_children; /* # of children initially pre-forked */
@@ -393,6 +395,7 @@ typedef struct
int num_reset_queries; /* number of queries in reset_query_list */
int num_listen_addresses; /* number of entries in listen_addresses */
int num_pcp_listen_addresses; /* number of entries in pcp_listen_addresses */
+ int num_unix_socket_directories; /* number of entries in unix_socket_directories */
int num_read_only_function_list; /* number of functions in
* read_only_function_list */
int num_write_function_list; /* number of functions in
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index 88ec3c872..fc551b662 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -60,7 +60,7 @@
#include "watchdog/wd_lifecheck.h"
#include "watchdog/watchdog.h"
#include "pcp/pcp_worker.h"
-
+#include <grp.h>
/*
* Reasons for signalling a pgpool-II main process
@@ -147,7 +147,8 @@ static void FileUnlink(int code, Datum path);
static pid_t pcp_fork_a_child(int *fds, char *pcp_conf_file);
static pid_t fork_a_child(int *fds, int id);
static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params);
-static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp);
+static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp, const char *group, const int permissions);
+static int *create_unix_domain_sockets_by_list(struct sockaddr_un *un_addrs, char *group, int permissions, int n_sockets);
static int *create_inet_domain_sockets(const char *hostname, const int port);
static int *create_inet_domain_sockets_by_list(char **listen_addresses, int n_listen_addresses, int port, int *n_sockets);
static void failover(void);
@@ -195,7 +196,7 @@ static void exec_notice_pcp_child(FAILOVER_CONTEXT *failover_context);
static void check_requests(void);
static void print_signal_member(sigset_t *sig);
-static struct sockaddr_un un_addr; /* unix domain socket path */
+static struct sockaddr_un *un_addrs; /* unix domain socket path */
static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */
ProcessInfo *process_info = NULL; /* Per child info table on shmem */
volatile User1SignalSlot *user1SignalSlot = NULL; /* User 1 signal slot on
@@ -304,9 +305,17 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
on_system_exit(system_will_go_down, (Datum) NULL);
/* set unix domain socket path for connections to pgpool */
- snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d",
- pool_config->socket_dir,
- pool_config->port);
+ un_addrs = malloc(sizeof(struct sockaddr_un) * pool_config->num_unix_socket_directories);
+ if (un_addrs == NULL)
+ ereport(FATAL,
+ (errmsg("failed to allocate memory in startup process")));
+
+ for (i = 0; i < pool_config->num_unix_socket_directories; i++)
+ {
+ snprintf(un_addrs[i].sun_path, sizeof(un_addrs[i].sun_path), "%s/.s.PGSQL.%d",
+ pool_config->unix_socket_directories[i],
+ pool_config->port);
+ }
/* set unix domain socket path for pgpool PCP communication */
snprintf(pcp_un_addr.sun_path, sizeof(pcp_un_addr.sun_path), "%s/.s.PGSQL.%d",
pool_config->pcp_socket_dir,
@@ -406,14 +415,20 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
}
/* create unix domain socket */
- fds = malloc(sizeof(int) * (num_fds + 2));
+ fds = malloc(sizeof(int) * (pool_config->num_unix_socket_directories + 1));
if (fds == NULL)
ereport(FATAL,
(errmsg("failed to allocate memory in startup process")));
- fds[0] = create_unix_domain_socket(un_addr);
- fds[1] = -1;
- on_proc_exit(FileUnlink, (Datum) un_addr.sun_path);
+ fds = create_unix_domain_sockets_by_list(un_addrs,
+ pool_config->unix_socket_group,
+ pool_config->unix_socket_permissions,
+ pool_config->num_unix_socket_directories);
+ fds[pool_config->num_unix_socket_directories] = -1;
+ for (i = 0; i < pool_config->num_unix_socket_directories; i++)
+ {
+ on_proc_exit(FileUnlink, (Datum) un_addrs[i].sun_path);
+ }
/* create inet domain socket if any */
inet_fds = create_inet_domain_sockets_by_list(pool_config->listen_addresses, pool_config->num_listen_addresses,
@@ -422,8 +437,8 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
/* copy inet domain sockets if any */
if (num_fds > 0)
{
- memcpy(&fds[1], inet_fds, sizeof(int) * num_fds);
- fds[num_fds + 1] = -1;
+ memcpy(&fds[pool_config->num_unix_socket_directories], inet_fds, sizeof(int) * num_fds);
+ fds[pool_config->num_unix_socket_directories + num_fds] = -1;
free(inet_fds);
}
@@ -470,7 +485,7 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
ereport(FATAL,
(errmsg("failed to allocate memory in startup process")));
- pcp_fds[0] = create_unix_domain_socket(pcp_un_addr);
+ pcp_fds[0] = create_unix_domain_socket(pcp_un_addr, "", 0777);
pcp_fds[1] = -1;
on_proc_exit(FileUnlink, (Datum) pcp_un_addr.sun_path);
@@ -951,7 +966,7 @@ create_inet_domain_sockets(const char *hostname, const int port)
* create UNIX domain socket
*/
static int
-create_unix_domain_socket(struct sockaddr_un un_addr_tmp)
+create_unix_domain_socket(struct sockaddr_un un_addr_tmp, const char *group, const int permissions)
{
struct sockaddr_un addr;
int fd;
@@ -980,7 +995,39 @@ create_unix_domain_socket(struct sockaddr_un un_addr_tmp)
errdetail("bind socket failed with error: \"%m\"")));
}
- if (chmod(un_addr_tmp.sun_path, 0777) == -1)
+ if (*group != '\0')
+ {
+ char *endptr;
+ gid_t gid;
+ unsigned long val;
+
+ /* check group*/
+ val = strtoul(group, &endptr, 10);
+ if (*endptr == '\0')
+ {
+ gid = val;
+ }
+ else
+ {
+ struct group *gr;
+ gr = getgrnam(group);
+ if(!gr)
+ {
+ ereport(FATAL,
+ (errmsg("unix_socket_group \"%s\" does not exist", group)));
+ }
+ gid = gr->gr_gid;
+ }
+
+ if (chown(un_addr_tmp.sun_path, -1, gid) == -1)
+ {
+ ereport(FATAL,
+ (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path),
+ errdetail("system call chown failed with error: \"%m\"")));
+ }
+ }
+
+ if (chmod(un_addr_tmp.sun_path, permissions) == -1)
{
ereport(FATAL,
(errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path),
@@ -4621,6 +4668,38 @@ exec_notice_pcp_child(FAILOVER_CONTEXT *failover_context)
*/
+/*
+ * Create UNIX domain sockets by unix_socket_directories, which is an array of
+ string. The number of elements is
+ * "n_listen_addresses". "port" is the port number. A socket array is returned.
+ * The number of elements in the socket array is "n_sockets".
+ */
+static int *
+create_unix_domain_sockets_by_list(struct sockaddr_un *un_addrs,
+ char *group, int permissions, int n_sockets)
+{
+ int i;
+ int *sockets = NULL;
+
+ if (un_addrs == NULL)
+ return NULL;
+
+ sockets = malloc(sizeof(int) * n_sockets);
+ if (sockets == NULL)
+ ereport(FATAL,
+ (errmsg("failed to allocate memory in startup process")));
+
+ for (i = 0; i < n_sockets; i++)
+ {
+ ereport(LOG,
+ (errmsg("unix_socket_directories[%d]: %s", i, un_addrs[i].sun_path)));
+
+ sockets[i] = create_unix_domain_socket(un_addrs[i], group, permissions);
+ }
+
+ return sockets;
+}
+
/*
* Create INET domain sockets by specified listen address list
* "listen_addresses", which is an array of string. The number of elements is
diff --git a/src/protocol/child.c b/src/protocol/child.c
index 962f1e4c2..9056a29a9 100644
--- a/src/protocol/child.c
+++ b/src/protocol/child.c
@@ -98,6 +98,8 @@ static bool backend_cleanup(POOL_CONNECTION * volatile *frontend, POOL_CONNECTIO
static void child_will_go_down(int code, Datum arg);
static int opt_sort(const void *a, const void *b);
+static bool unix_fds_not_isset(int* fds, int num_unix_fds, fd_set* opt);
+
/*
* Non 0 means SIGTERM (smart shutdown) or SIGINT (fast shutdown) has arrived
*/
@@ -1664,7 +1666,7 @@ retry_accept:
* Set no delay if AF_INET socket. Not sure if this is really necessary
* but PostgreSQL does this.
*/
- if (!FD_ISSET(fds[0], &rmask)) /* fds[0] is UNIX domain socket */
+ if (unix_fds_not_isset(fds, pool_config->num_unix_socket_directories, &rmask))
{
on = 1;
if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY,
@@ -1695,6 +1697,20 @@ retry_accept:
return afd;
}
+static bool
+unix_fds_not_isset(int* fds, int num_unix_fds, fd_set* opt)
+{
+ int i;
+ for (i = 0; i < num_unix_fds; i++)
+ {
+ if (!FD_ISSET(fds[i], opt))
+ continue;
+
+ return false;
+ }
+ return true;
+}
+
static void
check_config_reload(void)
{
diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream
index 312014a4c..87678c7ec 100644
--- a/src/sample/pgpool.conf.sample-stream
+++ b/src/sample/pgpool.conf.sample-stream
@@ -39,11 +39,17 @@ backend_clustering_mode = 'streaming_replication'
#port = 9999
# Port number
# (change requires restart)
-#socket_dir = '/tmp'
- # Unix domain socket path
+#unix_socket_directories = '/tmp'
+ # Unix domain socket path(s)
# The Debian package defaults to
# /var/run/postgresql
# (change requires restart)
+#unix_socket_group = ''
+ # The Owner group of Unix domain socket(s)
+ # (change requires restart)
+#unix_socket_premissions = 0777
+ # Permissions of Unix domain socket(s)
+ # (change requires restart)
#reserved_connections = 0
# Number of reserved connections.
# Pgpool-II does not accept connections if over
diff --git a/src/test/pgpool_setup.in b/src/test/pgpool_setup.in
index 880a6b93a..5ace6d488 100644
--- a/src/test/pgpool_setup.in
+++ b/src/test/pgpool_setup.in
@@ -887,7 +887,7 @@ function set_pgpool_conf {
echo "failover_command = '$FAILOVER_SCRIPT %d %h %p %D %m %H %M %P %r %R %N %S'" >> $CONF
fi
- echo "socket_dir = '$PGSOCKET_DIR'" >> $CONF
+ echo "unix_socket_directories = '$PGSOCKET_DIR'" >> $CONF
echo "pcp_socket_dir = '$PGSOCKET_DIR'" >> $CONF
echo "logging_collector = off" >> $CONF
echo "log_line_prefix = '%m: %a pid %p: '" >> $CONF
diff --git a/src/test/regression/tests/035.unix_socket_directories/test.sh b/src/test/regression/tests/035.unix_socket_directories/test.sh
new file mode 100755
index 000000000..e25f761df
--- /dev/null
+++ b/src/test/regression/tests/035.unix_socket_directories/test.sh
@@ -0,0 +1,110 @@
+#!/usr/bin/env bash
+#-------------------------------------------------------------------
+# test script for unix_socket_directories, unix_socket_group and unix_socket_permissions.
+# unix_socket_group test works if UNIX_SOCK_GROUP exists and the user running
+# this test belongs to it. Therefore, we usually comment out it.
+#
+source $TESTLIBS
+TESTDIR=testdir
+PSQL=$PGBIN/psql
+
+for mode in s
+do
+ rm -fr $TESTDIR
+ mkdir $TESTDIR
+ cd $TESTDIR
+
+# create test environment
+ echo -n "creating test environment..."
+ $PGPOOL_SETUP -m $mode -n 2 || exit 1
+ echo "done."
+
+ source ./bashrc.ports
+ dir=`pwd`
+ UNIX_SOCK_PATH1=/tmp
+ UNIX_SOCK_PATH2=$dir/run
+ UNIX_SOCK_FILE=.s.PGSQL.$PGPOOL_PORT
+ UNIX_SOCK_GROUP=wheel
+ USER=`whoami`
+
+ echo "unix_socket_directories = '$UNIX_SOCK_PATH1,$UNIX_SOCK_PATH2'" >> etc/pgpool.conf
+<<COMMENT_OUT
+ echo "unix_socket_group = '$UNIX_SOCK_GROUP'" >> etc/pgpool.conf
+COMMENT_OUT
+ echo "unix_socket_permissions = 0770" >> etc/pgpool.conf
+
+ ./startall
+
+ export PGPORT=$PGPOOL_PORT
+
+ wait_for_pgpool_startup
+
+ echo check: multiple unix domain sokets
+ if [ ! -e $UNIX_SOCK_PATH1/$UNIX_SOCK_FILE ]; then
+ echo "fail: not exist $UNIX_SOCK_PATH1/$UNIX_SOCK_FILE"
+ ./shutdownall
+ exit 1
+ fi
+
+ if [ ! -e $UNIX_SOCK_PATH2/$UNIX_SOCK_FILE ]; then
+ echo "fail: not exist $UNIX_SOCK_PATH2/$UNIX_SOCK_FILE"
+ ./shutdownall
+ exit 1
+ fi
+ echo ok: multiple unix domain sockets
+
+ echo check: connect to unix domain sockets
+ res=`$PSQL -t -h $UNIX_SOCK_PATH1 test -c "SELECT 1"`
+ if [ $res -ne 1 ]; then
+ echo "fail: cannot connect to $UNIX_SOCK_PATH2/$UNIX_SOCK_FILE"
+ ./shutdownall
+ exit 1
+ fi
+
+ res=`$PSQL -t -h $UNIX_SOCK_PATH1 test -c "SELECT 1"`
+ if [ $res -ne 1 ]; then
+ echo "fail: cannot connect to $UNIX_SOCK_PATH2/$UNIX_SOCK_FILE"
+ ./shutdownall
+ exit 1
+ fi
+ echo ok: connect to unix domain sockets
+
+<<COMMENT_OUT
+ echo check: socket files owner group
+ ls -la $UNIX_SOCK_PATH1 | grep "$USER $UNIX_SOCK_GROUP.*$UNIX_SOCK_FILE"
+ if [ $? -ne 0 ]; then
+ echo fail: owner group setting $UNIX_SOCK_PATH1
+ ./shutdownall
+ exit 1
+ fi
+
+ ls -la $UNIX_SOCK_PATH2 | grep "$USER $UNIX_SOCK_GROUP.*$UNIX_SOCK_FILE"
+ if [ $? -ne 0 ]; then
+ echo fail: owner group setting $UNIX_SOCK_PATH2
+ ./shutdownall
+ exit 1
+ fi
+ echo ok: socket files owner group
+COMMENT_OUT
+
+ echo check: socket files permission
+ ls -la $UNIX_SOCK_PATH1 | grep "srwxrwx---.*$UNIX_SOCK_FILE"
+ if [ $? -ne 0 ]; then
+ echo fail: permission setting $UNIX_SOCK_PATH1
+ ./shutdownall
+ exit 1
+ fi
+
+ ls -la $UNIX_SOCK_PATH2 | grep "srwxrwx---.*$UNIX_SOCK_FILE"
+ if [ $? -ne 0 ]; then
+ echo fail: permission setting $UNIX_SOCK_PATH2
+ ./shutdownall
+ exit 1
+ fi
+ echo ok: socket files permission
+ echo ok: unix_socket_directories and related parameters are working.
+
+ ./shutdownall
+
+done
+exit 0
\ No newline at end of file
diff --git a/src/test/watchdog_setup.in b/src/test/watchdog_setup.in
index 966205d66..42ba2f752 100644
--- a/src/test/watchdog_setup.in
+++ b/src/test/watchdog_setup.in
@@ -124,7 +124,7 @@ function set_pgpool_conf {
echo "failover_command = '$FAILOVER_SCRIPT %d %h %p %D %m %M %H %P %r %R'" >> $CONF
fi
- echo "socket_dir = '$PGSOCKET_DIR'" >> $CONF
+ echo "unix_socket_directories = '$PGSOCKET_DIR'" >> $CONF
echo "pcp_socket_dir = '$PGSOCKET_DIR'" >> $CONF
}
diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c
index 2f9157a44..1dad43a92 100644
--- a/src/utils/pool_process_reporting.c
+++ b/src/utils/pool_process_reporting.c
@@ -208,10 +208,27 @@ get_config(int *nrows)
StrNCpy(status[i].desc, "pgpool accepting port number", POOLCONFIG_MAXDESCLEN);
i++;
- /* - pgpool Communication Manager Connection Settings - */
- StrNCpy(status[i].name, "socket_dir", POOLCONFIG_MAXNAMELEN);
- snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->socket_dir);
- StrNCpy(status[i].desc, "pgpool socket directory", POOLCONFIG_MAXDESCLEN);
+ StrNCpy(status[i].name, "unix_socket_directories", POOLCONFIG_MAXNAMELEN);
+ *(status[i].value) = '\0';
+ for (j = 0; j < pool_config->num_unix_socket_directories; j++)
+ {
+ len = POOLCONFIG_MAXVALLEN - strlen(status[i].value);
+ strncat(status[i].value, pool_config->unix_socket_directories[j], len);
+ len = POOLCONFIG_MAXVALLEN - strlen(status[i].value);
+ if (j != pool_config->num_unix_socket_directories - 1)
+ strncat(status[i].value, ",", len);
+ }
+ StrNCpy(status[i].desc, "pgpool socket directories", POOLCONFIG_MAXDESCLEN);
+ i++;
+
+ StrNCpy(status[i].name, "unix_socket_group", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->unix_socket_group);
+ StrNCpy(status[i].desc, "owning user of the unix sockets", POOLCONFIG_MAXDESCLEN);
+ i++;
+
+ StrNCpy(status[i].name, "unix_socket_permissions", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%04o", pool_config->unix_socket_permissions);
+ StrNCpy(status[i].desc, "access permissions of the unix sockets.", POOLCONFIG_MAXDESCLEN);
i++;
StrNCpy(status[i].name, "pcp_listen_addresses", POOLCONFIG_MAXNAMELEN);
[parent: b64496a1907e]