aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2022-08-24 12:57:13 +0900
committerMichael Paquier <michael@paquier.xyz>2022-08-24 12:57:13 +0900
commitd951052a9e02bfacad8bd6f0f53a4dcd3b7e6d1f (patch)
tree3191caa0fb1cff85f349f3cdbb111ceca995f85c /src/backend/utils/init
parent421892a192b8f95ab96c5edb61d424f80a4221d0 (diff)
downloadpostgresql-d951052a9e02bfacad8bd6f0f53a4dcd3b7e6d1f.tar.gz
postgresql-d951052a9e02bfacad8bd6f0f53a4dcd3b7e6d1f.zip
Allow parallel workers to retrieve some data from Port
This commit moves authn_id into a new global structure called ClientConnectionInfo (mapping to a MyClientConnectionInfo for each backend) which is intended to hold all the client information that should be shared between the backend and any of its parallel workers, access for extensions and triggers being the primary use case. There is no need to push all the data of Port to the workers, and authn_id is quite a generic concept so using a separate structure provides the best balance (the name of the structure has been suggested by Robert Haas). While on it, and per discussion as this would be useful for a potential SYSTEM_USER that can be accessed through parallel workers, a second field is added for the authentication method, copied directly from Port. ClientConnectionInfo is serialized and restored using a new parallel key and a structure tracks the length of the authn_id, making the addition of more fields straight-forward. Author: Jacob Champion Reviewed-by: Bertrand Drouvot, Stephen Frost, Robert Haas, Tom Lane, Michael Paquier, Julien Rouhaud Discussion: https://postgr.es/m/793d990837ae5c06a558d58d62de9378ab525d83.camel@vmware.com
Diffstat (limited to 'src/backend/utils/init')
-rw-r--r--src/backend/utils/init/miscinit.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index bf3871a774b..683f616b1a8 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -936,6 +936,99 @@ GetUserNameFromId(Oid roleid, bool noerr)
return result;
}
+/* ------------------------------------------------------------------------
+ * Client connection state shared with parallel workers
+ *
+ * ClientConnectionInfo contains pieces of information about the client that
+ * need to be synced to parallel workers when they initialize.
+ *-------------------------------------------------------------------------
+ */
+
+ClientConnectionInfo MyClientConnectionInfo;
+
+/*
+ * Intermediate representation of ClientConnectionInfo for easier
+ * serialization. Variable-length fields are allocated right after this
+ * header.
+ */
+typedef struct SerializedClientConnectionInfo
+{
+ int32 authn_id_len; /* strlen(authn_id), or -1 if NULL */
+ UserAuth auth_method;
+} SerializedClientConnectionInfo;
+
+/*
+ * Calculate the space needed to serialize MyClientConnectionInfo.
+ */
+Size
+EstimateClientConnectionInfoSpace(void)
+{
+ Size size = 0;
+
+ size = add_size(size, sizeof(SerializedClientConnectionInfo));
+
+ if (MyClientConnectionInfo.authn_id)
+ size = add_size(size, strlen(MyClientConnectionInfo.authn_id) + 1);
+
+ return size;
+}
+
+/*
+ * Serialize MyClientConnectionInfo for use by parallel workers.
+ */
+void
+SerializeClientConnectionInfo(Size maxsize, char *start_address)
+{
+ SerializedClientConnectionInfo serialized = {0};
+
+ serialized.authn_id_len = -1;
+ serialized.auth_method = MyClientConnectionInfo.auth_method;
+
+ if (MyClientConnectionInfo.authn_id)
+ serialized.authn_id_len = strlen(MyClientConnectionInfo.authn_id);
+
+ /* Copy serialized representation to buffer */
+ Assert(maxsize >= sizeof(serialized));
+ memcpy(start_address, &serialized, sizeof(serialized));
+
+ maxsize -= sizeof(serialized);
+ start_address += sizeof(serialized);
+
+ /* Copy authn_id into the space after the struct */
+ if (serialized.authn_id_len >= 0)
+ {
+ Assert(maxsize >= (serialized.authn_id_len + 1));
+ memcpy(start_address,
+ MyClientConnectionInfo.authn_id,
+ /* include the NULL terminator to ease deserialization */
+ serialized.authn_id_len + 1);
+ }
+}
+
+/*
+ * Restore MyClientConnectionInfo from its serialized representation.
+ */
+void
+RestoreClientConnectionInfo(char *conninfo)
+{
+ SerializedClientConnectionInfo serialized;
+
+ memcpy(&serialized, conninfo, sizeof(serialized));
+
+ /* Copy the fields back into place */
+ MyClientConnectionInfo.authn_id = NULL;
+ MyClientConnectionInfo.auth_method = serialized.auth_method;
+
+ if (serialized.authn_id_len >= 0)
+ {
+ char *authn_id;
+
+ authn_id = conninfo + sizeof(serialized);
+ MyClientConnectionInfo.authn_id = MemoryContextStrdup(TopMemoryContext,
+ authn_id);
+ }
+}
+
/*-------------------------------------------------------------------------
* Interlock-file support