commit e6eca817f3cc359fff762600ad286d92046ba07d Author: Jacob Champion Date: Thu Mar 24 10:00:30 2022 -0700 squash! Allow parallel workers to use pg_session_authn_id() Move SharedPort out of Port and over to miscinit.c. diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index dda2aab7b1..c88eab0933 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -478,79 +478,6 @@ InitializeParallelDSM(ParallelContext *pcxt) MemoryContextSwitchTo(oldcontext); } -/* - * Calculate the space needed to serialize MyProcPort->shared. - */ -Size -EstimateSharedPortSpace(void) -{ - SharedPort *shared = &MyProcPort->shared; - Size size = 1; - - if (shared->authn_id) - size = add_size(size, strlen(shared->authn_id) + 1); - - return size; -} - -/* - * Serialize MyProcPort->shared for use by parallel workers. - */ -void -SerializeSharedPort(Size maxsize, char *start_address) -{ - SharedPort *shared = &MyProcPort->shared; - - /* - * First byte is an indication of whether or not authn_id has been set to - * non-NULL, to differentiate that case from the empty string. - */ - Assert(maxsize > 0); - start_address[0] = shared->authn_id ? 1 : 0; - start_address++; - maxsize--; - - if (shared->authn_id) - { - Size len; - - len = strlcpy(start_address, shared->authn_id, maxsize) + 1; - Assert(len <= maxsize); - maxsize -= len; - start_address += len; - } -} - -/* - * Restore MyProcPort->shared from its serialized representation, allocating - * MyProcPort if necessary. - */ -void -RestoreSharedPort(char *sharedport) -{ - /* First make sure we have a place to put the information. */ - if (!MyProcPort) - { - if (!(MyProcPort = calloc(1, sizeof(Port)))) - ereport(FATAL, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - } - - if (sharedport[0] == 0) - { - MyProcPort->shared.authn_id = NULL; - sharedport++; - } - else - { - sharedport++; - MyProcPort->shared.authn_id = MemoryContextStrdup(TopMemoryContext, - sharedport); - sharedport += strlen(sharedport) + 1; - } -} - /* * Reinitialize the dynamic shared memory segment for a parallel context such * that we could launch workers for it again. diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 40384a31b0..bceda9755a 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -342,15 +342,15 @@ auth_failed(Port *port, int status, const char *logdetail) * authorization will fail later. * * The provided string will be copied into TopMemoryContext, to match the - * lifetime of the Port, so it is safe to pass a string that is managed by an - * external library. + * lifetime of MyProcShared, so it is safe to pass a string that is managed by + * an external library. */ static void set_authn_id(Port *port, const char *id) { Assert(id); - if (port->shared.authn_id) + if (MyProcShared.authn_id) { /* * An existing authn_id should never be overwritten; that means two @@ -361,17 +361,17 @@ set_authn_id(Port *port, const char *id) ereport(FATAL, (errmsg("authentication identifier set more than once"), errdetail_log("previous identifier: \"%s\"; new identifier: \"%s\"", - port->shared.authn_id, id))); + MyProcShared.authn_id, id))); } - port->shared.authn_id = MemoryContextStrdup(TopMemoryContext, id); + MyProcShared.authn_id = MemoryContextStrdup(TopMemoryContext, id); if (Log_connections) { ereport(LOG, errmsg("connection authenticated: identity=\"%s\" method=%s " "(%s:%d)", - port->shared.authn_id, + MyProcShared.authn_id, hba_authname(port->hba->auth_method), HbaFileName, port->hba->linenumber)); } @@ -1910,7 +1910,7 @@ auth_peer(hbaPort *port) set_authn_id(port, pw->pw_name); ret = check_usermap(port->hba->usermap, port->user_name, - port->shared.authn_id, false); + MyProcShared.authn_id, false); return ret; #else diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index 9000ad05f8..6d497e63d9 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -275,10 +275,10 @@ session_user(PG_FUNCTION_ARGS) Datum pg_session_authn_id(PG_FUNCTION_ARGS) { - if (!MyProcPort || !MyProcPort->shared.authn_id) + if (!MyProcShared.authn_id) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(cstring_to_text(MyProcPort->shared.authn_id)); + PG_RETURN_TEXT_P(cstring_to_text(MyProcShared.authn_id)); } diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index bdc77af719..0afab3e142 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -929,6 +929,77 @@ GetUserNameFromId(Oid roleid, bool noerr) return result; } +/* ------------------------------------------------------------------------ + * "Shared" connection state + * + * MyProcShared contains pieces of information about the client that need to be + * synced to parallel workers when they initialize. Over time, this list will + * probably grow, and may subsume some of the "user state" variables above. + *------------------------------------------------------------------------- + */ + +SharedPort MyProcShared; + +/* + * Calculate the space needed to serialize MyProcShared. + */ +Size +EstimateSharedPortSpace(void) +{ + Size size = 1; + + if (MyProcShared.authn_id) + size = add_size(size, strlen(MyProcShared.authn_id) + 1); + + return size; +} + +/* + * Serialize MyProcShared for use by parallel workers. + */ +void +SerializeSharedPort(Size maxsize, char *start_address) +{ + /* + * First byte is an indication of whether or not authn_id has been set to + * non-NULL, to differentiate that case from the empty string. + */ + Assert(maxsize > 0); + start_address[0] = MyProcShared.authn_id ? 1 : 0; + start_address++; + maxsize--; + + if (MyProcShared.authn_id) + { + Size len; + + len = strlcpy(start_address, MyProcShared.authn_id, maxsize) + 1; + Assert(len <= maxsize); + maxsize -= len; + start_address += len; + } +} + +/* + * Restore MyProcShared from its serialized representation. + */ +void +RestoreSharedPort(char *sharedport) +{ + if (sharedport[0] == 0) + { + MyProcShared.authn_id = NULL; + sharedport++; + } + else + { + sharedport++; + MyProcShared.authn_id = MemoryContextStrdup(TopMemoryContext, + sharedport); + sharedport += strlen(sharedport) + 1; + } +} + /*------------------------------------------------------------------------- * Interlock-file support diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index 0a9dc61d04..911b8246ce 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -180,12 +180,6 @@ typedef struct Port */ HbaLine *hba; - /* - * Information that's copied between the backend and any parallel workers. - * This is the only part of the Port that a parallel worker may access! - */ - SharedPort shared; - /* * TCP keepalive and user timeout settings. * @@ -342,6 +336,7 @@ extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len); #endif /* ENABLE_GSS */ extern ProtocolVersion FrontendProtocol; +extern SharedPort MyProcShared; /* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */ @@ -355,8 +350,4 @@ extern int pq_setkeepalivesinterval(int interval, Port *port); extern int pq_setkeepalivescount(int count, Port *port); extern int pq_settcpusertimeout(int timeout, Port *port); -extern Size EstimateSharedPortSpace(void); -extern void SerializeSharedPort(Size maxsize, char *start_address); -extern void RestoreSharedPort(char *sharedport); - #endif /* LIBPQ_BE_H */ diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 0abc3ad540..68cc1517a0 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -481,6 +481,10 @@ extern void process_session_preload_libraries(void); extern void pg_bindtextdomain(const char *domain); extern bool has_rolreplication(Oid roleid); +extern Size EstimateSharedPortSpace(void); +extern void SerializeSharedPort(Size maxsize, char *start_address); +extern void RestoreSharedPort(char *sharedport); + /* in access/transam/xlog.c */ extern bool BackupInProgress(void); extern void CancelBackup(void);