[postgresql/f18] Place Unix sockets in /var/run/postgresql.

Tom Lane tgl at fedoraproject.org
Mon Aug 13 17:18:38 UTC 2012


commit 8a9c7c27275651aa313d64c9240e465f48d2e7ef
Author: Tom Lane <tgl at redhat.com>
Date:   Mon Aug 13 13:13:01 2012 -0400

    Place Unix sockets in /var/run/postgresql.

 generate-pdf.sh                 |    8 +-
 postgresql-config-comment.patch |   26 +
 postgresql-multi-sockets.patch  | 1182 +++++++++++++++++++++++++++++++++++++++
 postgresql-var-run-socket.patch |   94 +++
 postgresql.spec                 |   47 +-
 postgresql.tmpfiles.d           |    1 +
 sources                         |    2 +-
 7 files changed, 1340 insertions(+), 20 deletions(-)
---
diff --git a/generate-pdf.sh b/generate-pdf.sh
index 8a8ada5..1365bb4 100755
--- a/generate-pdf.sh
+++ b/generate-pdf.sh
@@ -22,7 +22,7 @@ TARGETFILE=postgresql-$VERSION-US.pdf
 
 echo Building $TARGETFILE ...
 
-# Unpack and configure postgresql
+# Unpack postgresql
 
 rm -rf postgresql-$VERSION
 
@@ -30,6 +30,12 @@ tar xfj postgresql-$VERSION.tar.bz2
 
 cd postgresql-$VERSION
 
+# Apply any patches that affect the PDF documentation
+
+patch -p1 < ../postgresql-multi-sockets.patch
+
+# Configure ...
+
 ./configure >/dev/null
 
 # Build the PDF docs
diff --git a/postgresql-config-comment.patch b/postgresql-config-comment.patch
new file mode 100644
index 0000000..58c62b5
--- /dev/null
+++ b/postgresql-config-comment.patch
@@ -0,0 +1,26 @@
+Add notes warning users that the data directory and port number are
+forced in the service file (the latter now mostly because it's traditional
+in Red Hat installations to set it there rather than in postgresql.conf).
+
+
+diff -Naur postgresql-9.1.4.orig/src/backend/utils/misc/postgresql.conf.sample postgresql-9.1.4/src/backend/utils/misc/postgresql.conf.sample
+--- postgresql-9.1.4.orig/src/backend/utils/misc/postgresql.conf.sample	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/utils/misc/postgresql.conf.sample	2012-08-13 12:15:10.939846705 -0400
+@@ -38,6 +38,8 @@
+ # The default values of these variables are driven from the -D command-line
+ # option or PGDATA environment variable, represented here as ConfigDir.
+ 
++# Note: In RHEL/Fedora installations, you can't set data_directory here;
++# adjust it in the service file instead.
+ #data_directory = 'ConfigDir'		# use data in another directory
+ 					# (change requires restart)
+ #hba_file = 'ConfigDir/pg_hba.conf'	# host-based authentication file
+@@ -60,6 +62,8 @@
+ 					# comma-separated list of addresses;
+ 					# defaults to 'localhost', '*' = all
+ 					# (change requires restart)
++# Note: In RHEL/Fedora installations, you can't set the port number here;
++# adjust it in the service file instead.
+ #port = 5432				# (change requires restart)
+ #max_connections = 100			# (change requires restart)
+ # Note:  Increasing max_connections costs ~400 bytes of shared memory per
diff --git a/postgresql-multi-sockets.patch b/postgresql-multi-sockets.patch
new file mode 100644
index 0000000..efebb8f
--- /dev/null
+++ b/postgresql-multi-sockets.patch
@@ -0,0 +1,1182 @@
+Back-port of upstream 9.3 patch to support multiple sockets
+(upstream git commit c9b0cbe98bd783e24a8c4d8d8ac472a494b81292,
+plus updates of derived documentation files).
+
+Note the patch also touches html-stamp and man-stamp in doc/src/sgml/;
+this is to keep the makefiles from trying to rebuild the derived doc
+files.  We don't want that to happen because the BuildRequires for the
+package don't include the necessary documentation tools.
+
+
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/client-auth.sgml postgresql-9.1.4/doc/src/sgml/client-auth.sgml
+--- postgresql-9.1.4.orig/doc/src/sgml/client-auth.sgml	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/client-auth.sgml	2012-08-12 19:31:41.479999838 -0400
+@@ -831,7 +831,7 @@
+     <varname>unix_socket_permissions</varname> (and possibly
+     <varname>unix_socket_group</varname>) configuration parameters as
+     described in <xref linkend="runtime-config-connection">.  Or you
+-    could set the <varname>unix_socket_directory</varname>
++    could set the <varname>unix_socket_directories</varname>
+     configuration parameter to place the socket file in a suitably
+     restricted directory.
+    </para>
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/config.sgml postgresql-9.1.4/doc/src/sgml/config.sgml
+--- postgresql-9.1.4.orig/doc/src/sgml/config.sgml	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/config.sgml	2012-08-12 19:31:41.481999903 -0400
+@@ -417,17 +417,24 @@
+       </listitem>
+      </varlistentry>
+ 
+-     <varlistentry id="guc-unix-socket-directory" xreflabel="unix_socket_directory">
+-      <term><varname>unix_socket_directory</varname> (<type>string</type>)</term>
++     <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
++      <term><varname>unix_socket_directories</varname> (<type>string</type>)</term>
+       <indexterm>
+-       <primary><varname>unix_socket_directory</> configuration parameter</primary>
++       <primary><varname>unix_socket_directories</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+-        Specifies the directory of the Unix-domain socket on which the
+-        server is to listen for
+-        connections from client applications.  The default is normally
+-        <filename>/tmp</filename>, but can be changed at build time.
++        Specifies the directory of the Unix-domain socket(s) on which the
++        server is to listen for connections from client applications.
++        Multiple sockets can be created by listing multiple directories
++        separated by commas.  Whitespace between entries is
++        ignored; surround a directory name with double quotes if you need
++        to include whitespace or commas in the name.
++        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
++        <filename>/tmp</filename>, but that can be changed at build time.
+         This parameter can only be set at server start.
+        </para>
+ 
+@@ -436,8 +443,8 @@
+         <literal>.s.PGSQL.<replaceable>nnnn</></literal> where
+         <replaceable>nnnn</> is the server's port number, an ordinary file
+         named <literal>.s.PGSQL.<replaceable>nnnn</>.lock</literal> will be
+-        created in the <varname>unix_socket_directory</> directory.  Neither
+-        file should ever be removed manually.
++        created in each of the <varname>unix_socket_directories</> directories.
++        Neither file should ever be removed manually.
+        </para>
+ 
+        <para>
+@@ -454,8 +461,8 @@
+       </indexterm>
+       <listitem>
+        <para>
+-        Sets the owning group of the Unix-domain socket.  (The owning
+-        user of the socket is always the user that starts the
++        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.
+@@ -478,7 +485,7 @@
+       </indexterm>
+       <listitem>
+        <para>
+-        Sets the access permissions of the Unix-domain socket.  Unix-domain
++        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
+@@ -6413,7 +6420,7 @@
+        </row>
+        <row>
+         <entry><option>-k <replaceable>x</replaceable></option></entry>
+-        <entry><literal>unix_socket_directory = <replaceable>x</replaceable></></entry>
++        <entry><literal>unix_socket_directories = <replaceable>x</replaceable></></entry>
+        </row>
+        <row>
+         <entry><option>-l</option></entry>
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/app-postgres.html postgresql-9.1.4/doc/src/sgml/html/app-postgres.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/app-postgres.html	2012-05-31 19:23:13.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/app-postgres.html	2012-08-12 19:32:55.022709775 -0400
+@@ -531,11 +531,19 @@
+ CLASS="COMMAND"
+ >postgres</TT
+ > is to listen for
+-        connections from client applications.  The default is normally
++        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
+         <TT
+ CLASS="FILENAME"
+ >/tmp</TT
+->, but can be changed at build time.
++>, but that can be changed at build time.
++        Specifying this option is equivalent to setting the <A
++HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
++>unix_socket_directories</A
++> configuration parameter.
+        </P
+ ></DD
+ ><DT
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/auth-methods.html postgresql-9.1.4/doc/src/sgml/html/auth-methods.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/auth-methods.html	2012-05-31 19:22:57.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/auth-methods.html	2012-08-12 19:32:37.316538936 -0400
+@@ -161,7 +161,7 @@
+ >.  Or you
+     could set the <TT
+ CLASS="VARNAME"
+->unix_socket_directory</TT
++>unix_socket_directories</TT
+ >
+     configuration parameter to place the socket file in a suitably
+     restricted directory.
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/bookindex.html postgresql-9.1.4/doc/src/sgml/html/bookindex.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/bookindex.html	2012-05-31 19:23:47.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/bookindex.html	2012-08-12 19:33:28.487032655 -0400
+@@ -16893,7 +16893,7 @@
+ ></DL
+ ></DD
+ ><DT
+->unix_socket_directory configuration parameter,
++>unix_socket_directories configuration parameter,
+     <A
+ HREF="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS"
+ >Connection Settings</A
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/preventing-server-spoofing.html postgresql-9.1.4/doc/src/sgml/html/preventing-server-spoofing.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/preventing-server-spoofing.html	2012-05-31 19:22:56.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/preventing-server-spoofing.html	2012-08-12 19:32:36.060526818 -0400
+@@ -115,8 +115,8 @@
+ >local</TT
+ >
+    connections is to use a Unix domain socket directory (<A
+-HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORY"
+->unix_socket_directory</A
++HREF="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES"
++>unix_socket_directories</A
+ >) that has write permission only
+    for a trusted local user.  This prevents a malicious user from creating
+    their own socket file in that directory.  If you are concerned that
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/runtime-config-connection.html postgresql-9.1.4/doc/src/sgml/html/runtime-config-connection.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/runtime-config-connection.html	2012-05-31 19:22:56.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/runtime-config-connection.html	2012-08-12 19:32:36.376529867 -0400
+@@ -274,24 +274,31 @@
+ ></DD
+ ><DT
+ ><A
+-NAME="GUC-UNIX-SOCKET-DIRECTORY"
++NAME="GUC-UNIX-SOCKET-DIRECTORIES"
+ ></A
+ ><TT
+ CLASS="VARNAME"
+->unix_socket_directory</TT
++>unix_socket_directories</TT
+ > (<TT
+ CLASS="TYPE"
+ >string</TT
+ >)</DT
+ ><DD
+ ><P
+->        Specifies the directory of the Unix-domain socket on which the
+-        server is to listen for
+-        connections from client applications.  The default is normally
++>        Specifies the directory of the Unix-domain socket(s) on which the
++        server is to listen for connections from client applications.
++        Multiple sockets can be created by listing multiple directories
++        separated by commas.  Whitespace between entries is
++        ignored; surround a directory name with double quotes if you need
++        to include whitespace or commas in the name.
++        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
+         <TT
+ CLASS="FILENAME"
+ >/tmp</TT
+->, but can be changed at build time.
++>, but that can be changed at build time.
+         This parameter can only be set at server start.
+        </P
+ ><P
+@@ -320,11 +327,11 @@
+ ></TT
+ >.lock</TT
+ > will be
+-        created in the <TT
++        created in each of the <TT
+ CLASS="VARNAME"
+->unix_socket_directory</TT
+-> directory.  Neither
+-        file should ever be removed manually.
++>unix_socket_directories</TT
++> directories.
++        Neither file should ever be removed manually.
+        </P
+ ><P
+ >        This parameter is irrelevant on Windows, which does not have
+@@ -344,8 +351,8 @@
+ >)</DT
+ ><DD
+ ><P
+->        Sets the owning group of the Unix-domain socket.  (The owning
+-        user of the socket is always the user that starts the
++>        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
+         <TT
+ CLASS="VARNAME"
+@@ -374,7 +381,7 @@
+ >)</DT
+ ><DD
+ ><P
+->        Sets the access permissions of the Unix-domain socket.  Unix-domain
++>        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
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html/runtime-config-short.html postgresql-9.1.4/doc/src/sgml/html/runtime-config-short.html
+--- postgresql-9.1.4.orig/doc/src/sgml/html/runtime-config-short.html	2012-05-31 19:22:57.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html/runtime-config-short.html	2012-08-12 19:32:37.044536313 -0400
+@@ -323,7 +323,7 @@
+ ><TD
+ ><TT
+ CLASS="LITERAL"
+->unix_socket_directory = <TT
++>unix_socket_directories = <TT
+ CLASS="REPLACEABLE"
+ ><I
+ >x</I
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/man1/postgres.1 postgresql-9.1.4/doc/src/sgml/man1/postgres.1
+--- postgresql-9.1.4.orig/doc/src/sgml/man1/postgres.1	2012-05-31 19:24:40.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/man1/postgres.1	2012-08-12 19:34:17.019500922 -0400
+@@ -180,8 +180,10 @@
+ .RS 4
+ Specifies the directory of the Unix\-domain socket on which
+ postgres
+-is to listen for connections from client applications\&. The default is normally
+-/tmp, but can be changed at build time\&.
++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
++/tmp, but that can be changed at build time\&. Specifying this option is equivalent to setting the
++unix_socket_directories
++configuration parameter\&.
+ .RE
+ .PP
+ \fB\-l\fR
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/ref/postgres-ref.sgml postgresql-9.1.4/doc/src/sgml/ref/postgres-ref.sgml
+--- postgresql-9.1.4.orig/doc/src/sgml/ref/postgres-ref.sgml	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/ref/postgres-ref.sgml	2012-08-12 19:31:41.481999903 -0400
+@@ -233,8 +233,14 @@
+        <para>
+         Specifies the directory of the Unix-domain socket on which
+         <command>postgres</command> is to listen for
+-        connections from client applications.  The default is normally
+-        <filename>/tmp</filename>, but can be changed at build time.
++        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
++        <filename>/tmp</filename>, but that can be changed at build time.
++        Specifying this option is equivalent to setting the <xref
++        linkend="guc-unix-socket-directories"> configuration parameter.
+        </para>
+       </listitem>
+      </varlistentry>
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/runtime.sgml postgresql-9.1.4/doc/src/sgml/runtime.sgml
+--- postgresql-9.1.4.orig/doc/src/sgml/runtime.sgml	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/runtime.sgml	2012-08-12 19:31:41.482999933 -0400
+@@ -1816,7 +1816,7 @@
+   <para>
+    The simplest way to prevent spoofing for <literal>local</>
+    connections is to use a Unix domain socket directory (<xref
+-   linkend="guc-unix-socket-directory">) that has write permission only
++   linkend="guc-unix-socket-directories">) that has write permission only
+    for a trusted local user.  This prevents a malicious user from creating
+    their own socket file in that directory.  If you are concerned that
+    some applications might still reference <filename>/tmp</> for the
+diff -Naur postgresql-9.1.4.orig/src/backend/libpq/pqcomm.c postgresql-9.1.4/src/backend/libpq/pqcomm.c
+--- postgresql-9.1.4.orig/src/backend/libpq/pqcomm.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/libpq/pqcomm.c	2012-08-12 19:31:41.483999957 -0400
+@@ -42,7 +42,7 @@
+  *		StreamServerPort	- Open postmaster's server port
+  *		StreamConnection	- Create new connection with client
+  *		StreamClose			- Close a client/backend connection
+- *		TouchSocketFile		- Protect socket file against /tmp cleaners
++ *		TouchSocketFiles	- Protect socket files against /tmp cleaners
+  *		pq_init			- initialize libpq at backend startup
+  *		pq_comm_reset	- reset libpq during error recovery
+  *		pq_close		- shutdown libpq at backend exit
+@@ -103,8 +103,8 @@
+ char	   *Unix_socket_group;
+ 
+ 
+-/* Where the Unix socket file is */
+-static char sock_path[MAXPGPATH];
++/* Where the Unix socket files are (list of palloc'd strings) */
++static List *sock_paths = NIL;
+ 
+ 
+ /*
+@@ -140,8 +140,8 @@
+ static void pq_set_nonblocking(bool nonblocking);
+ 
+ #ifdef HAVE_UNIX_SOCKETS
+-static int	Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName);
+-static int	Setup_AF_UNIX(void);
++static int	Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath);
++static int	Setup_AF_UNIX(char *sock_path);
+ #endif   /* HAVE_UNIX_SOCKETS */
+ 
+ 
+@@ -234,29 +234,43 @@
+ 
+ /* StreamDoUnlink()
+  * Shutdown routine for backend connection
+- * If a Unix socket is used for communication, explicitly close it.
++ * If any Unix sockets are used for communication, explicitly close them.
+  */
+ #ifdef HAVE_UNIX_SOCKETS
+ static void
+ StreamDoUnlink(int code, Datum arg)
+ {
+-	Assert(sock_path[0]);
+-	unlink(sock_path);
++	ListCell   *l;
++
++	/* Loop through all created sockets... */
++	foreach(l, sock_paths)
++	{
++		char	   *sock_path = (char *) lfirst(l);
++
++		unlink(sock_path);
++	}
++	/* Since we're about to exit, no need to reclaim storage */
++	sock_paths = NIL;
+ }
+ #endif   /* HAVE_UNIX_SOCKETS */
+ 
+ /*
+  * StreamServerPort -- open a "listening" port to accept connections.
+  *
+- * Successfully opened sockets are added to the ListenSocket[] array,
+- * at the first position that isn't PGINVALID_SOCKET.
++ * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number.
++ * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be
++ * specified.  For TCP ports, hostName is either NULL for all interfaces or
++ * the interface to listen on, and unixSocketDir is ignored (can be NULL).
++ *
++ * Successfully opened sockets are added to the ListenSocket[] array (of
++ * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
+  *
+  * RETURNS: STATUS_OK or STATUS_ERROR
+  */
+ 
+ int
+ StreamServerPort(int family, char *hostName, unsigned short portNumber,
+-				 char *unixSocketName,
++				 char *unixSocketDir,
+ 				 pgsocket ListenSocket[], int MaxListen)
+ {
+ 	pgsocket	fd;
+@@ -273,6 +287,9 @@
+ 	int			listen_index = 0;
+ 	int			added = 0;
+ 
++#ifdef HAVE_UNIX_SOCKETS
++	char		unixSocketPath[MAXPGPATH];
++#endif
+ #if !defined(WIN32) || defined(IPV6_V6ONLY)
+ 	int			one = 1;
+ #endif
+@@ -286,10 +303,14 @@
+ #ifdef HAVE_UNIX_SOCKETS
+ 	if (family == AF_UNIX)
+ 	{
+-		/* Lock_AF_UNIX will also fill in sock_path. */
+-		if (Lock_AF_UNIX(portNumber, unixSocketName) != STATUS_OK)
++		/*
++		 * Create unixSocketPath from portNumber and unixSocketDir and lock
++		 * that file path
++		 */
++		UNIXSOCK_PATH(unixSocketPath, portNumber, unixSocketDir);
++		if (Lock_AF_UNIX(unixSocketDir, unixSocketPath) != STATUS_OK)
+ 			return STATUS_ERROR;
+-		service = sock_path;
++		service = unixSocketPath;
+ 	}
+ 	else
+ #endif   /* HAVE_UNIX_SOCKETS */
+@@ -432,7 +453,7 @@
+ 					 (IS_AF_UNIX(addr->ai_family)) ?
+ 				  errhint("Is another postmaster already running on port %d?"
+ 						  " If not, remove socket file \"%s\" and retry.",
+-						  (int) portNumber, sock_path) :
++						  (int) portNumber, service) :
+ 				  errhint("Is another postmaster already running on port %d?"
+ 						  " If not, wait a few seconds and retry.",
+ 						  (int) portNumber)));
+@@ -443,7 +464,7 @@
+ #ifdef HAVE_UNIX_SOCKETS
+ 		if (addr->ai_family == AF_UNIX)
+ 		{
+-			if (Setup_AF_UNIX() != STATUS_OK)
++			if (Setup_AF_UNIX(service) != STATUS_OK)
+ 			{
+ 				closesocket(fd);
+ 				break;
+@@ -490,10 +511,8 @@
+  * Lock_AF_UNIX -- configure unix socket file path
+  */
+ static int
+-Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
++Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath)
+ {
+-	UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
+-
+ 	/*
+ 	 * Grab an interlock file associated with the socket file.
+ 	 *
+@@ -502,13 +521,23 @@
+ 	 * more portable, and second, it lets us remove any pre-existing socket
+ 	 * file without race conditions.
+ 	 */
+-	CreateSocketLockFile(sock_path, true);
++	CreateSocketLockFile(unixSocketPath, true, unixSocketDir);
+ 
+ 	/*
+ 	 * Once we have the interlock, we can safely delete any pre-existing
+ 	 * socket file to avoid failure at bind() time.
+ 	 */
+-	unlink(sock_path);
++	unlink(unixSocketPath);
++
++	/*
++	 * Arrange to unlink the socket file(s) at proc_exit.  If this is the
++	 * first one, set up the on_proc_exit function to do it; then add this
++	 * socket file to the list of files to unlink.
++	 */
++	if (sock_paths == NIL)
++		on_proc_exit(StreamDoUnlink, 0);
++
++	sock_paths = lappend(sock_paths, pstrdup(unixSocketPath));
+ 
+ 	return STATUS_OK;
+ }
+@@ -518,11 +547,8 @@
+  * Setup_AF_UNIX -- configure unix socket permissions
+  */
+ static int
+-Setup_AF_UNIX(void)
++Setup_AF_UNIX(char *sock_path)
+ {
+-	/* Arrange to unlink the socket file at exit */
+-	on_proc_exit(StreamDoUnlink, 0);
+-
+ 	/*
+ 	 * Fix socket ownership/permission if requested.  Note we must do this
+ 	 * before we listen() to avoid a window where unwanted connections could
+@@ -704,20 +730,24 @@
+ }
+ 
+ /*
+- * TouchSocketFile -- mark socket file as recently accessed
++ * TouchSocketFiles -- mark socket files as recently accessed
+  *
+  * This routine should be called every so often to ensure that the socket
+- * file has a recent mod date (ordinary operations on sockets usually won't
+- * change the mod date).  That saves it from being removed by
++ * files have a recent mod date (ordinary operations on sockets usually won't
++ * change the mod date).  That saves them from being removed by
+  * overenthusiastic /tmp-directory-cleaner daemons.  (Another reason we should
+  * never have put the socket file in /tmp...)
+  */
+ void
+-TouchSocketFile(void)
++TouchSocketFiles(void)
+ {
+-	/* Do nothing if we did not create a socket... */
+-	if (sock_path[0] != '\0')
++	ListCell   *l;
++
++	/* Loop through all created sockets... */
++	foreach(l, sock_paths)
+ 	{
++		char	   *sock_path = (char *) lfirst(l);
++
+ 		/*
+ 		 * utime() is POSIX standard, utimes() is a common alternative. If we
+ 		 * have neither, there's no way to affect the mod or access time of
+diff -Naur postgresql-9.1.4.orig/src/backend/postmaster/postmaster.c postgresql-9.1.4/src/backend/postmaster/postmaster.c
+--- postgresql-9.1.4.orig/src/backend/postmaster/postmaster.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/postmaster/postmaster.c	2012-08-12 19:31:41.486000046 -0400
+@@ -157,7 +157,9 @@
+ 
+ /* The socket number we are listening for connections on */
+ int			PostPortNumber;
+-char	   *UnixSocketDir;
++/* The directory names for Unix socket(s) */
++char	   *Unix_socket_directories;
++/* The TCP listen address(es) */
+ char	   *ListenAddresses;
+ 
+ /*
+@@ -589,7 +591,7 @@
+ 				break;
+ 
+ 			case 'k':
+-				SetConfigOption("unix_socket_directory", optarg, PGC_POSTMASTER, PGC_S_ARGV);
++				SetConfigOption("unix_socket_directories", optarg, PGC_POSTMASTER, PGC_S_ARGV);
+ 				break;
+ 
+ 			case 'l':
+@@ -842,7 +844,7 @@
+ 		/* Need a modifiable copy of ListenAddresses */
+ 		rawstring = pstrdup(ListenAddresses);
+ 
+-		/* Parse string into list of identifiers */
++		/* Parse string into list of hostnames */
+ 		if (!SplitIdentifierString(rawstring, ',', &elemlist))
+ 		{
+ 			/* syntax error in list */
+@@ -858,12 +860,12 @@
+ 			if (strcmp(curhost, "*") == 0)
+ 				status = StreamServerPort(AF_UNSPEC, NULL,
+ 										  (unsigned short) PostPortNumber,
+-										  UnixSocketDir,
++										  NULL,
+ 										  ListenSocket, MAXLISTEN);
+ 			else
+ 				status = StreamServerPort(AF_UNSPEC, curhost,
+ 										  (unsigned short) PostPortNumber,
+-										  UnixSocketDir,
++										  NULL,
+ 										  ListenSocket, MAXLISTEN);
+ 
+ 			if (status == STATUS_OK)
+@@ -882,7 +884,7 @@
+ 								curhost)));
+ 		}
+ 
+-		if (!success && list_length(elemlist))
++		if (!success && elemlist != NIL)
+ 			ereport(FATAL,
+ 					(errmsg("could not create any TCP/IP sockets")));
+ 
+@@ -929,13 +931,54 @@
+ #endif
+ 
+ #ifdef HAVE_UNIX_SOCKETS
+-	status = StreamServerPort(AF_UNIX, NULL,
+-							  (unsigned short) PostPortNumber,
+-							  UnixSocketDir,
+-							  ListenSocket, MAXLISTEN);
+-	if (status != STATUS_OK)
+-		ereport(WARNING,
+-				(errmsg("could not create Unix-domain socket")));
++	if (Unix_socket_directories)
++	{
++		char	   *rawstring;
++		List	   *elemlist;
++		ListCell   *l;
++		int			success = 0;
++
++		/* Need a modifiable copy of Unix_socket_directories */
++		rawstring = pstrdup(Unix_socket_directories);
++
++		/* Parse string into list of directories */
++		if (!SplitDirectoriesString(rawstring, ',', &elemlist))
++		{
++			/* syntax error in list */
++			ereport(FATAL,
++					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
++					 errmsg("invalid list syntax for \"unix_socket_directories\"")));
++		}
++
++		foreach(l, elemlist)
++		{
++			char	   *socketdir = (char *) lfirst(l);
++
++			status = StreamServerPort(AF_UNIX, NULL,
++									  (unsigned short) PostPortNumber,
++									  socketdir,
++									  ListenSocket, MAXLISTEN);
++
++			if (status == STATUS_OK)
++			{
++				success++;
++				/* record the first successful Unix socket in lockfile */
++				if (success == 1)
++					AddToDataDirLockFile(LOCK_FILE_LINE_SOCKET_DIR, socketdir);
++			}
++			else
++				ereport(WARNING,
++						(errmsg("could not create Unix-domain socket in directory \"%s\"",
++								socketdir)));
++		}
++
++		if (!success && elemlist != NIL)
++			ereport(FATAL,
++					(errmsg("could not create any Unix-domain sockets")));
++
++		list_free_deep(elemlist);
++		pfree(rawstring);
++	}
+ #endif
+ 
+ 	/*
+@@ -1523,15 +1566,15 @@
+ 		}
+ 
+ 		/*
+-		 * Touch the socket and lock file every 58 minutes, to ensure that
++		 * Touch Unix socket and lock files every 58 minutes, to ensure that
+ 		 * they are not removed by overzealous /tmp-cleaning tasks.  We assume
+ 		 * no one runs cleaners with cutoff times of less than an hour ...
+ 		 */
+ 		now = time(NULL);
+ 		if (now - last_touch_time >= 58 * SECS_PER_MINUTE)
+ 		{
+-			TouchSocketFile();
+-			TouchSocketLockFile();
++			TouchSocketFiles();
++			TouchSocketLockFiles();
+ 			last_touch_time = now;
+ 		}
+ 	}
+diff -Naur postgresql-9.1.4.orig/src/backend/tcop/postgres.c postgresql-9.1.4/src/backend/tcop/postgres.c
+--- postgresql-9.1.4.orig/src/backend/tcop/postgres.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/tcop/postgres.c	2012-08-12 19:31:41.487000086 -0400
+@@ -3345,7 +3345,7 @@
+ 				break;
+ 
+ 			case 'k':
+-				SetConfigOption("unix_socket_directory", optarg, ctx, gucsource);
++				SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
+ 				break;
+ 
+ 			case 'l':
+diff -Naur postgresql-9.1.4.orig/src/backend/utils/adt/varlena.c postgresql-9.1.4/src/backend/utils/adt/varlena.c
+--- postgresql-9.1.4.orig/src/backend/utils/adt/varlena.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/utils/adt/varlena.c	2012-08-12 19:31:41.489000154 -0400
+@@ -2387,6 +2387,116 @@
+ }
+ 
+ 
++/*
++ * SplitDirectoriesString --- parse a string containing directory names
++ *
++ * This is similar to SplitIdentifierString, except that the parsing
++ * rules are meant to handle pathnames instead of identifiers: there is
++ * no downcasing, the max length is MAXPGPATH-1, and we apply
++ * canonicalize_path() to each extracted string.  Because of the last,
++ * the returned strings are separately palloc'd rather than being
++ * pointers into rawstring --- but we still scribble on rawstring.
++ *
++ * Inputs:
++ *	rawstring: the input string; must be modifiable!
++ *	separator: the separator punctuation expected between directories
++ *			   (typically ',' or ';').	Whitespace may also appear around
++ *			   directories.
++ * Outputs:
++ *	namelist: filled with a palloc'd list of directory names.
++ *			  Caller should list_free_deep() this even on error return.
++ *
++ * Returns TRUE if okay, FALSE if there is a syntax error in the string.
++ *
++ * Note that an empty string is considered okay here.
++ */
++bool
++SplitDirectoriesString(char *rawstring, char separator,
++					   List **namelist)
++{
++	char	   *nextp = rawstring;
++	bool		done = false;
++
++	*namelist = NIL;
++
++	while (isspace((unsigned char) *nextp))
++		nextp++;				/* skip leading whitespace */
++
++	if (*nextp == '\0')
++		return true;			/* allow empty string */
++
++	/* At the top of the loop, we are at start of a new directory. */
++	do
++	{
++		char	   *curname;
++		char	   *endp;
++
++		if (*nextp == '\"')
++		{
++			/* Quoted name --- collapse quote-quote pairs */
++			curname = nextp + 1;
++			for (;;)
++			{
++				endp = strchr(nextp + 1, '\"');
++				if (endp == NULL)
++					return false;		/* mismatched quotes */
++				if (endp[1] != '\"')
++					break;		/* found end of quoted name */
++				/* Collapse adjacent quotes into one quote, and look again */
++				memmove(endp, endp + 1, strlen(endp));
++				nextp = endp;
++			}
++			/* endp now points at the terminating quote */
++			nextp = endp + 1;
++		}
++		else
++		{
++			/* Unquoted name --- extends to separator or whitespace */
++			curname = nextp;
++			while (*nextp && *nextp != separator &&
++				   !isspace((unsigned char) *nextp))
++				nextp++;
++			endp = nextp;
++			if (curname == nextp)
++				return false;	/* empty unquoted name not allowed */
++		}
++
++		while (isspace((unsigned char) *nextp))
++			nextp++;			/* skip trailing whitespace */
++
++		if (*nextp == separator)
++		{
++			nextp++;
++			while (isspace((unsigned char) *nextp))
++				nextp++;		/* skip leading whitespace for next */
++			/* we expect another name, so done remains false */
++		}
++		else if (*nextp == '\0')
++			done = true;
++		else
++			return false;		/* invalid syntax */
++
++		/* Now safe to overwrite separator with a null */
++		*endp = '\0';
++
++		/* Truncate path if it's overlength */
++		if (strlen(curname) >= MAXPGPATH)
++			curname[MAXPGPATH - 1] = '\0';
++
++		/*
++		 * Finished isolating current name --- add it to list
++		 */
++		curname = pstrdup(curname);
++		canonicalize_path(curname);
++		*namelist = lappend(*namelist, curname);
++
++		/* Loop back if we didn't reach end of string */
++	} while (!done);
++
++	return true;
++}
++
++
+ /*****************************************************************************
+  *	Comparison Functions used for bytea
+  *
+diff -Naur postgresql-9.1.4.orig/src/backend/utils/init/miscinit.c postgresql-9.1.4/src/backend/utils/init/miscinit.c
+--- postgresql-9.1.4.orig/src/backend/utils/init/miscinit.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/utils/init/miscinit.c	2012-08-12 19:31:41.489000154 -0400
+@@ -49,8 +49,8 @@
+ 
+ ProcessingMode Mode = InitProcessing;
+ 
+-/* Note: we rely on this to initialize as zeroes */
+-static char socketLockFile[MAXPGPATH];
++/* List of lock files to be removed at proc exit */
++static List *lock_files = NIL;
+ 
+ 
+ /* ----------------------------------------------------------------
+@@ -648,32 +648,35 @@
+  */
+ 
+ /*
+- * proc_exit callback to remove a lockfile.
++ * proc_exit callback to remove lockfiles.
+  */
+ static void
+-UnlinkLockFile(int status, Datum filename)
++UnlinkLockFiles(int status, Datum arg)
+ {
+-	char	   *fname = (char *) DatumGetPointer(filename);
++	ListCell   *l;
+ 
+-	if (fname != NULL)
++	foreach(l, lock_files)
+ 	{
+-		if (unlink(fname) != 0)
+-		{
+-			/* Should we complain if the unlink fails? */
+-		}
+-		free(fname);
++		char	   *curfile = (char *) lfirst(l);
++
++		unlink(curfile);
++		/* Should we complain if the unlink fails? */
+ 	}
++	/* Since we're about to exit, no need to reclaim storage */
++	lock_files = NIL;
+ }
+ 
+ /*
+  * Create a lockfile.
+  *
+- * filename is the name of the lockfile to create.
++ * filename is the path name of the lockfile to create.
+  * amPostmaster is used to determine how to encode the output PID.
++ * socketDir is the Unix socket directory path to include (possibly empty).
+  * isDDLock and refName are used to determine what error message to produce.
+  */
+ static void
+ CreateLockFile(const char *filename, bool amPostmaster,
++			   const char *socketDir,
+ 			   bool isDDLock, const char *refName)
+ {
+ 	int			fd;
+@@ -899,12 +902,7 @@
+ 			 DataDir,
+ 			 (long) MyStartTime,
+ 			 PostPortNumber,
+-#ifdef HAVE_UNIX_SOCKETS
+-			 (*UnixSocketDir != '\0') ? UnixSocketDir : DEFAULT_PGSOCKET_DIR
+-#else
+-			 ""
+-#endif
+-		);
++			 socketDir);
+ 
+ 	errno = 0;
+ 	if (write(fd, buffer, strlen(buffer)) != strlen(buffer))
+@@ -942,9 +940,14 @@
+ 	}
+ 
+ 	/*
+-	 * Arrange for automatic removal of lockfile at proc_exit.
++	 * Arrange to unlink the lock file(s) at proc_exit.  If this is the
++	 * first one, set up the on_proc_exit function to do it; then add this
++	 * lock file to the list of files to unlink.
+ 	 */
+-	on_proc_exit(UnlinkLockFile, PointerGetDatum(strdup(filename)));
++	if (lock_files == NIL)
++		on_proc_exit(UnlinkLockFiles, 0);
++
++	lock_files = lappend(lock_files, pstrdup(filename));
+ }
+ 
+ /*
+@@ -953,41 +956,50 @@
+  * When this is called, we must have already switched the working
+  * directory to DataDir, so we can just use a relative path.  This
+  * helps ensure that we are locking the directory we should be.
++ *
++ * Note that the socket directory path line is initially written as empty.
++ * postmaster.c will rewrite it upon creating the first Unix socket.
+  */
+ void
+ CreateDataDirLockFile(bool amPostmaster)
+ {
+-	CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, true, DataDir);
++	CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "", true, DataDir);
+ }
+ 
+ /*
+  * Create a lockfile for the specified Unix socket file.
+  */
+ void
+-CreateSocketLockFile(const char *socketfile, bool amPostmaster)
++CreateSocketLockFile(const char *socketfile, bool amPostmaster,
++					 const char *socketDir)
+ {
+ 	char		lockfile[MAXPGPATH];
+ 
+ 	snprintf(lockfile, sizeof(lockfile), "%s.lock", socketfile);
+-	CreateLockFile(lockfile, amPostmaster, false, socketfile);
+-	/* Save name of lockfile for TouchSocketLockFile */
+-	strcpy(socketLockFile, lockfile);
++	CreateLockFile(lockfile, amPostmaster, socketDir, false, socketfile);
+ }
+ 
+ /*
+- * TouchSocketLockFile -- mark socket lock file as recently accessed
++ * TouchSocketLockFiles -- mark socket lock files as recently accessed
+  *
+- * This routine should be called every so often to ensure that the lock file
+- * has a recent mod or access date.  That saves it
++ * This routine should be called every so often to ensure that the socket
++ * lock files have a recent mod or access date.  That saves them
+  * from being removed by overenthusiastic /tmp-directory-cleaner daemons.
+  * (Another reason we should never have put the socket file in /tmp...)
+  */
+ void
+-TouchSocketLockFile(void)
++TouchSocketLockFiles(void)
+ {
+-	/* Do nothing if we did not create a socket... */
+-	if (socketLockFile[0] != '\0')
++	ListCell   *l;
++
++	foreach(l, lock_files)
+ 	{
++		char	   *socketLockFile = (char *) lfirst(l);
++
++		/* No need to touch the data directory lock file, we trust */
++		if (strcmp(socketLockFile, DIRECTORY_LOCK_FILE) == 0)
++			continue;
++
+ 		/*
+ 		 * utime() is POSIX standard, utimes() is a common alternative; if we
+ 		 * have neither, fall back to actually reading the file (which only
+@@ -1019,8 +1031,10 @@
+  * Add (or replace) a line in the data directory lock file.
+  * The given string should not include a trailing newline.
+  *
+- * Caution: this erases all following lines.  In current usage that is OK
+- * because lines are added in order.  We could improve it if needed.
++ * Note: because we don't truncate the file, if we were to rewrite a line
++ * with less data than it had before, there would be garbage after the last
++ * line.  We don't ever actually do that, so not worth adding another kernel
++ * call to cover the possibility.
+  */
+ void
+ AddToDataDirLockFile(int target_line, const char *str)
+@@ -1028,8 +1042,10 @@
+ 	int			fd;
+ 	int			len;
+ 	int			lineno;
+-	char	   *ptr;
+-	char		buffer[BLCKSZ];
++	char	   *srcptr;
++	char	   *destptr;
++	char		srcbuffer[BLCKSZ];
++	char		destbuffer[BLCKSZ];
+ 
+ 	fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);
+ 	if (fd < 0)
+@@ -1040,7 +1056,7 @@
+ 						DIRECTORY_LOCK_FILE)));
+ 		return;
+ 	}
+-	len = read(fd, buffer, sizeof(buffer) - 1);
++	len = read(fd, srcbuffer, sizeof(srcbuffer) - 1);
+ 	if (len < 0)
+ 	{
+ 		ereport(LOG,
+@@ -1050,36 +1066,50 @@
+ 		close(fd);
+ 		return;
+ 	}
+-	buffer[len] = '\0';
++	srcbuffer[len] = '\0';
+ 
+ 	/*
+-	 * Skip over lines we are not supposed to rewrite.
++	 * Advance over lines we are not supposed to rewrite, then copy them
++	 * to destbuffer.
+ 	 */
+-	ptr = buffer;
++	srcptr = srcbuffer;
+ 	for (lineno = 1; lineno < target_line; lineno++)
+ 	{
+-		if ((ptr = strchr(ptr, '\n')) == NULL)
++		if ((srcptr = strchr(srcptr, '\n')) == NULL)
+ 		{
+ 			elog(LOG, "bogus data in \"%s\"", DIRECTORY_LOCK_FILE);
+ 			close(fd);
+ 			return;
+ 		}
+-		ptr++;
++		srcptr++;
+ 	}
++	memcpy(destbuffer, srcbuffer, srcptr - srcbuffer);
++	destptr = destbuffer + (srcptr - srcbuffer);
+ 
+ 	/*
+ 	 * Write or rewrite the target line.
+ 	 */
+-	snprintf(ptr, buffer + sizeof(buffer) - ptr, "%s\n", str);
++	snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s\n", str);
++	destptr += strlen(destptr);
++
++	/*
++	 * If there are more lines in the old file, append them to destbuffer.
++	 */
++	if ((srcptr = strchr(srcptr, '\n')) != NULL)
++	{
++		srcptr++;
++		snprintf(destptr, destbuffer + sizeof(destbuffer) - destptr, "%s",
++				 srcptr);
++	}
+ 
+ 	/*
+ 	 * And rewrite the data.  Since we write in a single kernel call, this
+ 	 * update should appear atomic to onlookers.
+ 	 */
+-	len = strlen(buffer);
++	len = strlen(destbuffer);
+ 	errno = 0;
+ 	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||
+-		(int) write(fd, buffer, len) != len)
++		(int) write(fd, destbuffer, len) != len)
+ 	{
+ 		/* if write didn't set errno, assume problem is no disk space */
+ 		if (errno == 0)
+diff -Naur postgresql-9.1.4.orig/src/backend/utils/misc/guc.c postgresql-9.1.4/src/backend/utils/misc/guc.c
+--- postgresql-9.1.4.orig/src/backend/utils/misc/guc.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/utils/misc/guc.c	2012-08-12 19:31:41.491000208 -0400
+@@ -2867,14 +2867,18 @@
+ 	},
+ 
+ 	{
+-		{"unix_socket_directory", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
+-			gettext_noop("Sets the directory where the Unix-domain socket will be created."),
++		{"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
++			gettext_noop("Sets the directories where Unix-domain sockets will be created."),
+ 			NULL,
+ 			GUC_SUPERUSER_ONLY
+ 		},
+-		&UnixSocketDir,
++		&Unix_socket_directories,
++#ifdef HAVE_UNIX_SOCKETS
++		DEFAULT_PGSOCKET_DIR,
++#else
+ 		"",
+-		check_canonical_path, NULL, NULL
++#endif
++		NULL, NULL, NULL
+ 	},
+ 
+ 	{
+diff -Naur postgresql-9.1.4.orig/src/backend/utils/misc/postgresql.conf.sample postgresql-9.1.4/src/backend/utils/misc/postgresql.conf.sample
+--- postgresql-9.1.4.orig/src/backend/utils/misc/postgresql.conf.sample	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/backend/utils/misc/postgresql.conf.sample	2012-08-12 19:31:41.492000232 -0400
+@@ -65,7 +65,8 @@
+ # Note:  Increasing max_connections costs ~400 bytes of shared memory per
+ # connection slot, plus lock space (see max_locks_per_transaction).
+ #superuser_reserved_connections = 3	# (change requires restart)
+-#unix_socket_directory = ''		# (change requires restart)
++#unix_socket_directories = '/tmp'	# comma-separated list of directories
++					# (change requires restart)
+ #unix_socket_group = ''			# (change requires restart)
+ #unix_socket_permissions = 0777		# begin with 0 to use octal notation
+ 					# (change requires restart)
+diff -Naur postgresql-9.1.4.orig/src/bin/initdb/initdb.c postgresql-9.1.4/src/bin/initdb/initdb.c
+--- postgresql-9.1.4.orig/src/bin/initdb/initdb.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/bin/initdb/initdb.c	2012-08-12 19:31:41.493000252 -0400
+@@ -947,7 +947,7 @@
+ setup_config(void)
+ {
+ 	char	  **conflines;
+-	char		repltok[100];
++	char		repltok[MAXPGPATH];
+ 	char		path[MAXPGPATH];
+ 
+ 	fputs(_("creating configuration files ... "), stdout);
+@@ -968,6 +968,15 @@
+ 				 n_buffers * (BLCKSZ / 1024));
+ 	conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok);
+ 
++#ifdef HAVE_UNIX_SOCKETS
++	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
++			 DEFAULT_PGSOCKET_DIR);
++#else
++	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
++#endif
++	conflines = replace_token(conflines, "#unix_socket_directories = '/tmp'",
++							  repltok);
++
+ #if DEF_PGPORT != 5432
+ 	snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT);
+ 	conflines = replace_token(conflines, "#port = 5432", repltok);
+diff -Naur postgresql-9.1.4.orig/src/bin/pg_ctl/pg_ctl.c postgresql-9.1.4/src/bin/pg_ctl/pg_ctl.c
+--- postgresql-9.1.4.orig/src/bin/pg_ctl/pg_ctl.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/bin/pg_ctl/pg_ctl.c	2012-08-12 19:31:41.494000277 -0400
+@@ -519,7 +519,7 @@
+ 						hostaddr = optlines[LOCK_FILE_LINE_LISTEN_ADDR - 1];
+ 
+ 						/*
+-						 * While unix_socket_directory can accept relative
++						 * While unix_socket_directories can accept relative
+ 						 * directories, libpq's host parameter must have a
+ 						 * leading slash to indicate a socket directory.  So,
+ 						 * ignore sockdir if it's relative, and try to use TCP
+diff -Naur postgresql-9.1.4.orig/src/include/libpq/libpq.h postgresql-9.1.4/src/include/libpq/libpq.h
+--- postgresql-9.1.4.orig/src/include/libpq/libpq.h	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/include/libpq/libpq.h	2012-08-12 19:31:41.494000277 -0400
+@@ -44,12 +44,12 @@
+ /*
+  * prototypes for functions in pqcomm.c
+  */
+-extern int StreamServerPort(int family, char *hostName,
+-	unsigned short portNumber, char *unixSocketName, pgsocket ListenSocket[],
+-				 int MaxListen);
++extern int	StreamServerPort(int family, char *hostName,
++				 unsigned short portNumber, char *unixSocketDir,
++				 pgsocket ListenSocket[], int MaxListen);
+ extern int	StreamConnection(pgsocket server_fd, Port *port);
+ extern void StreamClose(pgsocket sock);
+-extern void TouchSocketFile(void);
++extern void TouchSocketFiles(void);
+ extern void pq_init(void);
+ extern void pq_comm_reset(void);
+ extern int	pq_getbytes(char *s, size_t len);
+diff -Naur postgresql-9.1.4.orig/src/include/miscadmin.h postgresql-9.1.4/src/include/miscadmin.h
+--- postgresql-9.1.4.orig/src/include/miscadmin.h	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/include/miscadmin.h	2012-08-12 19:31:41.495000302 -0400
+@@ -370,7 +370,7 @@
+  *		2	data directory path
+  *		3	postmaster start timestamp (time_t representation)
+  *		4	port number
+- *		5	socket directory path (empty on Windows)
++ *		5	first Unix socket directory path (empty if none)
+  *		6	first listen_address (IP address or "*"; empty if no TCP port)
+  *		7	shared memory key (not present on Windows)
+  *
+@@ -388,8 +388,9 @@
+ #define LOCK_FILE_LINE_SHMEM_KEY	7
+ 
+ extern void CreateDataDirLockFile(bool amPostmaster);
+-extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster);
+-extern void TouchSocketLockFile(void);
++extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
++					 const char *socketDir);
++extern void TouchSocketLockFiles(void);
+ extern void AddToDataDirLockFile(int target_line, const char *str);
+ extern void ValidatePgVersion(const char *path);
+ extern void process_shared_preload_libraries(void);
+diff -Naur postgresql-9.1.4.orig/src/include/postmaster/postmaster.h postgresql-9.1.4/src/include/postmaster/postmaster.h
+--- postgresql-9.1.4.orig/src/include/postmaster/postmaster.h	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/include/postmaster/postmaster.h	2012-08-12 19:31:41.495000302 -0400
+@@ -20,7 +20,7 @@
+ extern int	PostPortNumber;
+ extern int	Unix_socket_permissions;
+ extern char *Unix_socket_group;
+-extern char *UnixSocketDir;
++extern char *Unix_socket_directories;
+ extern char *ListenAddresses;
+ extern bool ClientAuthInProgress;
+ extern int	PreAuthDelay;
+diff -Naur postgresql-9.1.4.orig/src/include/utils/builtins.h postgresql-9.1.4/src/include/utils/builtins.h
+--- postgresql-9.1.4.orig/src/include/utils/builtins.h	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/include/utils/builtins.h	2012-08-12 19:31:41.496000323 -0400
+@@ -726,6 +726,8 @@
+ extern List *textToQualifiedNameList(text *textval);
+ extern bool SplitIdentifierString(char *rawstring, char separator,
+ 					  List **namelist);
++extern bool SplitDirectoriesString(char *rawstring, char separator,
++					   List **namelist);
+ extern Datum replace_text(PG_FUNCTION_ARGS);
+ extern text *replace_text_regexp(text *src_text, void *regexp,
+ 					text *replace_text, bool glob);
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/html-stamp postgresql-9.1.4/doc/src/sgml/html-stamp
+--- postgresql-9.1.4.orig/doc/src/sgml/html-stamp	2012-05-31 19:23:47.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/html-stamp	2012-08-12 19:50:30.401879619 -0400
+@@ -0,0 +1 @@
++hack
+diff -Naur postgresql-9.1.4.orig/doc/src/sgml/man-stamp postgresql-9.1.4/doc/src/sgml/man-stamp
+--- postgresql-9.1.4.orig/doc/src/sgml/man-stamp	2012-05-31 19:24:44.000000000 -0400
++++ postgresql-9.1.4/doc/src/sgml/man-stamp	2012-08-12 19:50:36.017933728 -0400
+@@ -0,0 +1 @@
++hack
diff --git a/postgresql-var-run-socket.patch b/postgresql-var-run-socket.patch
new file mode 100644
index 0000000..5bad691
--- /dev/null
+++ b/postgresql-var-run-socket.patch
@@ -0,0 +1,94 @@
+Change the built-in default socket directory to be /var/run/postgresql.
+For backwards compatibility with (probably non-libpq-based) clients that
+might still expect to find the socket in /tmp, also create a socket in
+/tmp.  This is to resolve communication problems with clients operating
+under systemd's PrivateTmp environment, which won't be using the same
+global /tmp directory as the server; see bug #825448.
+
+Note that we apply the socket directory change at the level of the
+hard-wired defaults in the C code, not by just twiddling the setting in
+postgresql.conf.sample; this is so that the change will take effect on
+server package update, without requiring any existing postgresql.conf
+to be updated.  (Of course, a user who dislikes this behavior can still
+override it via postgresql.conf.)
+
+This patch must be applied after postgresql-multi-sockets.patch, at
+least until 9.3 when that will be part of the upstream package.
+
+
+diff -Naur postgresql-9.1.4.sockets/contrib/pg_upgrade/server.c postgresql-9.1.4/contrib/pg_upgrade/server.c
+--- postgresql-9.1.4.sockets/contrib/pg_upgrade/server.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/contrib/pg_upgrade/server.c	2012-08-12 22:43:10.388873678 -0400
+@@ -179,11 +179,14 @@
+ 	 */
+ 	snprintf(cmd, sizeof(cmd),
+ 			 SYSTEMQUOTE "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" "
+-			 "-o \"-p %d %s\" start >> \"%s\" 2>&1" SYSTEMQUOTE,
++			 "-o \"-p %d %s %s\" start >> \"%s\" 2>&1" SYSTEMQUOTE,
+ 			 cluster->bindir, output_filename, cluster->pgdata, cluster->port,
+ 			 (cluster->controldata.cat_ver >=
+ 			  BINARY_UPGRADE_SERVER_FLAG_CAT_VER) ? "-b" :
+ 			 "-c autovacuum=off -c autovacuum_freeze_max_age=2000000000",
++			 /* assume 9.1 builds will have newer socket directory */
++			 (GET_MAJOR_VERSION(cluster->major_version) < 901) ?
++			 "-c unix_socket_directory=/var/run/postgresql" : "",
+ 			 output_filename);
+ 
+ 	/*
+diff -Naur postgresql-9.1.4.sockets/src/backend/utils/misc/guc.c postgresql-9.1.4/src/backend/utils/misc/guc.c
+--- postgresql-9.1.4.sockets/src/backend/utils/misc/guc.c	2012-08-12 20:35:22.559682963 -0400
++++ postgresql-9.1.4/src/backend/utils/misc/guc.c	2012-08-12 20:35:55.071983609 -0400
+@@ -2874,7 +2874,7 @@
+ 		},
+ 		&Unix_socket_directories,
+ #ifdef HAVE_UNIX_SOCKETS
+-		DEFAULT_PGSOCKET_DIR,
++		DEFAULT_PGSOCKET_DIR ", /tmp",
+ #else
+ 		"",
+ #endif
+diff -Naur postgresql-9.1.4.sockets/src/bin/initdb/initdb.c postgresql-9.1.4/src/bin/initdb/initdb.c
+--- postgresql-9.1.4.sockets/src/bin/initdb/initdb.c	2012-08-12 20:35:22.561682693 -0400
++++ postgresql-9.1.4/src/bin/initdb/initdb.c	2012-08-12 20:35:55.073983799 -0400
+@@ -970,7 +970,7 @@
+ 
+ #ifdef HAVE_UNIX_SOCKETS
+ 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = '%s'",
+-			 DEFAULT_PGSOCKET_DIR);
++			 DEFAULT_PGSOCKET_DIR ", /tmp");
+ #else
+ 	snprintf(repltok, sizeof(repltok), "#unix_socket_directories = ''");
+ #endif
+diff -Naur postgresql-9.1.4.sockets/src/include/pg_config_manual.h postgresql-9.1.4/src/include/pg_config_manual.h
+--- postgresql-9.1.4.sockets/src/include/pg_config_manual.h	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/include/pg_config_manual.h	2012-08-12 20:35:55.073983799 -0400
+@@ -141,7 +141,7 @@
+  * here's where to twiddle it.  You can also override this at runtime
+  * with the postmaster's -k switch.
+  */
+-#define DEFAULT_PGSOCKET_DIR  "/tmp"
++#define DEFAULT_PGSOCKET_DIR  "/var/run/postgresql"
+ 
+ /*
+  * The random() function is expected to yield values between 0 and
+diff -Naur postgresql-9.1.4.sockets/src/test/regress/pg_regress.c postgresql-9.1.4/src/test/regress/pg_regress.c
+--- postgresql-9.1.4.sockets/src/test/regress/pg_regress.c	2012-05-31 19:07:09.000000000 -0400
++++ postgresql-9.1.4/src/test/regress/pg_regress.c	2012-08-12 20:38:43.933609334 -0400
+@@ -781,7 +781,7 @@
+ 		if (hostname != NULL)
+ 			doputenv("PGHOST", hostname);
+ 		else
+-			unsetenv("PGHOST");
++			doputenv("PGHOST", "/tmp");
+ 		unsetenv("PGHOSTADDR");
+ 		if (port != -1)
+ 		{
+@@ -2240,7 +2240,7 @@
+ 		 */
+ 		header(_("starting postmaster"));
+ 		snprintf(buf, sizeof(buf),
+-				 SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s -c \"listen_addresses=%s\" > \"%s/log/postmaster.log\" 2>&1" SYSTEMQUOTE,
++				 SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s -c \"listen_addresses=%s\" -c \"unix_socket_directories=/tmp\" > \"%s/log/postmaster.log\" 2>&1" SYSTEMQUOTE,
+ 				 bindir, temp_install,
+ 				 debug ? " -d 5" : "",
+ 				 hostname ? hostname : "",
diff --git a/postgresql.spec b/postgresql.spec
index 352cf65..a5e1ce3 100644
--- a/postgresql.spec
+++ b/postgresql.spec
@@ -53,7 +53,7 @@ Summary: PostgreSQL client programs
 Name: postgresql
 %global majorversion 9.1
 Version: 9.1.4
-Release: 4%{?dist}
+Release: 5%{?dist}
 
 # The PostgreSQL license is very similar to other MIT licenses, but the OSI
 # recognizes it as an independent license, so we do as well.
@@ -85,6 +85,7 @@ Source9: postgresql-setup
 Source10: postgresql.service
 Source11: initdb.sh
 Source12: upgrade.sh
+Source13: postgresql.tmpfiles.d
 Source14: postgresql.pam
 Source15: postgresql-bashprofile
 
@@ -93,6 +94,9 @@ Patch1: rpm-pgsql.patch
 Patch2: postgresql-logging.patch
 Patch3: postgresql-perl-rpath.patch
 Patch4: postgresql-oom_score_adj.patch
+Patch5: postgresql-multi-sockets.patch
+Patch6: postgresql-var-run-socket.patch
+Patch7: postgresql-config-comment.patch
 
 BuildRequires: perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk
 BuildRequires: perl(ExtUtils::Embed), perl-devel
@@ -146,8 +150,6 @@ BuildRequires: libselinux-devel
 # main package requires -libs subpackage
 Requires: %{name}-libs%{?_isa} = %{version}-%{release}
 
-Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
-
 %description
 PostgreSQL is an advanced Object-Relational database management system (DBMS).
 The base postgresql package contains the client programs that you'll need to
@@ -182,7 +184,9 @@ Requires(pre): /usr/sbin/useradd
 # for /sbin/ldconfig
 Requires(post): glibc
 Requires(postun): glibc
-# pre/post stuff needs systemd too
+# We require this to be present for %%{_prefix}/lib/tmpfiles.d
+Requires: systemd-units
+# Make sure it's there when scriptlets run, too
 Requires(post): systemd-units
 Requires(preun): systemd-units
 Requires(postun): systemd-units
@@ -305,6 +309,9 @@ benchmarks.
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
 
 # We used to run autoconf here, but there's no longer any real need to,
 # since Postgres ships with a reasonably modern configure script.
@@ -435,7 +442,6 @@ rm -f src/tutorial/GNUmakefile
 %endif
 
 %install
-rm -rf $RPM_BUILD_ROOT
 
 make DESTDIR=$RPM_BUILD_ROOT install-world
 
@@ -486,6 +492,13 @@ install -d $RPM_BUILD_ROOT/etc/pam.d
 install -m 644 %{SOURCE14} $RPM_BUILD_ROOT/etc/pam.d/postgresql
 %endif
 
+# Create the directory for sockets.
+install -d -m 755 $RPM_BUILD_ROOT/var/run/postgresql
+
+# ... and make a tmpfiles script to recreate it at reboot.
+mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d
+install -m 0644 %{SOURCE13} $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/postgresql.conf
+
 # PGDATA needs removal of group and world permissions due to pg_pwd hole.
 install -d -m 700 $RPM_BUILD_ROOT/var/lib/pgsql/data
 
@@ -678,13 +691,9 @@ fi
 %postun -p /sbin/ldconfig pltcl
 %endif
 
-%clean
-rm -rf $RPM_BUILD_ROOT
-
 # FILES section.
 
 %files -f main.lst
-%defattr(-,root,root)
 %doc doc/KNOWN_BUGS doc/MISSING_FEATURES doc/TODO
 %doc COPYRIGHT README HISTORY doc/bug.template
 %doc README.rpm-dist
@@ -721,12 +730,10 @@ rm -rf $RPM_BUILD_ROOT
 %dir %{_libdir}/pgsql
 
 %files docs
-%defattr(-,root,root)
 %doc *-US.pdf
 %{_libdir}/pgsql/tutorial/
 
 %files contrib
-%defattr(-,root,root)
 %{_datadir}/pgsql/extension/adminpack*
 %{_datadir}/pgsql/extension/autoinc*
 %{_datadir}/pgsql/extension/btree_gin*
@@ -828,7 +835,6 @@ rm -rf $RPM_BUILD_ROOT
 %doc contrib/spi/*.example
 
 %files libs -f libs.lst
-%defattr(-,root,root)
 %doc COPYRIGHT
 %{_libdir}/libpq.so.*
 %{_libdir}/libecpg.so.*
@@ -836,7 +842,6 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/libecpg_compat.so.*
 
 %files server -f server.lst
-%defattr(-,root,root)
 %{_unitdir}/postgresql.service
 %dir /usr/libexec/initscripts/legacy-actions/postgresql
 /usr/libexec/initscripts/legacy-actions/postgresql/*
@@ -872,6 +877,8 @@ rm -rf $RPM_BUILD_ROOT
 %dir %{_datadir}/pgsql/contrib
 %dir %{_datadir}/pgsql/extension
 %{_datadir}/pgsql/extension/plpgsql*
+%{_prefix}/lib/tmpfiles.d/postgresql.conf
+%attr(755,postgres,postgres) %dir /var/run/postgresql
 %attr(700,postgres,postgres) %dir /var/lib/pgsql
 %attr(700,postgres,postgres) %dir /var/lib/pgsql/data
 %attr(700,postgres,postgres) %dir /var/lib/pgsql/backups
@@ -885,7 +892,6 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/pgsql/sql_features.txt
 
 %files devel -f devel.lst
-%defattr(-,root,root)
 /usr/include/*
 %{_bindir}/ecpg
 %{_libdir}/libpq.so
@@ -898,7 +904,6 @@ rm -rf $RPM_BUILD_ROOT
 
 %if %upgrade
 %files upgrade
-%defattr(-,root,root)
 %{_bindir}/pg_upgrade
 %{_libdir}/pgsql/pg_upgrade_support.so
 %{_libdir}/pgsql/postgresql-%{prevmajorversion}
@@ -906,14 +911,12 @@ rm -rf $RPM_BUILD_ROOT
 
 %if %plperl
 %files plperl -f plperl.lst
-%defattr(-,root,root)
 %{_datadir}/pgsql/extension/plperl*
 %{_libdir}/pgsql/plperl.so
 %endif
 
 %if %pltcl
 %files pltcl -f pltcl.lst
-%defattr(-,root,root)
 %{_datadir}/pgsql/extension/pltcl*
 %{_libdir}/pgsql/pltcl.so
 %{_bindir}/pltcl_delmod
@@ -924,7 +927,6 @@ rm -rf $RPM_BUILD_ROOT
 
 %if %plpython
 %files plpython -f plpython.lst
-%defattr(-,root,root)
 %{_datadir}/pgsql/extension/plpython*
 %{_libdir}/pgsql/plpython2.so
 %endif
@@ -937,6 +939,15 @@ rm -rf $RPM_BUILD_ROOT
 %endif
 
 %changelog
+* Mon Aug 13 2012 Tom Lane <tgl at redhat.com> 9.1.4-5
+- Back-port upstream support for postmaster listening on multiple Unix sockets
+- Configure postmaster to create sockets in both /var/run/postgresql and /tmp;
+  the former is now the default place for libpq to contact the postmaster.
+Resolves: #825448
+- Annotate postgresql.config about not setting port number there
+- Minor specfile cleanup per suggestions from Tom Callaway
+Related: #845110
+
 * Sat Jul 21 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 9.1.4-4
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
 
diff --git a/postgresql.tmpfiles.d b/postgresql.tmpfiles.d
new file mode 100644
index 0000000..d8d960d
--- /dev/null
+++ b/postgresql.tmpfiles.d
@@ -0,0 +1 @@
+d /var/run/postgresql 0755 postgres postgres -
diff --git a/sources b/sources
index 95818fc..f80623d 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
 a8035688dba988b782725ac1aec60186  postgresql-9.1.4.tar.bz2
-f59cc1a3dbe089d9cc496be119161b3b  postgresql-9.1.4-US.pdf
+16153e524a263f7c1e66f5bbc71b8976  postgresql-9.1.4-US.pdf
 0e830b0f6538e04b788c3208060256ef  postgresql-9.0.8.tar.bz2


More information about the scm-commits mailing list