1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Diagnose incompatible OpenLDAP versions during build and test.

With OpenLDAP versions 2.4.24 through 2.4.31, inclusive, PostgreSQL
backends can crash at exit.  Raise a warning during "configure" based on
the compile-time OpenLDAP version number, and test the crash scenario in
the dblink test suite.  Back-patch to 9.0 (all supported versions).
This commit is contained in:
Noah Misch
2014-07-22 11:01:03 -04:00
parent 6e5a39c9e6
commit 4c6d0abde9
11 changed files with 236 additions and 1 deletions

View File

@ -7,7 +7,9 @@ SHLIB_LINK = $(libpq)
DATA_built = dblink.sql
DATA = uninstall_dblink.sql
REGRESS = dblink
REGRESS = paths dblink
REGRESS_OPTS = --dbname=$(CONTRIB_TESTDB) --dlpath=$(top_builddir)/src/test/regress
EXTRA_CLEAN = sql/paths.sql expected/paths.out
# the db name is hard-coded in the tests

1
contrib/dblink/expected/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/paths.out

View File

@ -115,6 +115,29 @@ SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
WHERE t.a > 7;
ERROR: connection not available
-- The first-level connection's backend will crash on exit given OpenLDAP
-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
-- process terminates and the postmaster responds. If process termination
-- entails writing a core dump, that can take awhile. Wait for the process to
-- vanish. At that point, the postmaster has called waitpid() on the crashed
-- process, and it will accept no new connections until it has reinitialized
-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
-- after the backend updates shared memory to reflect its impending exit.)
DO $pl$
BEGIN
PERFORM wait_pid(crash_pid)
FROM dblink('dbname=contrib_regression', $$
SELECT pg_backend_pid() FROM dblink(
'service=test_ldap dbname=contrib_regression',
-- This string concatenation is a hack to shoehorn a
-- set_pgservicefile call into the SQL statement.
'SELECT 1' || set_pgservicefile('pg_service.conf')
) t(c int)
$$) AS t(crash_pid int);
EXCEPTION WHEN sqlclient_unable_to_establish_sqlconnection THEN
-- Expect "syntax error in service file" in a non-LDAP build.
END
$pl$;
-- create a persistent connection
SELECT dblink_connect('dbname=contrib_regression');
dblink_connect

View File

@ -0,0 +1,14 @@
-- Initialization that requires path substitution.
CREATE FUNCTION putenv(text)
RETURNS void
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
LANGUAGE C STRICT;
CREATE FUNCTION wait_pid(int)
RETURNS void
AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT;
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;

View File

@ -0,0 +1,11 @@
-- Initialization that requires path substitution.
CREATE FUNCTION putenv(text)
RETURNS void
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
LANGUAGE C STRICT;
CREATE FUNCTION wait_pid(int)
RETURNS void
AS '@libdir@/regress@DLSUFFIX@'
LANGUAGE C STRICT;
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;

View File

@ -0,0 +1,7 @@
# pg_service.conf for minimally exercising libpq use of LDAP.
# Having failed to reach an LDAP server, libpq essentially ignores the
# "service=test_ldap" in its connection string. Contact the "discard"
# service; the test works whether or not it answers.
[test_ldap]
ldap://127.0.0.1:9/base?attribute?one?filter

1
contrib/dblink/sql/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/paths.sql

View File

@ -78,6 +78,30 @@ SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
WHERE t.a > 7;
-- The first-level connection's backend will crash on exit given OpenLDAP
-- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
-- process terminates and the postmaster responds. If process termination
-- entails writing a core dump, that can take awhile. Wait for the process to
-- vanish. At that point, the postmaster has called waitpid() on the crashed
-- process, and it will accept no new connections until it has reinitialized
-- the cluster. (We can't exploit pg_stat_activity, because the crash happens
-- after the backend updates shared memory to reflect its impending exit.)
DO $pl$
BEGIN
PERFORM wait_pid(crash_pid)
FROM dblink('dbname=contrib_regression', $$
SELECT pg_backend_pid() FROM dblink(
'service=test_ldap dbname=contrib_regression',
-- This string concatenation is a hack to shoehorn a
-- set_pgservicefile call into the SQL statement.
'SELECT 1' || set_pgservicefile('pg_service.conf')
) t(c int)
$$) AS t(crash_pid int);
EXCEPTION WHEN sqlclient_unable_to_establish_sqlconnection THEN
-- Expect "syntax error in service file" in a non-LDAP build.
END
$pl$;
-- create a persistent connection
SELECT dblink_connect('dbname=contrib_regression');