v2-0001-connection_hooks.patch
text/plain
Filename: v2-0001-connection_hooks.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v2-0001
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 11 | 1 |
| src/backend/utils/init/postinit.c | 12 | 0 |
| src/include/fmgr.h | 18 | 0 |
| src/tools/pgindent/typedefs.list | 1 | 0 |
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index d7257e4056..e459c1172f 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -567,6 +567,8 @@ int postmaster_alive_fds[2] = {-1, -1};
HANDLE PostmasterHandle;
#endif
+FailedConnection_hook_type FailedConnection_hook = NULL;
+
/*
* Postmaster main entry point
*/
@@ -4461,8 +4463,11 @@ BackendInitialize(Port *port)
* Stop here if it was bad or a cancel packet. ProcessStartupPacket
* already did any appropriate error reporting.
*/
- if (status != STATUS_OK)
+ if (status != STATUS_OK) {
+ if (FailedConnection_hook)
+ (*FailedConnection_hook) (FCET_BSP, port);
proc_exit(0);
+ }
/*
* Now that we have the user and database name, we can set the process
@@ -5322,6 +5327,11 @@ dummy_handler(SIGNAL_ARGS)
static void
StartupPacketTimeoutHandler(void)
{
+ if (FailedConnection_hook)
+ (*FailedConnection_hook) (FCET_SPT, MyProcPort);
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("timeout while processing startup packet")));
_exit(1);
}
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 6b9082604f..a064966f67 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -360,10 +360,14 @@ CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connect
if (!am_superuser &&
pg_database_aclcheck(MyDatabaseId, GetUserId(),
ACL_CONNECT) != ACLCHECK_OK)
+ {
+ if (FailedConnection_hook)
+ (*FailedConnection_hook) (FCET_BDP, MyProcPort);
ereport(FATAL,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied for database \"%s\"", name),
errdetail("User does not have CONNECT privilege.")));
+ }
/*
* Check connection limit for this database.
@@ -918,9 +922,13 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
tuple = GetDatabaseTuple(in_dbname);
if (!HeapTupleIsValid(tuple))
+ {
+ if (FailedConnection_hook)
+ (*FailedConnection_hook) (FCET_BDN, MyProcPort);
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", in_dbname)));
+ }
dbform = (Form_pg_database) GETSTRUCT(tuple);
MyDatabaseId = dbform->oid;
MyDatabaseTableSpace = dbform->dattablespace;
@@ -935,9 +943,13 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
tuple = GetDatabaseTupleByOid(dboid);
if (!HeapTupleIsValid(tuple))
+ {
+ if (FailedConnection_hook)
+ (*FailedConnection_hook) (FCET_BDO, MyProcPort);
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database %u does not exist", dboid)));
+ }
dbform = (Form_pg_database) GETSTRUCT(tuple);
MyDatabaseId = dbform->oid;
MyDatabaseTableSpace = dbform->dattablespace;
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 5314b73705..5425e778bf 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -778,4 +778,22 @@ extern PGDLLIMPORT fmgr_hook_type fmgr_hook;
#define FmgrHookIsNeeded(fn_oid) \
(!needs_fmgr_hook ? false : (*needs_fmgr_hook)(fn_oid))
+
+/*
+ * The failed connection events to be used in the FailedConnection_hook.
+ */
+typedef enum FailedConnectionEventType
+{
+ FCET_SPT, /* startup packet timeout */
+ FCET_BSP, /* bad startup packet */
+ FCET_BDN, /* bad database name */
+ FCET_BDO, /* bad database Oid */
+ FCET_BDP /* bad database permission */
+} FailedConnectionEventType;
+
+/* kluge to avoid including libpq/libpq-be.h here */
+struct Port;
+typedef void (*FailedConnection_hook_type) (FailedConnectionEventType event, const struct Port *port);
+extern PGDLLIMPORT FailedConnection_hook_type FailedConnection_hook;
+
#endif /* FMGR_H */
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 4fb746930a..4fadafbddb 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -717,6 +717,7 @@ FPI
FSMAddress
FSMPage
FSMPageData
+FailedConnection_hook_type
FakeRelCacheEntry
FakeRelCacheEntryData
FastPathStrongRelationLockData