|
|
6cb03e |
Back-port of upstream 9.3 patch to support multiple sockets
|
|
|
6cb03e |
(upstream git commits c9b0cbe98bd783e24a8c4d8d8ac472a494b81292 and
|
|
|
6cb03e |
d2286a98ef3fb88bafb57381b4c20b8b878827f1, plus updates of derived
|
|
|
6cb03e |
documentation files).
|
|
|
6cb03e |
|
|
|
6cb03e |
Note the patch also touches html-stamp and man-stamp in doc/src/sgml/;
|
|
|
6cb03e |
this is to keep the makefiles from trying to rebuild the derived doc
|
|
|
6cb03e |
files. We don't want that to happen because the BuildRequires for the
|
|
|
6cb03e |
package don't include the necessary documentation tools. Those diff
|
|
|
6cb03e |
hunks *must be at the end* so that those files are newer than the
|
|
|
6cb03e |
master doc files.
|
|
|
6cb03e |
|
|
|
6cb03e |
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
|
|
|
6cb03e |
index 0940e00..c5ecb84 100644
|
|
|
6cb03e |
--- a/contrib/pg_upgrade/server.c
|
|
|
6cb03e |
+++ b/contrib/pg_upgrade/server.c
|
|
|
6cb03e |
@@ -197,7 +197,8 @@ start_postmaster(ClusterInfo *cluster)
|
|
|
6cb03e |
snprintf(socket_string + strlen(socket_string),
|
|
|
6cb03e |
sizeof(socket_string) - strlen(socket_string),
|
|
|
6cb03e |
" -c %s='%s'",
|
|
|
6cb03e |
- (GET_MAJOR_VERSION(cluster->major_version) < 903) ?
|
|
|
6cb03e |
+ /* assume 9.1 build will not have unix_socket_directories patch */
|
|
|
6cb03e |
+ (GET_MAJOR_VERSION(cluster->major_version) < 902) ?
|
|
|
6cb03e |
"unix_socket_directory" : "unix_socket_directories",
|
|
|
6cb03e |
cluster->sockdir);
|
|
|
6cb03e |
#endif
|
|
|
6cb03e |
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
|
|
|
6cb03e |
index b9664cb..94e166d 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/client-auth.sgml
|
|
|
6cb03e |
+++ b/doc/src/sgml/client-auth.sgml
|
|
|
6cb03e |
@@ -838,7 +838,7 @@ omicron bryanh guest1
|
|
|
6cb03e |
<varname>unix_socket_permissions</varname> (and possibly
|
|
|
6cb03e |
<varname>unix_socket_group</varname>) configuration parameters as
|
|
|
6cb03e |
described in <xref linkend="runtime-config-connection">. Or you
|
|
|
6cb03e |
- could set the <varname>unix_socket_directory</varname>
|
|
|
6cb03e |
+ could set the <varname>unix_socket_directories</varname>
|
|
|
6cb03e |
configuration parameter to place the socket file in a suitably
|
|
|
6cb03e |
restricted directory.
|
|
|
6cb03e |
</para>
|
|
|
6cb03e |
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
|
|
|
6cb03e |
index 51d7da9..cb5c5d2 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/config.sgml
|
|
|
6cb03e |
+++ b/doc/src/sgml/config.sgml
|
|
|
6cb03e |
@@ -453,17 +453,24 @@ SET ENABLE_SEQSCAN TO OFF;
|
|
|
6cb03e |
</listitem>
|
|
|
6cb03e |
</varlistentry>
|
|
|
6cb03e |
|
|
|
6cb03e |
- <varlistentry id="guc-unix-socket-directory" xreflabel="unix_socket_directory">
|
|
|
6cb03e |
- <term><varname>unix_socket_directory</varname> (<type>string</type>)</term>
|
|
|
6cb03e |
+ <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
|
|
|
6cb03e |
+ <term><varname>unix_socket_directories</varname> (<type>string</type>)</term>
|
|
|
6cb03e |
<indexterm>
|
|
|
6cb03e |
- <primary><varname>unix_socket_directory configuration parameter</primary>
|
|
|
6cb03e |
+ <primary><varname>unix_socket_directories configuration parameter</primary>
|
|
|
6cb03e |
</indexterm>
|
|
|
6cb03e |
<listitem>
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
- Specifies the directory of the Unix-domain socket on which the
|
|
|
6cb03e |
- server is to listen for
|
|
|
6cb03e |
- connections from client applications. The default is normally
|
|
|
6cb03e |
- <filename>/tmp</filename>, but can be changed at build time.
|
|
|
6cb03e |
+ Specifies the directory of the Unix-domain socket(s) on which the
|
|
|
6cb03e |
+ server is to listen for connections from client applications.
|
|
|
6cb03e |
+ Multiple sockets can be created by listing multiple directories
|
|
|
6cb03e |
+ separated by commas. Whitespace between entries is
|
|
|
6cb03e |
+ ignored; surround a directory name with double quotes if you need
|
|
|
6cb03e |
+ to include whitespace or commas in the name.
|
|
|
6cb03e |
+ An empty value
|
|
|
6cb03e |
+ specifies not listening on any Unix-domain sockets, in which case
|
|
|
6cb03e |
+ only TCP/IP sockets can be used to connect to the server.
|
|
|
6cb03e |
+ The default value is normally
|
|
|
6cb03e |
+ <filename>/tmp</filename>, but that can be changed at build time.
|
|
|
6cb03e |
This parameter can only be set at server start.
|
|
|
6cb03e |
</para>
|
|
|
6cb03e |
|
|
|
6cb03e |
@@ -472,8 +479,8 @@ SET ENABLE_SEQSCAN TO OFF;
|
|
|
6cb03e |
<literal>.s.PGSQL.<replaceable>nnnn</literal> where
|
|
|
6cb03e |
<replaceable>nnnn is the server's port number, an ordinary file
|
|
|
6cb03e |
named <literal>.s.PGSQL.<replaceable>nnnn.lock</literal> will be
|
|
|
6cb03e |
- created in the <varname>unix_socket_directory directory. Neither
|
|
|
6cb03e |
- file should ever be removed manually.
|
|
|
6cb03e |
+ created in each of the <varname>unix_socket_directories directories.
|
|
|
6cb03e |
+ Neither file should ever be removed manually.
|
|
|
6cb03e |
</para>
|
|
|
6cb03e |
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
@@ -490,8 +497,8 @@ SET ENABLE_SEQSCAN TO OFF;
|
|
|
6cb03e |
</indexterm>
|
|
|
6cb03e |
<listitem>
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
- Sets the owning group of the Unix-domain socket. (The owning
|
|
|
6cb03e |
- user of the socket is always the user that starts the
|
|
|
6cb03e |
+ Sets the owning group of the Unix-domain socket(s). (The owning
|
|
|
6cb03e |
+ user of the sockets is always the user that starts the
|
|
|
6cb03e |
server.) In combination with the parameter
|
|
|
6cb03e |
<varname>unix_socket_permissions</varname> this can be used as
|
|
|
6cb03e |
an additional access control mechanism for Unix-domain connections.
|
|
|
6cb03e |
@@ -514,7 +521,7 @@ SET ENABLE_SEQSCAN TO OFF;
|
|
|
6cb03e |
</indexterm>
|
|
|
6cb03e |
<listitem>
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
- Sets the access permissions of the Unix-domain socket. Unix-domain
|
|
|
6cb03e |
+ Sets the access permissions of the Unix-domain socket(s). Unix-domain
|
|
|
6cb03e |
sockets use the usual Unix file system permission set.
|
|
|
6cb03e |
The parameter value is expected to be a numeric mode
|
|
|
6cb03e |
specified in the format accepted by the
|
|
|
6cb03e |
@@ -6624,7 +6631,7 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
|
|
|
6cb03e |
</row>
|
|
|
6cb03e |
<row>
|
|
|
6cb03e |
<entry><option>-k <replaceable>x</replaceable></option></entry>
|
|
|
6cb03e |
- <entry><literal>unix_socket_directory = <replaceable>x</replaceable></entry>
|
|
|
6cb03e |
+ <entry><literal>unix_socket_directories = <replaceable>x</replaceable></entry>
|
|
|
6cb03e |
</row>
|
|
|
6cb03e |
<row>
|
|
|
6cb03e |
<entry><option>-l</option></entry>
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/app-postgres.html b/doc/src/sgml/html/app-postgres.html
|
|
|
6cb03e |
index b1f4e31..b6359a8 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/app-postgres.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/app-postgres.html
|
|
|
6cb03e |
@@ -574,11 +574,19 @@ CLASS="REPLACEABLE"
|
|
|
6cb03e |
CLASS="COMMAND"
|
|
|
6cb03e |
>postgres
|
|
|
6cb03e |
> is to listen for
|
|
|
6cb03e |
- connections from client applications. The default is normally
|
|
|
6cb03e |
+ connections from client applications. The value can also be a
|
|
|
6cb03e |
+ comma-separated list of directories. An empty value
|
|
|
6cb03e |
+ specifies not listening on any Unix-domain sockets, in which case
|
|
|
6cb03e |
+ only TCP/IP sockets can be used to connect to the server.
|
|
|
6cb03e |
+ The default value is normally
|
|
|
6cb03e |
|
|
|
6cb03e |
CLASS="FILENAME"
|
|
|
6cb03e |
>/tmp
|
|
|
6cb03e |
->, but can be changed at build time.
|
|
|
6cb03e |
+>, but that can be changed at build time.
|
|
|
6cb03e |
+ Specifying this option is equivalent to setting the
|
|
|
6cb03e |
+HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
|
|
|
6cb03e |
+>unix_socket_directories
|
|
|
6cb03e |
+> configuration parameter.
|
|
|
6cb03e |
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/auth-methods.html b/doc/src/sgml/html/auth-methods.html
|
|
|
6cb03e |
index ab544a9..e1225d1 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/auth-methods.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/auth-methods.html
|
|
|
6cb03e |
@@ -161,7 +161,7 @@ HREF="runtime-config-connection.html"
|
|
|
6cb03e |
>. Or you
|
|
|
6cb03e |
could set the
|
|
|
6cb03e |
CLASS="VARNAME"
|
|
|
6cb03e |
->unix_socket_directory
|
|
|
6cb03e |
+>unix_socket_directories
|
|
|
6cb03e |
>
|
|
|
6cb03e |
configuration parameter to place the socket file in a suitably
|
|
|
6cb03e |
restricted directory.
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/bookindex.html b/doc/src/sgml/html/bookindex.html
|
|
|
6cb03e |
index 5e25f95..1562ffe 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/bookindex.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/bookindex.html
|
|
|
6cb03e |
@@ -17250,7 +17250,7 @@ HREF="xfunc-c.html#DFUNC"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
->unix_socket_directory configuration parameter,
|
|
|
6cb03e |
+>unix_socket_directories configuration parameter,
|
|
|
6cb03e |
|
|
|
6cb03e |
HREF="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS"
|
|
|
6cb03e |
>Connection Settings
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/preventing-server-spoofing.html b/doc/src/sgml/html/preventing-server-spoofing.html
|
|
|
6cb03e |
index 77d11ab..6abc511 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/preventing-server-spoofing.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/preventing-server-spoofing.html
|
|
|
6cb03e |
@@ -115,8 +115,8 @@ CLASS="LITERAL"
|
|
|
6cb03e |
>local
|
|
|
6cb03e |
>
|
|
|
6cb03e |
connections is to use a Unix domain socket directory (
|
|
|
6cb03e |
-HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORY"
|
|
|
6cb03e |
->unix_socket_directory
|
|
|
6cb03e |
+HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
|
|
|
6cb03e |
+>unix_socket_directories
|
|
|
6cb03e |
>) that has write permission only
|
|
|
6cb03e |
for a trusted local user. This prevents a malicious user from creating
|
|
|
6cb03e |
their own socket file in that directory. If you are concerned that
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/runtime-config-connection.html b/doc/src/sgml/html/runtime-config-connection.html
|
|
|
6cb03e |
index 74f096e..0ba6987 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/runtime-config-connection.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/runtime-config-connection.html
|
|
|
6cb03e |
@@ -274,24 +274,31 @@ CLASS="VARNAME"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
-NAME="GUC-UNIX-SOCKET-DIRECTORY"
|
|
|
6cb03e |
+NAME="GUC-UNIX-SOCKET-DIRECTORIES"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
CLASS="VARNAME"
|
|
|
6cb03e |
->unix_socket_directory
|
|
|
6cb03e |
+>unix_socket_directories
|
|
|
6cb03e |
> (
|
|
|
6cb03e |
CLASS="TYPE"
|
|
|
6cb03e |
>string
|
|
|
6cb03e |
>)
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
-> Specifies the directory of the Unix-domain socket on which the
|
|
|
6cb03e |
- server is to listen for
|
|
|
6cb03e |
- connections from client applications. The default is normally
|
|
|
6cb03e |
+> Specifies the directory of the Unix-domain socket(s) on which the
|
|
|
6cb03e |
+ server is to listen for connections from client applications.
|
|
|
6cb03e |
+ Multiple sockets can be created by listing multiple directories
|
|
|
6cb03e |
+ separated by commas. Whitespace between entries is
|
|
|
6cb03e |
+ ignored; surround a directory name with double quotes if you need
|
|
|
6cb03e |
+ to include whitespace or commas in the name.
|
|
|
6cb03e |
+ An empty value
|
|
|
6cb03e |
+ specifies not listening on any Unix-domain sockets, in which case
|
|
|
6cb03e |
+ only TCP/IP sockets can be used to connect to the server.
|
|
|
6cb03e |
+ The default value is normally
|
|
|
6cb03e |
|
|
|
6cb03e |
CLASS="FILENAME"
|
|
|
6cb03e |
>/tmp
|
|
|
6cb03e |
->, but can be changed at build time.
|
|
|
6cb03e |
+>, but that can be changed at build time.
|
|
|
6cb03e |
This parameter can only be set at server start.
|
|
|
6cb03e |
|
|
|
6cb03e |
>
|
|
|
6cb03e |
@@ -320,11 +327,11 @@ CLASS="REPLACEABLE"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>.lock
|
|
|
6cb03e |
> will be
|
|
|
6cb03e |
- created in the
|
|
|
6cb03e |
+ created in each of the
|
|
|
6cb03e |
CLASS="VARNAME"
|
|
|
6cb03e |
->unix_socket_directory
|
|
|
6cb03e |
-> directory. Neither
|
|
|
6cb03e |
- file should ever be removed manually.
|
|
|
6cb03e |
+>unix_socket_directories
|
|
|
6cb03e |
+> directories.
|
|
|
6cb03e |
+ Neither file should ever be removed manually.
|
|
|
6cb03e |
|
|
|
6cb03e |
>
|
|
|
6cb03e |
> This parameter is irrelevant on Windows, which does not have
|
|
|
6cb03e |
@@ -344,8 +351,8 @@ CLASS="TYPE"
|
|
|
6cb03e |
>)
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
-> Sets the owning group of the Unix-domain socket. (The owning
|
|
|
6cb03e |
- user of the socket is always the user that starts the
|
|
|
6cb03e |
+> Sets the owning group of the Unix-domain socket(s). (The owning
|
|
|
6cb03e |
+ user of the sockets is always the user that starts the
|
|
|
6cb03e |
server.) In combination with the parameter
|
|
|
6cb03e |
|
|
|
6cb03e |
CLASS="VARNAME"
|
|
|
6cb03e |
@@ -374,7 +381,7 @@ CLASS="TYPE"
|
|
|
6cb03e |
>)
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
-> Sets the access permissions of the Unix-domain socket. Unix-domain
|
|
|
6cb03e |
+> Sets the access permissions of the Unix-domain socket(s). Unix-domain
|
|
|
6cb03e |
sockets use the usual Unix file system permission set.
|
|
|
6cb03e |
The parameter value is expected to be a numeric mode
|
|
|
6cb03e |
specified in the format accepted by the
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html/runtime-config-short.html b/doc/src/sgml/html/runtime-config-short.html
|
|
|
6cb03e |
index 8c39c2f..f0d7080 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html/runtime-config-short.html
|
|
|
6cb03e |
+++ b/doc/src/sgml/html/runtime-config-short.html
|
|
|
6cb03e |
@@ -330,7 +330,7 @@ CLASS="REPLACEABLE"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>
|
|
|
6cb03e |
CLASS="LITERAL"
|
|
|
6cb03e |
->unix_socket_directory =
|
|
|
6cb03e |
+>unix_socket_directories =
|
|
|
6cb03e |
CLASS="REPLACEABLE"
|
|
|
6cb03e |
>
|
|
|
6cb03e |
>x
|
|
|
6cb03e |
diff --git a/doc/src/sgml/man1/postgres.1 b/doc/src/sgml/man1/postgres.1
|
|
|
6cb03e |
index 6ec18ee..3378dde 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/man1/postgres.1
|
|
|
6cb03e |
+++ b/doc/src/sgml/man1/postgres.1
|
|
|
6cb03e |
@@ -195,8 +195,10 @@ directly\&.
|
|
|
6cb03e |
.RS 4
|
|
|
6cb03e |
Specifies the directory of the Unix\-domain socket on which
|
|
|
6cb03e |
\fBpostgres\fR
|
|
|
6cb03e |
-is to listen for connections from client applications\&. The default is normally
|
|
|
6cb03e |
-/tmp, but can be changed at build time\&.
|
|
|
6cb03e |
+is to listen for connections from client applications\&. The value can also be a comma\-separated list of directories\&. An empty value specifies not listening on any Unix\-domain sockets, in which case only TCP/IP sockets can be used to connect to the server\&. The default value is normally
|
|
|
6cb03e |
+/tmp, but that can be changed at build time\&. Specifying this option is equivalent to setting the
|
|
|
6cb03e |
+unix_socket_directories
|
|
|
6cb03e |
+configuration parameter\&.
|
|
|
6cb03e |
.RE
|
|
|
6cb03e |
.PP
|
|
|
6cb03e |
\fB\-l\fR
|
|
|
6cb03e |
diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
|
|
|
6cb03e |
index 4e5cd02..a1f36e1 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/ref/postgres-ref.sgml
|
|
|
6cb03e |
+++ b/doc/src/sgml/ref/postgres-ref.sgml
|
|
|
6cb03e |
@@ -254,8 +254,14 @@ PostgreSQL documentation
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
Specifies the directory of the Unix-domain socket on which
|
|
|
6cb03e |
<command>postgres</command> is to listen for
|
|
|
6cb03e |
- connections from client applications. The default is normally
|
|
|
6cb03e |
- <filename>/tmp</filename>, but can be changed at build time.
|
|
|
6cb03e |
+ connections from client applications. The value can also be a
|
|
|
6cb03e |
+ comma-separated list of directories. An empty value
|
|
|
6cb03e |
+ specifies not listening on any Unix-domain sockets, in which case
|
|
|
6cb03e |
+ only TCP/IP sockets can be used to connect to the server.
|
|
|
6cb03e |
+ The default value is normally
|
|
|
6cb03e |
+ <filename>/tmp</filename>, but that can be changed at build time.
|
|
|
6cb03e |
+ Specifying this option is equivalent to setting the
|
|
|
6cb03e |
+ linkend="guc-unix-socket-directories"> configuration parameter.
|
|
|
6cb03e |
</para>
|
|
|
6cb03e |
</listitem>
|
|
|
6cb03e |
</varlistentry>
|
|
|
6cb03e |
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
|
|
|
6cb03e |
index cfd3532..e6c9eaa 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/runtime.sgml
|
|
|
6cb03e |
+++ b/doc/src/sgml/runtime.sgml
|
|
|
6cb03e |
@@ -1800,7 +1800,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
|
|
|
6cb03e |
<para>
|
|
|
6cb03e |
The simplest way to prevent spoofing for <literal>local
|
|
|
6cb03e |
connections is to use a Unix domain socket directory (
|
|
|
6cb03e |
- linkend="guc-unix-socket-directory">) that has write permission only
|
|
|
6cb03e |
+ linkend="guc-unix-socket-directories">) that has write permission only
|
|
|
6cb03e |
for a trusted local user. This prevents a malicious user from creating
|
|
|
6cb03e |
their own socket file in that directory. If you are concerned that
|
|
|
6cb03e |
some applications might still reference <filename>/tmp for the
|
|
|
6cb03e |
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
|
|
|
6cb03e |
index aeeffd7..b7e0d09 100644
|
|
|
6cb03e |
--- a/src/backend/libpq/pqcomm.c
|
|
|
6cb03e |
+++ b/src/backend/libpq/pqcomm.c
|
|
|
6cb03e |
@@ -42,7 +42,7 @@
|
|
|
6cb03e |
* StreamServerPort - Open postmaster's server port
|
|
|
6cb03e |
* StreamConnection - Create new connection with client
|
|
|
6cb03e |
* StreamClose - Close a client/backend connection
|
|
|
6cb03e |
- * TouchSocketFile - Protect socket file against /tmp cleaners
|
|
|
6cb03e |
+ * TouchSocketFiles - Protect socket files against /tmp cleaners
|
|
|
6cb03e |
* pq_init - initialize libpq at backend startup
|
|
|
6cb03e |
* pq_comm_reset - reset libpq during error recovery
|
|
|
6cb03e |
* pq_close - shutdown libpq at backend exit
|
|
|
6cb03e |
@@ -103,8 +103,8 @@ int Unix_socket_permissions;
|
|
|
6cb03e |
char *Unix_socket_group;
|
|
|
6cb03e |
|
|
|
6cb03e |
|
|
|
6cb03e |
-/* Where the Unix socket file is */
|
|
|
6cb03e |
-static char sock_path[MAXPGPATH];
|
|
|
6cb03e |
+/* Where the Unix socket files are (list of palloc'd strings) */
|
|
|
6cb03e |
+static List *sock_paths = NIL;
|
|
|
6cb03e |
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
@@ -141,8 +141,8 @@ static int internal_flush(void);
|
|
|
6cb03e |
static void pq_set_nonblocking(bool nonblocking);
|
|
|
6cb03e |
|
|
|
6cb03e |
#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
-static int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName);
|
|
|
6cb03e |
-static int Setup_AF_UNIX(void);
|
|
|
6cb03e |
+static int Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath);
|
|
|
6cb03e |
+static int Setup_AF_UNIX(char *sock_path);
|
|
|
6cb03e |
#endif /* HAVE_UNIX_SOCKETS */
|
|
|
6cb03e |
|
|
|
6cb03e |
|
|
|
6cb03e |
@@ -236,29 +236,43 @@ pq_close(int code, Datum arg)
|
|
|
6cb03e |
|
|
|
6cb03e |
/* StreamDoUnlink()
|
|
|
6cb03e |
* Shutdown routine for backend connection
|
|
|
6cb03e |
- * If a Unix socket is used for communication, explicitly close it.
|
|
|
6cb03e |
+ * If any Unix sockets are used for communication, explicitly close them.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
static void
|
|
|
6cb03e |
StreamDoUnlink(int code, Datum arg)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- Assert(sock_path[0]);
|
|
|
6cb03e |
- unlink(sock_path);
|
|
|
6cb03e |
+ ListCell *l;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Loop through all created sockets... */
|
|
|
6cb03e |
+ foreach(l, sock_paths)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ char *sock_path = (char *) lfirst(l);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ unlink(sock_path);
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ /* Since we're about to exit, no need to reclaim storage */
|
|
|
6cb03e |
+ sock_paths = NIL;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
#endif /* HAVE_UNIX_SOCKETS */
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* StreamServerPort -- open a "listening" port to accept connections.
|
|
|
6cb03e |
*
|
|
|
6cb03e |
- * Successfully opened sockets are added to the ListenSocket[] array,
|
|
|
6cb03e |
- * at the first position that isn't PGINVALID_SOCKET.
|
|
|
6cb03e |
+ * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
|
|
|
6cb03e |
+ * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
|
|
|
6cb03e |
+ * specified. For TCP ports, hostName is either NULL for all interfaces or
|
|
|
6cb03e |
+ * the interface to listen on, and unixSocketDir is ignored (can be NULL).
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * Successfully opened sockets are added to the ListenSocket[] array (of
|
|
|
6cb03e |
+ * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
|
|
|
6cb03e |
*
|
|
|
6cb03e |
* RETURNS: STATUS_OK or STATUS_ERROR
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
|
|
|
6cb03e |
int
|
|
|
6cb03e |
StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
- char *unixSocketName,
|
|
|
6cb03e |
+ char *unixSocketDir,
|
|
|
6cb03e |
pgsocket ListenSocket[], int MaxListen)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
pgsocket fd;
|
|
|
6cb03e |
@@ -275,6 +289,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
int listen_index = 0;
|
|
|
6cb03e |
int added = 0;
|
|
|
6cb03e |
|
|
|
6cb03e |
+#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
+ char unixSocketPath[MAXPGPATH];
|
|
|
6cb03e |
+#endif
|
|
|
6cb03e |
#if !defined(WIN32) || defined(IPV6_V6ONLY)
|
|
|
6cb03e |
int one = 1;
|
|
|
6cb03e |
#endif
|
|
|
6cb03e |
@@ -288,10 +305,22 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
if (family == AF_UNIX)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- /* Lock_AF_UNIX will also fill in sock_path. */
|
|
|
6cb03e |
- if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
|
|
|
6cb03e |
+ /*
|
|
|
6cb03e |
+ * Create unixSocketPath from portNumber and unixSocketDir and lock
|
|
|
6cb03e |
+ * that file path
|
|
|
6cb03e |
+ */
|
|
|
6cb03e |
+ UNIXSOCK_PATH(unixSocketPath, portNumber, unixSocketDir);
|
|
|
6cb03e |
+ if (strlen(unixSocketPath) >= UNIXSOCK_PATH_BUFLEN)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ ereport(LOG,
|
|
|
6cb03e |
+ (errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
|
|
|
6cb03e |
+ unixSocketPath,
|
|
|
6cb03e |
+ (int) (UNIXSOCK_PATH_BUFLEN - 1))));
|
|
|
6cb03e |
return STATUS_ERROR;
|
|
|
6cb03e |
- service = sock_path;
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ if (Lock_AF_UNIX(unixSocketDir, unixSocketPath) != STATUS_OK)
|
|
|
6cb03e |
+ return STATUS_ERROR;
|
|
|
6cb03e |
+ service = unixSocketPath;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
else
|
|
|
6cb03e |
#endif /* HAVE_UNIX_SOCKETS */
|
|
|
6cb03e |
@@ -434,7 +463,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
(IS_AF_UNIX(addr->ai_family)) ?
|
|
|
6cb03e |
errhint("Is another postmaster already running on port %d?"
|
|
|
6cb03e |
" If not, remove socket file \"%s\" and retry.",
|
|
|
6cb03e |
- (int) portNumber, sock_path) :
|
|
|
6cb03e |
+ (int) portNumber, service) :
|
|
|
6cb03e |
errhint("Is another postmaster already running on port %d?"
|
|
|
6cb03e |
" If not, wait a few seconds and retry.",
|
|
|
6cb03e |
(int) portNumber)));
|
|
|
6cb03e |
@@ -445,7 +474,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
if (addr->ai_family == AF_UNIX)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- if (Setup_AF_UNIX() != STATUS_OK)
|
|
|
6cb03e |
+ if (Setup_AF_UNIX(service) != STATUS_OK)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
closesocket(fd);
|
|
|
6cb03e |
break;
|
|
|
6cb03e |
@@ -492,18 +521,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
|
|
6cb03e |
* Lock_AF_UNIX -- configure unix socket file path
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
static int
|
|
|
6cb03e |
-Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
|
|
|
6cb03e |
+Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
|
|
|
6cb03e |
- if (strlen(sock_path) >= UNIXSOCK_PATH_BUFLEN)
|
|
|
6cb03e |
- {
|
|
|
6cb03e |
- ereport(LOG,
|
|
|
6cb03e |
- (errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
|
|
|
6cb03e |
- sock_path,
|
|
|
6cb03e |
- (int) (UNIXSOCK_PATH_BUFLEN - 1))));
|
|
|
6cb03e |
- return STATUS_ERROR;
|
|
|
6cb03e |
- }
|
|
|
6cb03e |
-
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Grab an interlock file associated with the socket file.
|
|
|
6cb03e |
*
|
|
|
6cb03e |
@@ -512,13 +531,23 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
|
|
|
6cb03e |
* more portable, and second, it lets us remove any pre-existing socket
|
|
|
6cb03e |
* file without race conditions.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- CreateSocketLockFile(sock_path, true);
|
|
|
6cb03e |
+ CreateSocketLockFile(unixSocketPath, true, unixSocketDir);
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Once we have the interlock, we can safely delete any pre-existing
|
|
|
6cb03e |
* socket file to avoid failure at bind() time.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- unlink(sock_path);
|
|
|
6cb03e |
+ unlink(unixSocketPath);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /*
|
|
|
6cb03e |
+ * Arrange to unlink the socket file(s) at proc_exit. If this is the
|
|
|
6cb03e |
+ * first one, set up the on_proc_exit function to do it; then add this
|
|
|
6cb03e |
+ * socket file to the list of files to unlink.
|
|
|
6cb03e |
+ */
|
|
|
6cb03e |
+ if (sock_paths == NIL)
|
|
|
6cb03e |
+ on_proc_exit(StreamDoUnlink, 0);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ sock_paths = lappend(sock_paths, pstrdup(unixSocketPath));
|
|
|
6cb03e |
|
|
|
6cb03e |
return STATUS_OK;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
@@ -528,11 +557,8 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
|
|
|
6cb03e |
* Setup_AF_UNIX -- configure unix socket permissions
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
static int
|
|
|
6cb03e |
-Setup_AF_UNIX(void)
|
|
|
6cb03e |
+Setup_AF_UNIX(char *sock_path)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- /* Arrange to unlink the socket file at exit */
|
|
|
6cb03e |
- on_proc_exit(StreamDoUnlink, 0);
|
|
|
6cb03e |
-
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Fix socket ownership/permission if requested. Note we must do this
|
|
|
6cb03e |
* before we listen() to avoid a window where unwanted connections could
|
|
|
6cb03e |
@@ -714,20 +740,24 @@ StreamClose(pgsocket sock)
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * TouchSocketFile -- mark socket file as recently accessed
|
|
|
6cb03e |
+ * TouchSocketFiles -- mark socket files as recently accessed
|
|
|
6cb03e |
*
|
|
|
6cb03e |
* This routine should be called every so often to ensure that the socket
|
|
|
6cb03e |
- * file has a recent mod date (ordinary operations on sockets usually won't
|
|
|
6cb03e |
- * change the mod date). That saves it from being removed by
|
|
|
6cb03e |
+ * files have a recent mod date (ordinary operations on sockets usually won't
|
|
|
6cb03e |
+ * change the mod date). That saves them from being removed by
|
|
|
6cb03e |
* overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should
|
|
|
6cb03e |
* never have put the socket file in /tmp...)
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
void
|
|
|
6cb03e |
-TouchSocketFile(void)
|
|
|
6cb03e |
+TouchSocketFiles(void)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- /* Do nothing if we did not create a socket... */
|
|
|
6cb03e |
- if (sock_path[0] != '\0')
|
|
|
6cb03e |
+ ListCell *l;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Loop through all created sockets... */
|
|
|
6cb03e |
+ foreach(l, sock_paths)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
+ char *sock_path = (char *) lfirst(l);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* utime() is POSIX standard, utimes() is a common alternative. If we
|
|
|
6cb03e |
* have neither, there's no way to affect the mod or access time of
|
|
|
6cb03e |
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
|
|
|
6cb03e |
index 07aca31..e84a18c 100644
|
|
|
6cb03e |
--- a/src/backend/postmaster/postmaster.c
|
|
|
6cb03e |
+++ b/src/backend/postmaster/postmaster.c
|
|
|
6cb03e |
@@ -160,7 +160,9 @@ static Backend *ShmemBackendArray;
|
|
|
6cb03e |
|
|
|
6cb03e |
/* The socket number we are listening for connections on */
|
|
|
6cb03e |
int PostPortNumber;
|
|
|
6cb03e |
-char *UnixSocketDir;
|
|
|
6cb03e |
+/* The directory names for Unix socket(s) */
|
|
|
6cb03e |
+char *Unix_socket_directories;
|
|
|
6cb03e |
+/* The TCP listen address(es) */
|
|
|
6cb03e |
char *ListenAddresses;
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
@@ -636,7 +638,7 @@ PostmasterMain(int argc, char *argv[])
|
|
|
6cb03e |
break;
|
|
|
6cb03e |
|
|
|
6cb03e |
case 'k':
|
|
|
6cb03e |
- SetConfigOption("unix_socket_directory", optarg, PGC_POSTMASTER, PGC_S_ARGV);
|
|
|
6cb03e |
+ SetConfigOption("unix_socket_directories", optarg, PGC_POSTMASTER, PGC_S_ARGV);
|
|
|
6cb03e |
break;
|
|
|
6cb03e |
|
|
|
6cb03e |
case 'l':
|
|
|
6cb03e |
@@ -880,7 +882,7 @@ PostmasterMain(int argc, char *argv[])
|
|
|
6cb03e |
/* Need a modifiable copy of ListenAddresses */
|
|
|
6cb03e |
rawstring = pstrdup(ListenAddresses);
|
|
|
6cb03e |
|
|
|
6cb03e |
- /* Parse string into list of identifiers */
|
|
|
6cb03e |
+ /* Parse string into list of hostnames */
|
|
|
6cb03e |
if (!SplitIdentifierString(rawstring, ',', &elemlist))
|
|
|
6cb03e |
{
|
|
|
6cb03e |
/* syntax error in list */
|
|
|
6cb03e |
@@ -896,12 +898,12 @@ PostmasterMain(int argc, char *argv[])
|
|
|
6cb03e |
if (strcmp(curhost, "*") == 0)
|
|
|
6cb03e |
status = StreamServerPort(AF_UNSPEC, NULL,
|
|
|
6cb03e |
(unsigned short) PostPortNumber,
|
|
|
6cb03e |
- UnixSocketDir,
|
|
|
6cb03e |
+ NULL,
|
|
|
6cb03e |
ListenSocket, MAXLISTEN);
|
|
|
6cb03e |
else
|
|
|
6cb03e |
status = StreamServerPort(AF_UNSPEC, curhost,
|
|
|
6cb03e |
(unsigned short) PostPortNumber,
|
|
|
6cb03e |
- UnixSocketDir,
|
|
|
6cb03e |
+ NULL,
|
|
|
6cb03e |
ListenSocket, MAXLISTEN);
|
|
|
6cb03e |
|
|
|
6cb03e |
if (status == STATUS_OK)
|
|
|
6cb03e |
@@ -920,7 +922,7 @@ PostmasterMain(int argc, char *argv[])
|
|
|
6cb03e |
curhost)));
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
- if (!success && list_length(elemlist))
|
|
|
6cb03e |
+ if (!success && elemlist != NIL)
|
|
|
6cb03e |
ereport(FATAL,
|
|
|
6cb03e |
(errmsg("could not create any TCP/IP sockets")));
|
|
|
6cb03e |
|
|
|
6cb03e |
@@ -967,13 +969,54 @@ PostmasterMain(int argc, char *argv[])
|
|
|
6cb03e |
#endif
|
|
|
6cb03e |
|
|
|
6cb03e |
#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
- status = StreamServerPort(AF_UNIX, NULL,
|
|
|
6cb03e |
- (unsigned short) PostPortNumber,
|
|
|
6cb03e |
- UnixSocketDir,
|
|
|
6cb03e |
- ListenSocket, MAXLISTEN);
|
|
|
6cb03e |
- if (status != STATUS_OK)
|
|
|
6cb03e |
- ereport(WARNING,
|
|
|
6cb03e |
- (errmsg("could not create Unix-domain socket")));
|
|
|
6cb03e |
+ if (Unix_socket_directories)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ char *rawstring;
|
|
|
6cb03e |
+ List *elemlist;
|
|
|
6cb03e |
+ ListCell *l;
|
|
|
6cb03e |
+ int success = 0;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Need a modifiable copy of Unix_socket_directories */
|
|
|
6cb03e |
+ rawstring = pstrdup(Unix_socket_directories);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Parse string into list of directories */
|
|
|
6cb03e |
+ if (!SplitDirectoriesString(rawstring, ',', &elemlist))
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ /* syntax error in list */
|
|
|
6cb03e |
+ ereport(FATAL,
|
|
|
6cb03e |
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
|
6cb03e |
+ errmsg("invalid list syntax for \"unix_socket_directories\"")));
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ foreach(l, elemlist)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ char *socketdir = (char *) lfirst(l);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ status = StreamServerPort(AF_UNIX, NULL,
|
|
|
6cb03e |
+ (unsigned short) PostPortNumber,
|
|
|
6cb03e |
+ socketdir,
|
|
|
6cb03e |
+ ListenSocket, MAXLISTEN);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ if (status == STATUS_OK)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ success++;
|
|
|
6cb03e |
+ /* record the first successful Unix socket in lockfile */
|
|
|
6cb03e |
+ if (success == 1)
|
|
|
6cb03e |
+ AddToDataDirLockFile(LOCK_FILE_LINE_SOCKET_DIR, socketdir);
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ else
|
|
|
6cb03e |
+ ereport(WARNING,
|
|
|
6cb03e |
+ (errmsg("could not create Unix-domain socket in directory \"%s\"",
|
|
|
6cb03e |
+ socketdir)));
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ if (!success && elemlist != NIL)
|
|
|
6cb03e |
+ ereport(FATAL,
|
|
|
6cb03e |
+ (errmsg("could not create any Unix-domain sockets")));
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ list_free_deep(elemlist);
|
|
|
6cb03e |
+ pfree(rawstring);
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
#endif
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
@@ -1561,14 +1604,14 @@ ServerLoop(void)
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * Touch Unix socket and lock file every 58 minutes, to ensure that
|
|
|
6cb03e |
+ * Touch Unix socket and lock files every 58 minutes, to ensure that
|
|
|
6cb03e |
* they are not removed by overzealous /tmp-cleaning tasks. We assume
|
|
|
6cb03e |
* no one runs cleaners with cutoff times of less than an hour ...
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
if (now - last_touch_time >= 58 * SECS_PER_MINUTE)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- TouchSocketFile();
|
|
|
6cb03e |
- TouchSocketLockFile();
|
|
|
6cb03e |
+ TouchSocketFiles();
|
|
|
6cb03e |
+ TouchSocketLockFiles();
|
|
|
6cb03e |
last_touch_time = now;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
}
|
|
|
6cb03e |
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
|
|
|
6cb03e |
index 39017ff..318ac38 100644
|
|
|
6cb03e |
--- a/src/backend/tcop/postgres.c
|
|
|
6cb03e |
+++ b/src/backend/tcop/postgres.c
|
|
|
6cb03e |
@@ -3393,7 +3393,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
|
|
|
6cb03e |
break;
|
|
|
6cb03e |
|
|
|
6cb03e |
case 'k':
|
|
|
6cb03e |
- SetConfigOption("unix_socket_directory", optarg, ctx, gucsource);
|
|
|
6cb03e |
+ SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
|
|
|
6cb03e |
break;
|
|
|
6cb03e |
|
|
|
6cb03e |
case 'l':
|
|
|
6cb03e |
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
|
|
|
6cb03e |
index d4abfe3..e8217ac 100644
|
|
|
6cb03e |
--- a/src/backend/utils/adt/varlena.c
|
|
|
6cb03e |
+++ b/src/backend/utils/adt/varlena.c
|
|
|
6cb03e |
@@ -2446,6 +2446,119 @@ SplitIdentifierString(char *rawstring, char separator,
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
|
|
|
6cb03e |
+/*
|
|
|
6cb03e |
+ * SplitDirectoriesString --- parse a string containing directory names
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * This is similar to SplitIdentifierString, except that the parsing
|
|
|
6cb03e |
+ * rules are meant to handle pathnames instead of identifiers: there is
|
|
|
6cb03e |
+ * no downcasing, embedded spaces are allowed, the max length is MAXPGPATH-1,
|
|
|
6cb03e |
+ * and we apply canonicalize_path() to each extracted string. Because of the
|
|
|
6cb03e |
+ * last, the returned strings are separately palloc'd rather than being
|
|
|
6cb03e |
+ * pointers into rawstring --- but we still scribble on rawstring.
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * Inputs:
|
|
|
6cb03e |
+ * rawstring: the input string; must be modifiable!
|
|
|
6cb03e |
+ * separator: the separator punctuation expected between directories
|
|
|
6cb03e |
+ * (typically ',' or ';'). Whitespace may also appear around
|
|
|
6cb03e |
+ * directories.
|
|
|
6cb03e |
+ * Outputs:
|
|
|
6cb03e |
+ * namelist: filled with a palloc'd list of directory names.
|
|
|
6cb03e |
+ * Caller should list_free_deep() this even on error return.
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * Returns TRUE if okay, FALSE if there is a syntax error in the string.
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * Note that an empty string is considered okay here.
|
|
|
6cb03e |
+ */
|
|
|
6cb03e |
+bool
|
|
|
6cb03e |
+SplitDirectoriesString(char *rawstring, char separator,
|
|
|
6cb03e |
+ List **namelist)
|
|
|
6cb03e |
+{
|
|
|
6cb03e |
+ char *nextp = rawstring;
|
|
|
6cb03e |
+ bool done = false;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ *namelist = NIL;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ while (isspace((unsigned char) *nextp))
|
|
|
6cb03e |
+ nextp++; /* skip leading whitespace */
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ if (*nextp == '\0')
|
|
|
6cb03e |
+ return true; /* allow empty string */
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* At the top of the loop, we are at start of a new directory. */
|
|
|
6cb03e |
+ do
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ char *curname;
|
|
|
6cb03e |
+ char *endp;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ if (*nextp == '\"')
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ /* Quoted name --- collapse quote-quote pairs */
|
|
|
6cb03e |
+ curname = nextp + 1;
|
|
|
6cb03e |
+ for (;;)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ endp = strchr(nextp + 1, '\"');
|
|
|
6cb03e |
+ if (endp == NULL)
|
|
|
6cb03e |
+ return false; /* mismatched quotes */
|
|
|
6cb03e |
+ if (endp[1] != '\"')
|
|
|
6cb03e |
+ break; /* found end of quoted name */
|
|
|
6cb03e |
+ /* Collapse adjacent quotes into one quote, and look again */
|
|
|
6cb03e |
+ memmove(endp, endp + 1, strlen(endp));
|
|
|
6cb03e |
+ nextp = endp;
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ /* endp now points at the terminating quote */
|
|
|
6cb03e |
+ nextp = endp + 1;
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ else
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ /* Unquoted name --- extends to separator or end of string */
|
|
|
6cb03e |
+ curname = endp = nextp;
|
|
|
6cb03e |
+ while (*nextp && *nextp != separator)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ /* trailing whitespace should not be included in name */
|
|
|
6cb03e |
+ if (!isspace((unsigned char) *nextp))
|
|
|
6cb03e |
+ endp = nextp + 1;
|
|
|
6cb03e |
+ nextp++;
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ if (curname == endp)
|
|
|
6cb03e |
+ return false; /* empty unquoted name not allowed */
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ while (isspace((unsigned char) *nextp))
|
|
|
6cb03e |
+ nextp++; /* skip trailing whitespace */
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ if (*nextp == separator)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ nextp++;
|
|
|
6cb03e |
+ while (isspace((unsigned char) *nextp))
|
|
|
6cb03e |
+ nextp++; /* skip leading whitespace for next */
|
|
|
6cb03e |
+ /* we expect another name, so done remains false */
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
+ else if (*nextp == '\0')
|
|
|
6cb03e |
+ done = true;
|
|
|
6cb03e |
+ else
|
|
|
6cb03e |
+ return false; /* invalid syntax */
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Now safe to overwrite separator with a null */
|
|
|
6cb03e |
+ *endp = '\0';
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Truncate path if it's overlength */
|
|
|
6cb03e |
+ if (strlen(curname) >= MAXPGPATH)
|
|
|
6cb03e |
+ curname[MAXPGPATH - 1] = '\0';
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /*
|
|
|
6cb03e |
+ * Finished isolating current name --- add it to list
|
|
|
6cb03e |
+ */
|
|
|
6cb03e |
+ curname = pstrdup(curname);
|
|
|
6cb03e |
+ canonicalize_path(curname);
|
|
|
6cb03e |
+ *namelist = lappend(*namelist, curname);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* Loop back if we didn't reach end of string */
|
|
|
6cb03e |
+ } while (!done);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ return true;
|
|
|
6cb03e |
+}
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+
|
|
|
6cb03e |
/*****************************************************************************
|
|
|
6cb03e |
* Comparison Functions used for bytea
|
|
|
6cb03e |
*
|
|
|
6cb03e |
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
|
|
|
6cb03e |
index f994af6..db5303c 100644
|
|
|
6cb03e |
--- a/src/backend/utils/init/miscinit.c
|
|
|
6cb03e |
+++ b/src/backend/utils/init/miscinit.c
|
|
|
6cb03e |
@@ -49,8 +49,8 @@
|
|
|
6cb03e |
|
|
|
6cb03e |
ProcessingMode Mode = InitProcessing;
|
|
|
6cb03e |
|
|
|
6cb03e |
-/* Note: we rely on this to initialize as zeroes */
|
|
|
6cb03e |
-static char socketLockFile[MAXPGPATH];
|
|
|
6cb03e |
+/* List of lock files to be removed at proc exit */
|
|
|
6cb03e |
+static List *lock_files = NIL;
|
|
|
6cb03e |
|
|
|
6cb03e |
|
|
|
6cb03e |
/* ----------------------------------------------------------------
|
|
|
6cb03e |
@@ -640,32 +640,35 @@ GetUserNameFromId(Oid roleid)
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * proc_exit callback to remove a lockfile.
|
|
|
6cb03e |
+ * proc_exit callback to remove lockfiles.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
static void
|
|
|
6cb03e |
-UnlinkLockFile(int status, Datum filename)
|
|
|
6cb03e |
+UnlinkLockFiles(int status, Datum arg)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- char *fname = (char *) DatumGetPointer(filename);
|
|
|
6cb03e |
+ ListCell *l;
|
|
|
6cb03e |
|
|
|
6cb03e |
- if (fname != NULL)
|
|
|
6cb03e |
+ foreach(l, lock_files)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- if (unlink(fname) != 0)
|
|
|
6cb03e |
- {
|
|
|
6cb03e |
- /* Should we complain if the unlink fails? */
|
|
|
6cb03e |
- }
|
|
|
6cb03e |
- free(fname);
|
|
|
6cb03e |
+ char *curfile = (char *) lfirst(l);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ unlink(curfile);
|
|
|
6cb03e |
+ /* Should we complain if the unlink fails? */
|
|
|
6cb03e |
}
|
|
|
6cb03e |
+ /* Since we're about to exit, no need to reclaim storage */
|
|
|
6cb03e |
+ lock_files = NIL;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Create a lockfile.
|
|
|
6cb03e |
*
|
|
|
6cb03e |
- * filename is the name of the lockfile to create.
|
|
|
6cb03e |
+ * filename is the path name of the lockfile to create.
|
|
|
6cb03e |
* amPostmaster is used to determine how to encode the output PID.
|
|
|
6cb03e |
+ * socketDir is the Unix socket directory path to include (possibly empty).
|
|
|
6cb03e |
* isDDLock and refName are used to determine what error message to produce.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
static void
|
|
|
6cb03e |
CreateLockFile(const char *filename, bool amPostmaster,
|
|
|
6cb03e |
+ const char *socketDir,
|
|
|
6cb03e |
bool isDDLock, const char *refName)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
int fd;
|
|
|
6cb03e |
@@ -891,12 +894,7 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|
|
6cb03e |
DataDir,
|
|
|
6cb03e |
(long) MyStartTime,
|
|
|
6cb03e |
PostPortNumber,
|
|
|
6cb03e |
-#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
- (*UnixSocketDir != '\0') ? UnixSocketDir : DEFAULT_PGSOCKET_DIR
|
|
|
6cb03e |
-#else
|
|
|
6cb03e |
- ""
|
|
|
6cb03e |
-#endif
|
|
|
6cb03e |
- );
|
|
|
6cb03e |
+ socketDir);
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* In a standalone backend, the next line (LOCK_FILE_LINE_LISTEN_ADDR)
|
|
|
6cb03e |
@@ -941,9 +939,14 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * Arrange for automatic removal of lockfile at proc_exit.
|
|
|
6cb03e |
+ * Arrange to unlink the lock file(s) at proc_exit. If this is the
|
|
|
6cb03e |
+ * first one, set up the on_proc_exit function to do it; then add this
|
|
|
6cb03e |
+ * lock file to the list of files to unlink.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- on_proc_exit(UnlinkLockFile, PointerGetDatum(strdup(filename)));
|
|
|
6cb03e |
+ if (lock_files == NIL)
|
|
|
6cb03e |
+ on_proc_exit(UnlinkLockFiles, 0);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ lock_files = lappend(lock_files, pstrdup(filename));
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
@@ -952,41 +955,50 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|
|
6cb03e |
* When this is called, we must have already switched the working
|
|
|
6cb03e |
* directory to DataDir, so we can just use a relative path. This
|
|
|
6cb03e |
* helps ensure that we are locking the directory we should be.
|
|
|
6cb03e |
+ *
|
|
|
6cb03e |
+ * Note that the socket directory path line is initially written as empty.
|
|
|
6cb03e |
+ * postmaster.c will rewrite it upon creating the first Unix socket.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
void
|
|
|
6cb03e |
CreateDataDirLockFile(bool amPostmaster)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, true, DataDir);
|
|
|
6cb03e |
+ CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "", true, DataDir);
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Create a lockfile for the specified Unix socket file.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
void
|
|
|
6cb03e |
-CreateSocketLockFile(const char *socketfile, bool amPostmaster)
|
|
|
6cb03e |
+CreateSocketLockFile(const char *socketfile, bool amPostmaster,
|
|
|
6cb03e |
+ const char *socketDir)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
char lockfile[MAXPGPATH];
|
|
|
6cb03e |
|
|
|
6cb03e |
snprintf(lockfile, sizeof(lockfile), "%s.lock", socketfile);
|
|
|
6cb03e |
- CreateLockFile(lockfile, amPostmaster, false, socketfile);
|
|
|
6cb03e |
- /* Save name of lockfile for TouchSocketLockFile */
|
|
|
6cb03e |
- strcpy(socketLockFile, lockfile);
|
|
|
6cb03e |
+ CreateLockFile(lockfile, amPostmaster, socketDir, false, socketfile);
|
|
|
6cb03e |
}
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * TouchSocketLockFile -- mark socket lock file as recently accessed
|
|
|
6cb03e |
+ * TouchSocketLockFiles -- mark socket lock files as recently accessed
|
|
|
6cb03e |
*
|
|
|
6cb03e |
- * This routine should be called every so often to ensure that the lock file
|
|
|
6cb03e |
- * has a recent mod or access date. That saves it
|
|
|
6cb03e |
+ * This routine should be called every so often to ensure that the socket
|
|
|
6cb03e |
+ * lock files have a recent mod or access date. That saves them
|
|
|
6cb03e |
* from being removed by overenthusiastic /tmp-directory-cleaner daemons.
|
|
|
6cb03e |
* (Another reason we should never have put the socket file in /tmp...)
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
void
|
|
|
6cb03e |
-TouchSocketLockFile(void)
|
|
|
6cb03e |
+TouchSocketLockFiles(void)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- /* Do nothing if we did not create a socket... */
|
|
|
6cb03e |
- if (socketLockFile[0] != '\0')
|
|
|
6cb03e |
+ ListCell *l;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ foreach(l, lock_files)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
+ char *socketLockFile = (char *) lfirst(l);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /* No need to touch the data directory lock file, we trust */
|
|
|
6cb03e |
+ if (strcmp(socketLockFile, DIRECTORY_LOCK_FILE) == 0)
|
|
|
6cb03e |
+ continue;
|
|
|
6cb03e |
+
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* utime() is POSIX standard, utimes() is a common alternative; if we
|
|
|
6cb03e |
* have neither, fall back to actually reading the file (which only
|
|
|
6cb03e |
@@ -1018,8 +1030,10 @@ TouchSocketLockFile(void)
|
|
|
6cb03e |
* Add (or replace) a line in the data directory lock file.
|
|
|
6cb03e |
* The given string should not include a trailing newline.
|
|
|
6cb03e |
*
|
|
|
6cb03e |
- * Caution: this erases all following lines. In current usage that is OK
|
|
|
6cb03e |
- * because lines are added in order. We could improve it if needed.
|
|
|
6cb03e |
+ * Note: because we don't truncate the file, if we were to rewrite a line
|
|
|
6cb03e |
+ * with less data than it had before, there would be garbage after the last
|
|
|
6cb03e |
+ * line. We don't ever actually do that, so not worth adding another kernel
|
|
|
6cb03e |
+ * call to cover the possibility.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
void
|
|
|
6cb03e |
AddToDataDirLockFile(int target_line, const char *str)
|
|
|
6cb03e |
@@ -1027,8 +1041,10 @@ AddToDataDirLockFile(int target_line, const char *str)
|
|
|
6cb03e |
int fd;
|
|
|
6cb03e |
int len;
|
|
|
6cb03e |
int lineno;
|
|
|
6cb03e |
- char *ptr;
|
|
|
6cb03e |
- char buffer[BLCKSZ];
|
|
|
6cb03e |
+ char *srcptr;
|
|
|
6cb03e |
+ char *destptr;
|
|
|
6cb03e |
+ char srcbuffer[BLCKSZ];
|
|
|
6cb03e |
+ char destbuffer[BLCKSZ];
|
|
|
6cb03e |
|
|
|
6cb03e |
fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
|
|
|
6cb03e |
if (fd < 0)
|
|
|
6cb03e |
@@ -1039,7 +1055,7 @@ AddToDataDirLockFile(int target_line, const char *str)
|
|
|
6cb03e |
DIRECTORY_LOCK_FILE)));
|
|
|
6cb03e |
return;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
- len = read(fd, buffer, sizeof(buffer) - 1);
|
|
|
6cb03e |
+ len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
|
|
|
6cb03e |
if (len < 0)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
ereport(LOG,
|
|
|
6cb03e |
@@ -1049,37 +1065,51 @@ AddToDataDirLockFile(int target_line, const char *str)
|
|
|
6cb03e |
close(fd);
|
|
|
6cb03e |
return;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
- buffer[len] = '\0';
|
|
|
6cb03e |
+ srcbuffer[len] = '\0';
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * Skip over lines we are not supposed to rewrite.
|
|
|
6cb03e |
+ * Advance over lines we are not supposed to rewrite, then copy them
|
|
|
6cb03e |
+ * to destbuffer.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- ptr = buffer;
|
|
|
6cb03e |
+ srcptr = srcbuffer;
|
|
|
6cb03e |
for (lineno = 1; lineno < target_line; lineno++)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- if ((ptr = strchr(ptr, '\n')) == NULL)
|
|
|
6cb03e |
+ if ((srcptr = strchr(srcptr, '\n')) == NULL)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
elog(LOG, "incomplete data in \"%s\": found only %d newlines while trying to add line %d",
|
|
|
6cb03e |
DIRECTORY_LOCK_FILE, lineno - 1, target_line);
|
|
|
6cb03e |
close(fd);
|
|
|
6cb03e |
return;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
- ptr++;
|
|
|
6cb03e |
+ srcptr++;
|
|
|
6cb03e |
}
|
|
|
6cb03e |
+ memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
|
|
|
6cb03e |
+ destptr = destbuffer + (srcptr - srcbuffer);
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* Write or rewrite the target line.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- snprintf(ptr, buffer + sizeof(buffer) - ptr, "%s\n", str);
|
|
|
6cb03e |
+ snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);
|
|
|
6cb03e |
+ destptr += strlen(destptr);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
+ /*
|
|
|
6cb03e |
+ * If there are more lines in the old file, append them to destbuffer.
|
|
|
6cb03e |
+ */
|
|
|
6cb03e |
+ if ((srcptr = strchr(srcptr, '\n')) != NULL)
|
|
|
6cb03e |
+ {
|
|
|
6cb03e |
+ srcptr++;
|
|
|
6cb03e |
+ snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s",
|
|
|
6cb03e |
+ srcptr);
|
|
|
6cb03e |
+ }
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* And rewrite the data. Since we write in a single kernel call, this
|
|
|
6cb03e |
* update should appear atomic to onlookers.
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
- len = strlen(buffer);
|
|
|
6cb03e |
+ len = strlen(destbuffer);
|
|
|
6cb03e |
errno = 0;
|
|
|
6cb03e |
if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
|
|
|
6cb03e |
- (int) write(fd, buffer, len) != len)
|
|
|
6cb03e |
+ (int) write(fd, destbuffer, len) != len)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
/* if write didn't set errno, assume problem is no disk space */
|
|
|
6cb03e |
if (errno == 0)
|
|
|
6cb03e |
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
|
|
|
6cb03e |
index e5ee0f8..1428cb6 100644
|
|
|
6cb03e |
--- a/src/backend/utils/misc/guc.c
|
|
|
6cb03e |
+++ b/src/backend/utils/misc/guc.c
|
|
|
6cb03e |
@@ -2894,14 +2894,18 @@ static struct config_string ConfigureNamesString[] =
|
|
|
6cb03e |
},
|
|
|
6cb03e |
|
|
|
6cb03e |
{
|
|
|
6cb03e |
- {"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
|
|
6cb03e |
- gettext_noop("Sets the directory where the Unix-domain socket will be created."),
|
|
|
6cb03e |
+ {"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
|
|
|
6cb03e |
+ gettext_noop("Sets the directories where Unix-domain sockets will be created."),
|
|
|
6cb03e |
NULL,
|
|
|
6cb03e |
GUC_SUPERUSER_ONLY
|
|
|
6cb03e |
},
|
|
|
6cb03e |
- &UnixSocketDir,
|
|
|
6cb03e |
+ &Unix_socket_directories,
|
|
|
6cb03e |
+#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
+ DEFAULT_PGSOCKET_DIR,
|
|
|
6cb03e |
+#else
|
|
|
6cb03e |
"",
|
|
|
6cb03e |
- check_canonical_path, NULL, NULL
|
|
|
6cb03e |
+#endif
|
|
|
6cb03e |
+ NULL, NULL, NULL
|
|
|
6cb03e |
},
|
|
|
6cb03e |
|
|
|
6cb03e |
{
|
|
|
6cb03e |
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
|
|
|
6cb03e |
index 013a91a..c0ab61c 100644
|
|
|
6cb03e |
--- a/src/backend/utils/misc/postgresql.conf.sample
|
|
|
6cb03e |
+++ b/src/backend/utils/misc/postgresql.conf.sample
|
|
|
6cb03e |
@@ -67,7 +67,8 @@
|
|
|
6cb03e |
# Note: Increasing max_connections costs ~400 bytes of shared memory per
|
|
|
6cb03e |
# connection slot, plus lock space (see max_locks_per_transaction).
|
|
|
6cb03e |
#superuser_reserved_connections = 3 # (change requires restart)
|
|
|
6cb03e |
-#unix_socket_directory = '' # (change requires restart)
|
|
|
6cb03e |
+#unix_socket_directories = '/tmp' # comma-separated list of directories
|
|
|
6cb03e |
+ # (change requires restart)
|
|
|
6cb03e |
#unix_socket_group = '' # (change requires restart)
|
|
|
6cb03e |
#unix_socket_permissions = 0777 # begin with 0 to use octal notation
|
|
|
6cb03e |
# (change requires restart)
|
|
|
6cb03e |
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
|
|
|
6cb03e |
index 23fa468..452ac0b 100644
|
|
|
6cb03e |
--- a/src/bin/initdb/initdb.c
|
|
|
6cb03e |
+++ b/src/bin/initdb/initdb.c
|
|
|
6cb03e |
@@ -991,7 +991,7 @@ static void
|
|
|
6cb03e |
setup_config(void)
|
|
|
6cb03e |
{
|
|
|
6cb03e |
char **conflines;
|
|
|
6cb03e |
- char repltok[TZ_STRLEN_MAX + 100];
|
|
|
6cb03e |
+ char repltok[MAXPGPATH];
|
|
|
6cb03e |
char path[MAXPGPATH];
|
|
|
6cb03e |
const char *default_timezone;
|
|
|
6cb03e |
|
|
|
6cb03e |
@@ -1013,6 +1013,15 @@ setup_config(void)
|
|
|
6cb03e |
n_buffers * (BLCKSZ / 1024));
|
|
|
6cb03e |
conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);
|
|
|
6cb03e |
|
|
|
6cb03e |
+#ifdef HAVE_UNIX_SOCKETS
|
|
|
6cb03e |
+ snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
|
|
|
6cb03e |
+ DEFAULT_PGSOCKET_DIR);
|
|
|
6cb03e |
+#else
|
|
|
6cb03e |
+ snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
|
|
|
6cb03e |
+#endif
|
|
|
6cb03e |
+ conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
|
|
|
6cb03e |
+ repltok);
|
|
|
6cb03e |
+
|
|
|
6cb03e |
#if DEF_PGPORT != 5432
|
|
|
6cb03e |
snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
|
|
|
6cb03e |
conflines = replace_token(conflines, "#port = 5432", repltok);
|
|
|
6cb03e |
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
|
|
|
6cb03e |
index 66ef6bd..b815ef2 100644
|
|
|
6cb03e |
--- a/src/bin/pg_ctl/pg_ctl.c
|
|
|
6cb03e |
+++ b/src/bin/pg_ctl/pg_ctl.c
|
|
|
6cb03e |
@@ -561,7 +561,7 @@ test_postmaster_connection(bool do_checkpoint)
|
|
|
6cb03e |
hostaddr = optlines[LOCK_FILE_LINE_LISTEN_ADDR - 1];
|
|
|
6cb03e |
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
- * While unix_socket_directory can accept relative
|
|
|
6cb03e |
+ * While unix_socket_directories can accept relative
|
|
|
6cb03e |
* directories, libpq's host parameter must have a
|
|
|
6cb03e |
* leading slash to indicate a socket directory. So,
|
|
|
6cb03e |
* ignore sockdir if it's relative, and try to use TCP
|
|
|
6cb03e |
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
|
|
|
6cb03e |
index 6dd91ba..2bfec2b 100644
|
|
|
6cb03e |
--- a/src/include/libpq/libpq.h
|
|
|
6cb03e |
+++ b/src/include/libpq/libpq.h
|
|
|
6cb03e |
@@ -44,12 +44,12 @@ typedef struct
|
|
|
6cb03e |
/*
|
|
|
6cb03e |
* prototypes for functions in pqcomm.c
|
|
|
6cb03e |
*/
|
|
|
6cb03e |
-extern int StreamServerPort(int family, char *hostName,
|
|
|
6cb03e |
- unsigned short portNumber, char *unixSocketName, pgsocket ListenSocket[],
|
|
|
6cb03e |
- int MaxListen);
|
|
|
6cb03e |
+extern int StreamServerPort(int family, char *hostName,
|
|
|
6cb03e |
+ unsigned short portNumber, char *unixSocketDir,
|
|
|
6cb03e |
+ pgsocket ListenSocket[], int MaxListen);
|
|
|
6cb03e |
extern int StreamConnection(pgsocket server_fd, Port *port);
|
|
|
6cb03e |
extern void StreamClose(pgsocket sock);
|
|
|
6cb03e |
-extern void TouchSocketFile(void);
|
|
|
6cb03e |
+extern void TouchSocketFiles(void);
|
|
|
6cb03e |
extern void pq_init(void);
|
|
|
6cb03e |
extern void pq_comm_reset(void);
|
|
|
6cb03e |
extern int pq_getbytes(char *s, size_t len);
|
|
|
6cb03e |
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
|
|
|
6cb03e |
index 1051ca4..e6c663c 100644
|
|
|
6cb03e |
--- a/src/include/miscadmin.h
|
|
|
6cb03e |
+++ b/src/include/miscadmin.h
|
|
|
6cb03e |
@@ -424,7 +424,7 @@ extern char *local_preload_libraries_string;
|
|
|
6cb03e |
* 2 data directory path
|
|
|
6cb03e |
* 3 postmaster start timestamp (time_t representation)
|
|
|
6cb03e |
* 4 port number
|
|
|
6cb03e |
- * 5 socket directory path (empty on Windows)
|
|
|
6cb03e |
+ * 5 first Unix socket directory path (empty if none)
|
|
|
6cb03e |
* 6 first listen_address (IP address or "*"; empty if no TCP port)
|
|
|
6cb03e |
* 7 shared memory key (not present on Windows)
|
|
|
6cb03e |
*
|
|
|
6cb03e |
@@ -443,8 +443,9 @@ extern char *local_preload_libraries_string;
|
|
|
6cb03e |
#define LOCK_FILE_LINE_SHMEM_KEY 7
|
|
|
6cb03e |
|
|
|
6cb03e |
extern void CreateDataDirLockFile(bool amPostmaster);
|
|
|
6cb03e |
-extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster);
|
|
|
6cb03e |
-extern void TouchSocketLockFile(void);
|
|
|
6cb03e |
+extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
|
|
|
6cb03e |
+ const char *socketDir);
|
|
|
6cb03e |
+extern void TouchSocketLockFiles(void);
|
|
|
6cb03e |
extern void AddToDataDirLockFile(int target_line, const char *str);
|
|
|
6cb03e |
extern bool RecheckDataDirLockFile(void);
|
|
|
6cb03e |
extern void ValidatePgVersion(const char *path);
|
|
|
6cb03e |
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
|
|
|
6cb03e |
index 683ce3c..080a8ca 100644
|
|
|
6cb03e |
--- a/src/include/postmaster/postmaster.h
|
|
|
6cb03e |
+++ b/src/include/postmaster/postmaster.h
|
|
|
6cb03e |
@@ -19,7 +19,7 @@ extern int ReservedBackends;
|
|
|
6cb03e |
extern int PostPortNumber;
|
|
|
6cb03e |
extern int Unix_socket_permissions;
|
|
|
6cb03e |
extern char *Unix_socket_group;
|
|
|
6cb03e |
-extern char *UnixSocketDir;
|
|
|
6cb03e |
+extern char *Unix_socket_directories;
|
|
|
6cb03e |
extern char *ListenAddresses;
|
|
|
6cb03e |
extern bool ClientAuthInProgress;
|
|
|
6cb03e |
extern int PreAuthDelay;
|
|
|
6cb03e |
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
|
|
|
6cb03e |
index 4bf07e4..c830243 100644
|
|
|
6cb03e |
--- a/src/include/utils/builtins.h
|
|
|
6cb03e |
+++ b/src/include/utils/builtins.h
|
|
|
6cb03e |
@@ -754,6 +754,8 @@ extern int varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid);
|
|
|
6cb03e |
extern List *textToQualifiedNameList(text *textval);
|
|
|
6cb03e |
extern bool SplitIdentifierString(char *rawstring, char separator,
|
|
|
6cb03e |
List **namelist);
|
|
|
6cb03e |
+extern bool SplitDirectoriesString(char *rawstring, char separator,
|
|
|
6cb03e |
+ List **namelist);
|
|
|
6cb03e |
extern Datum replace_text(PG_FUNCTION_ARGS);
|
|
|
6cb03e |
extern text *replace_text_regexp(text *src_text, void *regexp,
|
|
|
6cb03e |
text *replace_text, bool glob);
|
|
|
6cb03e |
diff --git a/doc/src/sgml/html-stamp b/doc/src/sgml/html-stamp
|
|
|
6cb03e |
index e69de29..fcf9276 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/html-stamp
|
|
|
6cb03e |
+++ b/doc/src/sgml/html-stamp
|
|
|
6cb03e |
@@ -0,0 +1 @@
|
|
|
6cb03e |
+hack
|
|
|
6cb03e |
diff --git a/doc/src/sgml/man-stamp b/doc/src/sgml/man-stamp
|
|
|
6cb03e |
index e69de29..fcf9276 100644
|
|
|
6cb03e |
--- a/doc/src/sgml/man-stamp
|
|
|
6cb03e |
+++ b/doc/src/sgml/man-stamp
|
|
|
6cb03e |
@@ -0,0 +1 @@
|
|
|
6cb03e |
+hack
|