diff --git a/contrib/pg_tde/Makefile b/contrib/pg_tde/Makefile index f8500336c00c2..32171a622cb67 100644 --- a/contrib/pg_tde/Makefile +++ b/contrib/pg_tde/Makefile @@ -44,7 +44,6 @@ src/keyring/keyring_api.o \ src/catalog/tde_keyring.o \ src/catalog/tde_keyring_parse_opts.o \ src/catalog/tde_principal_key.o \ -src/common/pg_tde_shmem.o \ src/common/pg_tde_utils.o \ src/smgr/pg_tde_smgr.o \ src/pg_tde_event_capture.o \ diff --git a/contrib/pg_tde/meson.build b/contrib/pg_tde/meson.build index 7abf96de07030..c2b44755a5eca 100644 --- a/contrib/pg_tde/meson.build +++ b/contrib/pg_tde/meson.build @@ -7,7 +7,6 @@ pg_tde_sources = files( 'src/catalog/tde_keyring.c', 'src/catalog/tde_keyring_parse_opts.c', 'src/catalog/tde_principal_key.c', - 'src/common/pg_tde_shmem.c', 'src/common/pg_tde_utils.c', 'src/encryption/enc_aes.c', 'src/encryption/enc_tde.c', diff --git a/contrib/pg_tde/src/catalog/tde_keyring.c b/contrib/pg_tde/src/catalog/tde_keyring.c index c5aee34e377bd..b192069052af2 100644 --- a/contrib/pg_tde/src/catalog/tde_keyring.c +++ b/contrib/pg_tde/src/catalog/tde_keyring.c @@ -34,12 +34,13 @@ #ifndef FRONTEND #include "access/heapam.h" +#include "funcapi.h" +#include "access/relscan.h" #include "access/relation.h" #include "access/relscan.h" #include "catalog/namespace.h" #include "executor/spi.h" #include "funcapi.h" -#include "common/pg_tde_shmem.h" #else #include "fe_utils/simple_list.h" #include "pg_tde_fe.h" @@ -87,12 +88,10 @@ PG_FUNCTION_INFO_V1(pg_tde_list_all_global_key_providers); static const char *get_keyring_provider_typename(ProviderType p_type); static List *GetAllKeyringProviders(Oid dbOid); -static Size initialize_shared_state(void *start_address); static Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS, Oid dbOid); static Datum pg_tde_change_key_provider_internal(PG_FUNCTION_ARGS, Oid dbOid); static Datum pg_tde_delete_key_provider_internal(PG_FUNCTION_ARGS, Oid dbOid); static Datum pg_tde_list_all_key_providers_internal(PG_FUNCTION_ARGS, const char *fname, Oid dbOid); -static Size required_shared_mem_size(void); static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid); static void save_new_key_provider_info(KeyringProviderRecord *provider, Oid databaseId); static void modify_key_provider_info(KeyringProviderRecord *provider, Oid databaseId); @@ -101,47 +100,19 @@ static void check_provider_record(KeyringProviderRecord *provider_record); #define PG_TDE_LIST_PROVIDERS_COLS 4 -typedef struct TdeKeyProviderInfoSharedState -{ - LWLockPadded *Locks; -} TdeKeyProviderInfoSharedState; - -TdeKeyProviderInfoSharedState *sharedPrincipalKeyState = NULL; /* Lives in shared state */ - -static const TDEShmemSetupRoutine key_provider_info_shmem_routine = { - .init_shared_state = initialize_shared_state, - .init_dsa_area_objects = NULL, - .required_shared_mem_size = required_shared_mem_size, - .shmem_kill = NULL -}; - -static Size -required_shared_mem_size(void) -{ - return MAXALIGN(sizeof(TdeKeyProviderInfoSharedState)); -} - -static Size -initialize_shared_state(void *start_address) -{ - sharedPrincipalKeyState = (TdeKeyProviderInfoSharedState *) start_address; - sharedPrincipalKeyState->Locks = GetNamedLWLockTranche(TDE_TRANCHE_NAME); - - return sizeof(TdeKeyProviderInfoSharedState); -} +static LWLockPadded *tdeLocks = NULL; /* Lives in shared state */ static inline LWLock * tde_provider_info_lock(void) { - Assert(sharedPrincipalKeyState); - return &sharedPrincipalKeyState->Locks[TDE_LWLOCK_PI_FILES].lock; + Assert(tdeLocks); + return &tdeLocks[TDE_LWLOCK_PI_FILES].lock; } void -InitializeKeyProviderInfo(void) +KeyProviderShmemInit(void) { - ereport(LOG, errmsg("initializing TDE key provider info")); - RegisterShmemRequest(&key_provider_info_shmem_routine); + tdeLocks = GetNamedLWLockTranche(TDE_TRANCHE_NAME); } void diff --git a/contrib/pg_tde/src/catalog/tde_principal_key.c b/contrib/pg_tde/src/catalog/tde_principal_key.c index 21d7156375214..a3dcd443f6ed6 100644 --- a/contrib/pg_tde/src/catalog/tde_principal_key.c +++ b/contrib/pg_tde/src/catalog/tde_principal_key.c @@ -44,7 +44,6 @@ #include "lib/dshash.h" #include "storage/lwlock.h" #include "storage/shmem.h" -#include "common/pg_tde_shmem.h" #else #include "pg_tde_fe.h" #endif @@ -60,7 +59,6 @@ typedef struct TdePrincipalKeySharedState LWLockPadded *Locks; dshash_table_handle hashHandle; void *rawDsaArea; /* DSA area pointer */ - } TdePrincipalKeySharedState; typedef struct TdePrincipalKeylocalState @@ -84,10 +82,6 @@ static dshash_parameters principal_key_dsh_params = { static TdePrincipalKeylocalState principalKeyLocalState; static void principal_key_info_attach_shmem(void); -static Size initialize_shared_state(void *start_address); -static void initialize_objects_in_dsa_area(dsa_area *dsa, void *raw_dsa_area); -static Size required_shared_mem_size(void); -static void shared_memory_shutdown(int code, Datum arg); static void clear_principal_key_cache(Oid databaseId); static inline dshash_table *get_principal_key_hash(void); static TDEPrincipalKey *get_principal_key_from_cache(Oid dbOid); @@ -111,32 +105,6 @@ PG_FUNCTION_INFO_V1(pg_tde_set_server_key_using_global_key_provider); static void pg_tde_set_principal_key_internal(Oid providerOid, Oid dbOid, const char *principal_key_name, const char *provider_name, bool ensure_new_key); -static const TDEShmemSetupRoutine principal_key_info_shmem_routine = { - .init_shared_state = initialize_shared_state, - .init_dsa_area_objects = initialize_objects_in_dsa_area, - .required_shared_mem_size = required_shared_mem_size, - .shmem_kill = shared_memory_shutdown -}; - -void -InitializePrincipalKeyInfo(void) -{ - ereport(LOG, errmsg("Initializing TDE principal key info")); - RegisterShmemRequest(&principal_key_info_shmem_routine); -} - -/* - * Lock to guard internal/principal key. Usually, this lock has to be held until - * the caller fetches an internal_key or rotates the principal. - */ -LWLock * -tde_lwlock_enc_keys(void) -{ - Assert(principalKeyLocalState.sharedPrincipalKeyState); - - return &principalKeyLocalState.sharedPrincipalKeyState->Locks[TDE_LWLOCK_ENC_KEY].lock; -} - /* * Request some pages so we can fit the DSA header, empty hash table plus some * extra. Additional memory to grow the hash map will be allocated as needed @@ -147,8 +115,8 @@ tde_lwlock_enc_keys(void) */ #define CACHE_DSA_INITIAL_SIZE (4096 * 64) -static Size -required_shared_mem_size(void) +Size +PrincipalKeyShmemSize(void) { Size sz = CACHE_DSA_INITIAL_SIZE; @@ -156,41 +124,75 @@ required_shared_mem_size(void) return MAXALIGN(sz); } -/* - * Initialize the shared area for Principal key info. - * This includes locks and cache area for principal key info - */ - -static Size -initialize_shared_state(void *start_address) +void +PrincipalKeyShmemInit(void) { - TdePrincipalKeySharedState *sharedState = (TdePrincipalKeySharedState *) start_address; + bool found; + char *free_start; + Size required_shmem_size = PrincipalKeyShmemSize(); - ereport(LOG, errmsg("initializing shared state for principal key")); + LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); - sharedState->Locks = GetNamedLWLockTranche(TDE_TRANCHE_NAME); + /* Create or attach to the shared memory state */ + ereport(NOTICE, errmsg("PrincipalKeyShmemInit: requested %ld bytes", required_shmem_size)); + free_start = ShmemInitStruct("pg_tde", required_shmem_size, &found); - principalKeyLocalState.sharedPrincipalKeyState = sharedState; - principalKeyLocalState.sharedHash = NULL; + if (!found) + { + TdePrincipalKeySharedState *sharedState; + Size sz; + Size dsa_area_size; + dsa_area *dsa; + dshash_table *dsh; - return sizeof(TdePrincipalKeySharedState); -} + /* Now place shared state structure */ + sharedState = (TdePrincipalKeySharedState *) free_start; + sz = MAXALIGN(sizeof(TdePrincipalKeySharedState)); + free_start += sz; + Assert(sz <= required_shmem_size); -static void -initialize_objects_in_dsa_area(dsa_area *dsa, void *raw_dsa_area) -{ - dshash_table *dsh; - TdePrincipalKeySharedState *sharedState = principalKeyLocalState.sharedPrincipalKeyState; + /* Create DSA area */ + dsa_area_size = required_shmem_size - sz; + Assert(dsa_area_size > 0); + + ereport(LOG, errmsg("creating DSA area of size %lu", dsa_area_size)); + + dsa = dsa_create_in_place(free_start, + dsa_area_size, + LWLockNewTrancheId(), 0); + dsa_pin(dsa); + + /* Limit area size during population to get a nice error */ + dsa_set_size_limit(dsa, dsa_area_size); + + principal_key_dsh_params.tranche_id = LWLockNewTrancheId(); + dsh = dshash_create(dsa, &principal_key_dsh_params, NULL); + + dsa_set_size_limit(dsa, -1); - ereport(LOG, errmsg("initializing dsa area objects for principal key")); + sharedState->Locks = GetNamedLWLockTranche(TDE_TRANCHE_NAME); + sharedState->hashHandle = dshash_get_hash_table_handle(dsh); + sharedState->rawDsaArea = free_start; - Assert(sharedState != NULL); + principalKeyLocalState.sharedPrincipalKeyState = sharedState; + principalKeyLocalState.sharedHash = NULL; - sharedState->rawDsaArea = raw_dsa_area; - principal_key_dsh_params.tranche_id = LWLockNewTrancheId(); - dsh = dshash_create(dsa, &principal_key_dsh_params, NULL); - sharedState->hashHandle = dshash_get_hash_table_handle(dsh); - dshash_detach(dsh); + dshash_detach(dsh); + } + + LWLockRelease(AddinShmemInitLock); +} + +/* + * Lock to guard internal/principal key. Usually, this lock has to be held until + * the caller fetches an internal_key or rotates the principal. + */ +LWLock * +tde_lwlock_enc_keys(void) +{ + Assert(principalKeyLocalState.sharedPrincipalKeyState); + + return &principalKeyLocalState.sharedPrincipalKeyState->Locks[TDE_LWLOCK_ENC_KEY].lock; } /* @@ -217,12 +219,6 @@ principal_key_info_attach_shmem(void) MemoryContextSwitchTo(oldcontext); } -static void -shared_memory_shutdown(int code, Datum arg) -{ - principalKeyLocalState.sharedPrincipalKeyState = NULL; -} - void set_principal_key_with_keyring(const char *key_name, const char *provider_name, Oid providerOid, Oid dbOid, bool ensure_new_key) diff --git a/contrib/pg_tde/src/common/pg_tde_shmem.c b/contrib/pg_tde/src/common/pg_tde_shmem.c deleted file mode 100644 index 697a3e23b6843..0000000000000 --- a/contrib/pg_tde/src/common/pg_tde_shmem.c +++ /dev/null @@ -1,132 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_tde_shmem.c - * Shared memory area to manage cache and locks. - * - * IDENTIFICATION - * contrib/pg_tde/src/pg_tde_shmem.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "lib/dshash.h" -#include "nodes/pg_list.h" -#include "storage/ipc.h" -#include "storage/lwlock.h" -#include "storage/shmem.h" - -#include "common/pg_tde_shmem.h" - -static void tde_shmem_shutdown(int code, Datum arg); - -List *registeredShmemRequests = NIL; -bool shmemInited = false; - -void -RegisterShmemRequest(const TDEShmemSetupRoutine *routine) -{ - Assert(shmemInited == false); - registeredShmemRequests = lappend(registeredShmemRequests, (void *) routine); -} - -Size -TdeRequiredSharedMemorySize(void) -{ - Size sz = 0; - ListCell *lc; - - foreach(lc, registeredShmemRequests) - { - TDEShmemSetupRoutine *routine = (TDEShmemSetupRoutine *) lfirst(lc); - - if (routine->required_shared_mem_size) - sz = add_size(sz, routine->required_shared_mem_size()); - } - return MAXALIGN(sz); -} - -int -TdeRequiredLocksCount(void) -{ - return TDE_LWLOCK_COUNT; -} - -void -TdeShmemInit(void) -{ - bool found; - char *free_start; - Size required_shmem_size = TdeRequiredSharedMemorySize(); - - LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); - /* Create or attach to the shared memory state */ - ereport(NOTICE, errmsg("TdeShmemInit: requested %ld bytes", required_shmem_size)); - free_start = ShmemInitStruct("pg_tde", required_shmem_size, &found); - - if (!found) - { - /* First time through ... */ - dsa_area *dsa; - ListCell *lc; - Size used_size = 0; - Size dsa_area_size; - - /* Now place all shared state structures */ - foreach(lc, registeredShmemRequests) - { - Size sz = 0; - TDEShmemSetupRoutine *routine = (TDEShmemSetupRoutine *) lfirst(lc); - - if (routine->init_shared_state) - { - sz = routine->init_shared_state(free_start); - used_size += MAXALIGN(sz); - free_start += MAXALIGN(sz); - Assert(used_size <= required_shmem_size); - } - } - /* Create DSA area */ - dsa_area_size = required_shmem_size - used_size; - Assert(dsa_area_size > 0); - - ereport(LOG, errmsg("creating DSA area of size %lu", dsa_area_size)); - dsa = dsa_create_in_place(free_start, - dsa_area_size, - LWLockNewTrancheId(), 0); - dsa_pin(dsa); - dsa_set_size_limit(dsa, dsa_area_size); - - /* Initialize all DSA area objects */ - foreach(lc, registeredShmemRequests) - { - TDEShmemSetupRoutine *routine = (TDEShmemSetupRoutine *) lfirst(lc); - - if (routine->init_dsa_area_objects) - routine->init_dsa_area_objects(dsa, free_start); - } - ereport(LOG, errmsg("setting no limit to DSA area of size %lu", dsa_area_size)); - - dsa_set_size_limit(dsa, -1); /* Let it grow outside the shared - * memory */ - - shmemInited = true; - } - LWLockRelease(AddinShmemInitLock); - on_shmem_exit(tde_shmem_shutdown, (Datum) 0); -} - -static void -tde_shmem_shutdown(int code, Datum arg) -{ - ListCell *lc; - - foreach(lc, registeredShmemRequests) - { - TDEShmemSetupRoutine *routine = (TDEShmemSetupRoutine *) lfirst(lc); - - if (routine->shmem_kill) - routine->shmem_kill(code, arg); - } -} diff --git a/contrib/pg_tde/src/include/catalog/tde_keyring.h b/contrib/pg_tde/src/include/catalog/tde_keyring.h index 11c24027747e6..5dd09f3e2c12a 100644 --- a/contrib/pg_tde/src/include/catalog/tde_keyring.h +++ b/contrib/pg_tde/src/include/catalog/tde_keyring.h @@ -33,7 +33,7 @@ typedef struct KeyringProviderRecordInFile extern GenericKeyring *GetKeyProviderByName(const char *provider_name, Oid dbOid); extern GenericKeyring *GetKeyProviderByID(int provider_id, Oid dbOid); extern ProviderType get_keyring_provider_from_typename(char *provider_type); -extern void InitializeKeyProviderInfo(void); +extern void KeyProviderShmemInit(void); extern void key_provider_startup_cleanup(Oid databaseId); extern bool get_keyring_info_file_record_by_name(char *provider_name, Oid database_id, diff --git a/contrib/pg_tde/src/include/catalog/tde_principal_key.h b/contrib/pg_tde/src/include/catalog/tde_principal_key.h index 26dd6f22befaa..185a92292954a 100644 --- a/contrib/pg_tde/src/include/catalog/tde_principal_key.h +++ b/contrib/pg_tde/src/include/catalog/tde_principal_key.h @@ -42,7 +42,8 @@ typedef struct XLogPrincipalKeyRotate #define SizeoOfXLogPrincipalKeyRotate offsetof(XLogPrincipalKeyRotate, buff) -extern void InitializePrincipalKeyInfo(void); +extern void PrincipalKeyShmemInit(void); +extern Size PrincipalKeyShmemSize(void); #ifndef FRONTEND extern void principal_key_startup_cleanup(Oid databaseId); diff --git a/contrib/pg_tde/src/include/common/pg_tde_shmem.h b/contrib/pg_tde/src/include/common/pg_tde_shmem.h deleted file mode 100644 index 31dfb3a691723..0000000000000 --- a/contrib/pg_tde/src/include/common/pg_tde_shmem.h +++ /dev/null @@ -1,60 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_tde_shmem.h - * src/include/common/pg_tde_shmem.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_TDE_SHMEM_H -#define PG_TDE_SHMEM_H - -#include "postgres.h" -#include "utils/dsa.h" - -#define TDE_TRANCHE_NAME "pg_tde_tranche" - -typedef enum -{ - TDE_LWLOCK_ENC_KEY, - TDE_LWLOCK_PI_FILES, - - /* Must be the last entry in the enum */ - TDE_LWLOCK_COUNT -} TDELockTypes; - -typedef struct TDEShmemSetupRoutine -{ - /* - * init_shared_state gets called at the time of extension load you can - * initialize the data structures required to be placed in shared memory - * in this callback The callback must return the size of the shared memory - * area acquired. The argument to the function is the start of the shared - * memory address that can be used to store the shared data structures. - */ - Size (*init_shared_state) (void *raw_dsa_area); - - /* - * shmem_startup gets called at the time of postmaster shutdown - */ - void (*shmem_kill) (int code, Datum arg); - - /* - * The callback must return the size of the shared memory acquired. - */ - Size (*required_shared_mem_size) (void); - - /* - * Gets called after all shared memory structures are initialized and here - * you can create shared memory hash tables or any other shared objects - * that needs to live in DSA area. - */ - void (*init_dsa_area_objects) (dsa_area *dsa, void *raw_dsa_area); -} TDEShmemSetupRoutine; - -/* Interface to register the shared memory requests */ -extern void RegisterShmemRequest(const TDEShmemSetupRoutine *routine); -extern void TdeShmemInit(void); -extern Size TdeRequiredSharedMemorySize(void); -extern int TdeRequiredLocksCount(void); - -#endif /* PG_TDE_SHMEM_H */ diff --git a/contrib/pg_tde/src/include/pg_tde.h b/contrib/pg_tde/src/include/pg_tde.h index f20af2892e896..cdeff802ed7b1 100644 --- a/contrib/pg_tde/src/include/pg_tde.h +++ b/contrib/pg_tde/src/include/pg_tde.h @@ -14,6 +14,17 @@ #define PG_TDE_DATA_DIR "pg_tde" +#define TDE_TRANCHE_NAME "pg_tde_tranche" + +typedef enum +{ + TDE_LWLOCK_ENC_KEY, + TDE_LWLOCK_PI_FILES, + + /* Must be the last entry in the enum */ + TDE_LWLOCK_COUNT +} TDELockTypes; + typedef struct XLogExtensionInstall { Oid database_id; diff --git a/contrib/pg_tde/src/pg_tde.c b/contrib/pg_tde/src/pg_tde.c index f38ad795609c4..216d6a1f3c6cb 100644 --- a/contrib/pg_tde/src/pg_tde.c +++ b/contrib/pg_tde/src/pg_tde.c @@ -30,7 +30,6 @@ #include "access/pg_tde_xlog_smgr.h" #include "catalog/tde_global_space.h" #include "catalog/tde_principal_key.h" -#include "common/pg_tde_shmem.h" #include "encryption/enc_aes.h" #include "keyring/keyring_api.h" #include "keyring/keyring_file.h" @@ -55,15 +54,16 @@ PG_FUNCTION_INFO_V1(pg_tdeam_handler); static void tde_shmem_request(void) { - Size sz = TdeRequiredSharedMemorySize(); - int required_locks = TdeRequiredLocksCount(); + Size sz = 0; + sz = add_size(sz, PrincipalKeyShmemSize()); sz = add_size(sz, TDEXLogEncryptStateSize()); if (prev_shmem_request_hook) prev_shmem_request_hook(); + RequestAddinShmemSpace(sz); - RequestNamedLWLockTranche(TDE_TRANCHE_NAME, required_locks); + RequestNamedLWLockTranche(TDE_TRANCHE_NAME, TDE_LWLOCK_COUNT); ereport(LOG, errmsg("tde_shmem_request: requested %ld bytes", sz)); } @@ -73,7 +73,8 @@ tde_shmem_startup(void) if (prev_shmem_startup_hook) prev_shmem_startup_hook(); - TdeShmemInit(); + KeyProviderShmemInit(); + PrincipalKeyShmemInit(); TDEXLogShmemInit(); TDEXLogSmgrInit(); } @@ -99,8 +100,6 @@ _PG_init(void) AesInit(); TdeGucInit(); TdeEventCaptureInit(); - InitializePrincipalKeyInfo(); - InitializeKeyProviderInfo(); InstallFileKeyring(); InstallVaultV2Keyring(); InstallKmipKeyring();