From b18366c18c29ef3f7dde09e9cddc5c3f5760d12c Mon Sep 17 00:00:00 2001 From: Adam Guo Date: Fri, 12 Jan 2024 19:05:36 +0000 Subject: [PATCH] Let Postgres start if clientauth hits an error Currently we block Postgres from starting if clientauth cannot initialize its background workers. This causes more downtime and headache than necessary. Instead, use a flag to track whether clientauth hit an error initializing and effectively disable the feature if so, emitting warnings to the database log. --- src/clientauth.c | 16 ++++++++++++++-- test/t/004_pg_tle_clientauth.pl | 16 ++++++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/clientauth.c b/src/clientauth.c index d3ef945..8d89acd 100644 --- a/src/clientauth.c +++ b/src/clientauth.c @@ -140,6 +140,7 @@ static char *clientauth_databases_to_skip = ""; /* Global flags */ static bool clientauth_reload_config = false; +static bool clientauth_init_error = false; /* * Fixed-length subset of Port, passed to user function. A corresponding SQL @@ -342,7 +343,7 @@ clientauth_init(void) /* * Check the backgroud worker registered list. If any clientauth workers - * failed to register, then throw an error. + * failed to register, emit a warning and flip the init error flag. */ slist_foreach(siter, &BackgroundWorkerList) { @@ -354,9 +355,12 @@ clientauth_init(void) } if (num_registered_workers < clientauth_num_parallel_workers) - ereport(ERROR, + { + clientauth_init_error = true; + ereport(WARNING, errmsg("\"%s.clientauth\" feature was not able to create background workers", PG_TLE_NSPNAME), errhint("Consider increasing max_worker_processes or decreasing pgtle.clientauth_num_parallel_workers.")); + } } void @@ -662,6 +666,14 @@ clientauth_hook(Port *port, int status) /* Skip if this database is on the skip list */ if (check_string_in_guc_list(port->database_name, clientauth_databases_to_skip, "pgtle.clientauth_databases_to_skip")) return; + /* Emit a warning and skip if clientauth failed to init */ + if (clientauth_init_error) + { + ereport(WARNING, + errmsg("\"%s.clientauth\" feature encountered an error and failed to start", PG_TLE_NSPNAME), + errhint("Check the database logs for \"%s.clientauth\" errors.", PG_TLE_NSPNAME)); + return; + } /* * If the queue entry is not available, wait until another client using it diff --git a/test/t/004_pg_tle_clientauth.pl b/test/t/004_pg_tle_clientauth.pl index 1f2c434..c45f6fb 100644 --- a/test/t/004_pg_tle_clientauth.pl +++ b/test/t/004_pg_tle_clientauth.pl @@ -25,7 +25,7 @@ ### 11. Users cannot log in when pgtle.enable_clientauth = 'require' and no functions are registered to clientauth ### 12. Users cannot log in when pgtle.enable_clientauth = 'require' and pg_tle is not installed on pgtle.clientauth_database_name ### 13. Rejects connections when no schema qualified function is found -### 14. Database does not come up if clientauth workers fail to start +### 14. clientauth does not trigger if clientauth workers fail to start ### 15. Malformed strings cannot be used for SQL injection use strict; @@ -233,17 +233,21 @@ $node->command_ok( ['psql', '-c', 'select;'], "can still connect if database is in pgtle.clientauth_databases_to_skip"); -$node->psql('postgres', qq[TRUNCATE pgtle.feature_info], on_error_die => 1); -### 14. Database does not come up if clientauth workers fail to start +### 14. clientauth does not trigger if clientauth workers fail to start $node->append_conf('postgresql.conf', qq(pgtle.clientauth_num_parallel_workers = 64)); $node->append_conf('postgresql.conf', qq(max_worker_processes = 63)); -$node->command_fails( - [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ], - "postmaster does not start up if clientauth workers fail to start"); +$node->restart; +$node->psql('not_excluded', 'select', on_error_die => 1); +# after fixing the parameter and restarting, clientauth should work again $node->append_conf('postgresql.conf', qq(pgtle.clientauth_num_parallel_workers = 60)); $node->append_conf('postgresql.conf', qq(max_worker_processes = 63)); $node->restart; +$psql_err = ''; +$node->psql('not_excluded', 'select', stderr => \$psql_err); +like($psql_err, qr/FATAL: table, schema, and proname must be present in "pgtle.feature_info"/, + "clientauth rejects connections when no schema qualified function is found"); +$node->psql('postgres', qq[TRUNCATE pgtle.feature_info], on_error_die => 1); ### 15. Malformed strings cannot be used for SQL injection $node->psql('postgres', q[