From 74e6d08530dfb07a62ce61516c2f32a54d2a142e Mon Sep 17 00:00:00 2001 From: Andrew Pogrebnoy Date: Fri, 15 Nov 2024 19:44:19 +0200 Subject: [PATCH] Move pg_tde files to one dir inside PGDATA For PG-1209 --- meson.build | 2 +- src/access/pg_tde_tdemap.c | 79 +++++-------------------- src/catalog/tde_global_space.c | 10 ++-- src/catalog/tde_keyring.c | 72 +++++++++------------- src/catalog/tde_principal_key.c | 24 ++++---- src/common/pg_tde_utils.c | 19 ------ src/include/access/pg_tde_tdemap.h | 17 +++++- src/include/catalog/tde_global_space.h | 2 - src/include/catalog/tde_keyring.h | 12 ++-- src/include/catalog/tde_principal_key.h | 2 +- src/include/common/pg_tde_utils.h | 1 - src/include/pg_tde.h | 4 ++ src/pg_tde.c | 20 +++++++ 13 files changed, 104 insertions(+), 160 deletions(-) diff --git a/meson.build b/meson.build index cc49a7ba..06e971c8 100644 --- a/meson.build +++ b/meson.build @@ -128,7 +128,7 @@ if get_variable('percona_ext', false) 'trigger_on_view', 'change_access_method', 'insert_update_delete', - # 'tablespace', + 'tablespace', 'vault_v2_test', 'alter_index', 'merge_join', diff --git a/src/access/pg_tde_tdemap.c b/src/access/pg_tde_tdemap.c index f1ee5956..59c630f6 100644 --- a/src/access/pg_tde_tdemap.c +++ b/src/access/pg_tde_tdemap.c @@ -55,9 +55,6 @@ } #endif -#define PG_TDE_MAP_FILENAME "pg_tde.map" -#define PG_TDE_KEYDATA_FILENAME "pg_tde.dat" - #define PG_TDE_FILEMAGIC 0x01454454 /* version ID value = TDE 01 */ @@ -259,13 +256,13 @@ tde_encrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyData *rel_key_data, co * Returns true if both map and key data files are created. */ void -pg_tde_delete_tde_files(Oid dbOid, Oid spcOid) +pg_tde_delete_tde_files(Oid dbOid) { char db_map_path[MAXPGPATH] = {0}; char db_keydata_path[MAXPGPATH] = {0}; /* Set the file paths */ - pg_tde_set_db_file_paths(dbOid, spcOid, db_map_path, db_keydata_path); + pg_tde_set_db_file_paths(dbOid, db_map_path, db_keydata_path); /* Remove these files without emitting any error */ PathNameDeleteTemporaryFile(db_map_path, false); @@ -294,7 +291,6 @@ pg_tde_save_principal_key(TDEPrincipalKeyInfo *principal_key_info) /* Set the file paths */ pg_tde_set_db_file_paths(principal_key_info->databaseId, - principal_key_info->tablespaceId, db_map_path, db_keydata_path); ereport(LOG, (errmsg("pg_tde_save_principal_key"))); @@ -434,7 +430,7 @@ pg_tde_write_one_map_entry(int fd, const RelFileLocator *rlocator, uint32 flags, { char db_map_path[MAXPGPATH] = {0}; - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL); ereport(FATAL, (errcode_for_file_access(), errmsg("could not write tde map file \"%s\": %m", @@ -444,7 +440,7 @@ pg_tde_write_one_map_entry(int fd, const RelFileLocator *rlocator, uint32 flags, { char db_map_path[MAXPGPATH] = {0}; - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL); ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", db_map_path))); @@ -525,7 +521,7 @@ pg_tde_write_key_map_entry(const RelFileLocator *rlocator, RelKeyData *enc_rel_k Assert(rlocator); /* Set the file paths */ - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path); /* Create the map entry and then add the encrypted key to the data file */ key_index = pg_tde_write_map_entry(rlocator, enc_rel_key_data->internal_key.rel_type, db_map_path, principal_key_info); @@ -550,7 +546,7 @@ pg_tde_delete_key_map_entry(const RelFileLocator *rlocator, uint32 key_type) Assert(rlocator); /* Get the file paths */ - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path); errno = 0; /* Remove the map entry if found */ @@ -596,7 +592,7 @@ pg_tde_free_key_map_entry(const RelFileLocator *rlocator, uint32 key_type, off_t Assert(rlocator); /* Get the file paths */ - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, NULL); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, NULL); /* Remove the map entry if found */ key_index = pg_tde_process_map_entry(rlocator, key_type, db_map_path, &offset, true); @@ -610,17 +606,6 @@ pg_tde_free_key_map_entry(const RelFileLocator *rlocator, uint32 key_type, off_t db_map_path))); } - /* - * Remove TDE files it was the last TDE relation in a custom tablespace. - * DROP TABLESPACE needs an empty dir. - */ - if (rlocator->spcOid != GLOBALTABLESPACE_OID && - rlocator->spcOid != DEFAULTTABLESPACE_OID && - pg_tde_process_map_entry(NULL, key_type, db_map_path, &start, false) == -1) - { - pg_tde_delete_tde_files(rlocator->dbOid, rlocator->spcOid); - cleanup_key_provider_info(rlocator->dbOid, rlocator->spcOid); - } } /* @@ -689,7 +674,6 @@ pg_tde_perform_rotate_key(TDEPrincipalKey *principal_key, TDEPrincipalKey *new_p /* Set the file paths */ pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, - principal_key->keyInfo.tablespaceId, db_map_path, db_keydata_path); /* @@ -814,7 +798,6 @@ pg_tde_write_map_keydata_files(off_t map_size, char *m_file_data, off_t keydata_ /* Set the file paths */ pg_tde_set_db_file_paths(fheader->principal_key_info.databaseId, - fheader->principal_key_info.tablespaceId, db_map_path, db_keydata_path); /* Initialize the new files and set the names */ @@ -870,10 +853,8 @@ pg_tde_write_map_keydata_files(off_t map_size, char *m_file_data, off_t keydata_ } /* - * Move relation's key to the new physical location and cache it with the new - * relfilenode. It recreates *.map and *.dat files with the old principal key - * and re-encrypted with the new relfilenode internal key. And copies the - * old keyring to the new location. + * Move relation's key - re-encrypts and saves the relation key with the new + * relfilenode. * Needed by ALTER TABLE SET TABLESPACE for example. */ bool @@ -890,31 +871,13 @@ pg_tde_move_rel_key(const RelFileLocator *newrlocator, const RelFileLocator *old off_t offset = 0; int32 key_index = 0; - pg_tde_set_db_file_paths(oldrlocator->dbOid, oldrlocator->spcOid, db_map_path, db_keydata_path); + pg_tde_set_db_file_paths(oldrlocator->dbOid, db_map_path, db_keydata_path); LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE); principal_key = GetPrincipalKey(oldrlocator->dbOid, oldrlocator->spcOid, LW_EXCLUSIVE); Assert(principal_key); - /* - * Copy kering provider info. - * - * TODO: we can potentially avoid moving keyring and key tde files keeping - * these files always in dbOid+MyDatabaseTableSpace path. But the - * background writer isn't aware of MyDatabaseTableSpace hence it won't - * work with SMGR -> tde_heap. Revisit this after chages in SMGR (mdcreate) - * interface. - */ - keyring = GetKeyProviderByID(principal_key->keyInfo.keyringId, oldrlocator->dbOid, oldrlocator->spcOid); - Assert(keyring); - memcpy(provider_rec.provider_name, keyring->provider_name, sizeof(keyring->provider_name)); - provider_rec.provider_type = keyring->type; - memcpy(provider_rec.options, keyring->options, sizeof(keyring->options)); - copy_key_provider_info(&provider_rec, newrlocator->dbOid, newrlocator->spcOid, true); - - principal_key->keyInfo.keyringId = provider_rec.provider_id; - key_index = pg_tde_process_map_entry(oldrlocator, MAP_ENTRY_VALID, db_map_path, &offset, false); Assert(key_index != -1); /* @@ -992,7 +955,7 @@ pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool n } /* Get the file paths */ - pg_tde_set_db_file_paths(rlocator->dbOid, rlocator->spcOid, db_map_path, db_keydata_path); + pg_tde_set_db_file_paths(rlocator->dbOid, db_map_path, db_keydata_path); if (no_map_ok && access(db_map_path, F_OK) == -1) { @@ -1016,18 +979,6 @@ pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool n return rel_key_data; } -inline void -pg_tde_set_db_file_paths(Oid dbOid, Oid spcOid, char *map_path, char *keydata_path) -{ - char *db_path = pg_tde_get_tde_file_dir(dbOid, spcOid); - - if (map_path) - join_path_components(map_path, db_path, PG_TDE_MAP_FILENAME); - if (keydata_path) - join_path_components(keydata_path, db_path, PG_TDE_KEYDATA_FILENAME); - pfree(db_path); -} - /* * Returns the index of the read map if we find a valid match; i.e. * - flags is set to MAP_ENTRY_VALID and the relNumber matches the one @@ -1321,7 +1272,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi { char db_keydata_path[MAXPGPATH] = {0}; - pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, principal_key->keyInfo.tablespaceId, NULL, db_keydata_path); + pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, NULL, db_keydata_path); ereport(FATAL, (errcode(ERRCODE_NO_DATA_FOUND), errmsg("could not find the required key at index %d in tde data file \"%s\": %m", @@ -1335,7 +1286,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi { char db_keydata_path[MAXPGPATH] = {0}; - pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, principal_key->keyInfo.tablespaceId, NULL, db_keydata_path); + pg_tde_set_db_file_paths(principal_key->keyInfo.databaseId, NULL, db_keydata_path); ereport(FATAL, (errcode_for_file_access(), errmsg("could not read key at index %d in tde key data file \"%s\": %m", @@ -1352,7 +1303,7 @@ pg_tde_read_one_keydata(int keydata_fd, int32 key_index, TDEPrincipalKey *princi * a LW_SHARED or higher lock on files before calling this function. */ TDEPrincipalKeyInfo * -pg_tde_get_principal_key_info(Oid dbOid, Oid spcOid) +pg_tde_get_principal_key_info(Oid dbOid) { int fd = -1; TDEFileHeader fheader; @@ -1362,7 +1313,7 @@ pg_tde_get_principal_key_info(Oid dbOid, Oid spcOid) char db_map_path[MAXPGPATH] = {0}; /* Set the file paths */ - pg_tde_set_db_file_paths(dbOid, spcOid, db_map_path, NULL); + pg_tde_set_db_file_paths(dbOid, db_map_path, NULL); /* * Ensuring that we always open the file in binary mode. The caller must diff --git a/src/catalog/tde_global_space.c b/src/catalog/tde_global_space.c index e97f9d42..583bb788 100644 --- a/src/catalog/tde_global_space.c +++ b/src/catalog/tde_global_space.c @@ -36,7 +36,7 @@ #define KEYRING_DEFAULT_FILE_NAME "pg_tde_default_keyring_CHANGE_AND_REMOVE_IT" #define DefaultKeyProvider GetKeyProviderByName(KEYRING_DEFAULT_NAME, \ - GLOBAL_DATA_TDE_OID, GLOBALTABLESPACE_OID) + GLOBAL_DATA_TDE_OID) #ifndef FRONTEND static void init_keys(void); @@ -53,7 +53,7 @@ TDEInitGlobalKeys(const char *dir) #ifndef FRONTEND char db_map_path[MAXPGPATH] = {0}; - pg_tde_set_db_file_paths(GLOBAL_DATA_TDE_OID, GLOBALTABLESPACE_OID, db_map_path, NULL); + pg_tde_set_db_file_paths(GLOBAL_DATA_TDE_OID, db_map_path, NULL); if (access(db_map_path, F_OK) == -1) { init_default_keyring(); @@ -87,7 +87,7 @@ TDEInitGlobalKeys(const char *dir) static void init_default_keyring(void) { - if (GetAllKeyringProviders(GLOBAL_DATA_TDE_OID, GLOBALTABLESPACE_OID) == NIL) + if (GetAllKeyringProviders(GLOBAL_DATA_TDE_OID) == NIL) { char path[MAXPGPATH] = {0}; static KeyringProvideRecord provider = @@ -100,7 +100,7 @@ init_default_keyring(void) elog(WARNING, "unable to get current working dir"); /* TODO: not sure about the location. Currently it's in $PGDATA */ - join_path_components(path, path, KEYRING_DEFAULT_FILE_NAME); + join_path_components(path, PG_TDE_DATA_DIR, KEYRING_DEFAULT_FILE_NAME); snprintf(provider.options, MAX_KEYRING_OPTION_LEN, "{" @@ -109,6 +109,8 @@ init_default_keyring(void) "}", path ); + pg_tde_init_data_dir(); + /* * TODO: should we remove it automaticaly on * pg_tde_rotate_principal_key() ? diff --git a/src/catalog/tde_keyring.c b/src/catalog/tde_keyring.c index 49cdfd0f..fdb73239 100644 --- a/src/catalog/tde_keyring.c +++ b/src/catalog/tde_keyring.c @@ -47,24 +47,24 @@ typedef enum ProviderScanType PROVIDER_SCAN_ALL } ProviderScanType; -#define PG_TDE_KEYRING_FILENAME "pg_tde_keyrings" +#define PG_TDE_KEYRING_FILENAME "pg_tde_%d_keyring" static FileKeyring *load_file_keyring_provider_options(char *keyring_options); static GenericKeyring *load_keyring_provider_options(ProviderType provider_type, char *keyring_options); static VaultV2Keyring *load_vaultV2_keyring_provider_options(char *keyring_options); static void debug_print_kerying(GenericKeyring *keyring); static GenericKeyring *load_keyring_provider_from_record(KeyringProvideRecord *provider); -static char *get_keyring_infofile_path(char *resPath, Oid dbOid, Oid spcOid); +static inline void get_keyring_infofile_path(char *resPath, Oid dbOid); static bool fetch_next_key_provider(int fd, off_t *curr_pos, KeyringProvideRecord *provider); #ifdef FRONTEND -static SimplePtrList *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid); +static SimplePtrList *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid); static void simple_list_free(SimplePtrList *list); #else -static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid); +static List *scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid); PG_FUNCTION_INFO_V1(pg_tde_add_key_provider_internal); Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS); @@ -77,9 +77,8 @@ Datum pg_tde_list_all_key_providers(PG_FUNCTION_ARGS); static void key_provider_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, bool redo, void *arg); static const char *get_keyring_provider_typename(ProviderType p_type); static uint32 write_key_provider_info(KeyringProvideRecord *provider, - Oid database_id, Oid tablespace_id, - off_t position, bool error_if_exists, - bool write_xlog); + Oid database_id, off_t position, + bool error_if_exists, bool write_xlog); static Size initialize_shared_state(void *start_address); static Size required_shared_mem_size(void); @@ -137,7 +136,7 @@ key_provider_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, (errmsg("failed to perform initialization. database already has %d TDE tables", tde_tbl_count))); return; } - cleanup_key_provider_info(ext_info->database_id, ext_info->tablespace_id); + cleanup_key_provider_info(ext_info->database_id); } ProviderType @@ -169,16 +168,16 @@ get_keyring_provider_typename(ProviderType p_type) } List * -GetAllKeyringProviders(Oid dbOid, Oid spcOid) +GetAllKeyringProviders(Oid dbOid) { - return scan_key_provider_file(PROVIDER_SCAN_ALL, NULL, dbOid, spcOid); + return scan_key_provider_file(PROVIDER_SCAN_ALL, NULL, dbOid); } GenericKeyring * -GetKeyProviderByName(const char *provider_name, Oid dbOid, Oid spcOid) +GetKeyProviderByName(const char *provider_name, Oid dbOid) { GenericKeyring *keyring = NULL; - List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_NAME, (void *) provider_name, dbOid, spcOid); + List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_NAME, (void *) provider_name, dbOid); if (providers != NIL) { @@ -197,8 +196,8 @@ GetKeyProviderByName(const char *provider_name, Oid dbOid, Oid spcOid) static uint32 -write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, - Oid tablespace_id, off_t position, bool error_if_exists, bool write_xlog) +write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, + off_t position, bool error_if_exists, bool write_xlog) { off_t bytes_written = 0; off_t curr_pos = 0; @@ -209,7 +208,7 @@ write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, Assert(provider != NULL); - get_keyring_infofile_path(kp_info_path, database_id, tablespace_id); + get_keyring_infofile_path(kp_info_path, database_id); LWLockAcquire(tde_provider_info_lock(), LW_EXCLUSIVE); @@ -258,7 +257,6 @@ write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, KeyringProviderXLRecord xlrec; xlrec.database_id = database_id; - xlrec.tablespace_id = tablespace_id; xlrec.offset_in_file = curr_pos; memcpy(&xlrec.provider, provider, sizeof(KeyringProvideRecord)); @@ -310,31 +308,22 @@ write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, uint32 save_new_key_provider_info(KeyringProvideRecord* provider, Oid databaseId, Oid tablespaceId, bool write_xlog) { - return write_key_provider_info(provider, databaseId, tablespaceId, -1, true, write_xlog); -} - -/* - * Save the key provider info to the file but don't fail if it is already exists. - */ -uint32 -copy_key_provider_info(KeyringProvideRecord* provider, Oid newdatabaseId, Oid newtablespaceId, bool write_xlog) -{ - return write_key_provider_info(provider, newdatabaseId, newtablespaceId, -1, false, write_xlog); + return write_key_provider_info(provider, databaseId, -1, true, write_xlog); } uint32 redo_key_provider_info(KeyringProviderXLRecord *xlrec) { - return write_key_provider_info(&xlrec->provider, xlrec->database_id, xlrec->tablespace_id, xlrec->offset_in_file, true, false); + return write_key_provider_info(&xlrec->provider, xlrec->database_id, xlrec->offset_in_file, true, false); } void -cleanup_key_provider_info(Oid databaseId, Oid tablespaceId) +cleanup_key_provider_info(Oid databaseId) { /* Remove the key provider info file */ char kp_info_path[MAXPGPATH] = {0}; - get_keyring_infofile_path(kp_info_path, databaseId, tablespaceId); + get_keyring_infofile_path(kp_info_path, databaseId); PathNameDeleteTemporaryFile(kp_info_path, false); } @@ -366,7 +355,7 @@ pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS) Datum pg_tde_list_all_key_providers(PG_FUNCTION_ARGS) { - List *all_providers = GetAllKeyringProviders(MyDatabaseId, MyDatabaseTableSpace); + List *all_providers = GetAllKeyringProviders(MyDatabaseId); ListCell *lc; Tuplestorestate *tupstore; TupleDesc tupdesc; @@ -419,10 +408,10 @@ pg_tde_list_all_key_providers(PG_FUNCTION_ARGS) } GenericKeyring * -GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid) +GetKeyProviderByID(int provider_id, Oid dbOid) { GenericKeyring *keyring = NULL; - List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid, spcOid); + List *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid); if (providers != NIL) { @@ -436,10 +425,10 @@ GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid) #ifdef FRONTEND GenericKeyring * -GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid) +GetKeyProviderByID(int provider_id, Oid dbOid) { GenericKeyring *keyring = NULL; - SimplePtrList *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid, spcOid); + SimplePtrList *providers = scan_key_provider_file(PROVIDER_SCAN_BY_ID, &provider_id, dbOid); if (providers != NULL) { @@ -474,7 +463,7 @@ static List * #else static SimplePtrList * #endif -scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid spcOid) +scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid) { off_t curr_pos = 0; int fd; @@ -489,7 +478,7 @@ scan_key_provider_file(ProviderScanType scanType, void *scanKey, Oid dbOid, Oid if (scanType != PROVIDER_SCAN_ALL) Assert(scanKey != NULL); - get_keyring_infofile_path(kp_info_path, dbOid, spcOid); + get_keyring_infofile_path(kp_info_path, dbOid); LWLockAcquire(tde_provider_info_lock(), LW_SHARED); @@ -661,15 +650,10 @@ debug_print_kerying(GenericKeyring *keyring) } } -static char * -get_keyring_infofile_path(char *resPath, Oid dbOid, Oid spcOid) +static inline void +get_keyring_infofile_path(char *resPath, Oid dbOid) { - char *db_path = pg_tde_get_tde_file_dir(dbOid, spcOid); - - Assert(db_path != NULL); - join_path_components(resPath, db_path, PG_TDE_KEYRING_FILENAME); - pfree(db_path); - return resPath; + join_path_components(resPath, PG_TDE_DATA_DIR, psprintf(PG_TDE_KEYRING_FILENAME, dbOid)); } /* diff --git a/src/catalog/tde_principal_key.c b/src/catalog/tde_principal_key.c index ab241d69..ff525bee 100644 --- a/src/catalog/tde_principal_key.c +++ b/src/catalog/tde_principal_key.c @@ -238,7 +238,7 @@ set_principal_key_with_keyring(const char *key_name, GenericKeyring *keyring, /* TODO: Add the key in the cache? */ if (!is_dup_key) - is_dup_key = (pg_tde_get_principal_key_info(dbOid, spcOid) != NULL); + is_dup_key = (pg_tde_get_principal_key_info(dbOid) != NULL); if (!is_dup_key) { @@ -301,7 +301,7 @@ bool SetPrincipalKey(const char *key_name, const char *provider_name, bool ensure_new_key) { TDEPrincipalKey *principal_key = set_principal_key_with_keyring(key_name, - GetKeyProviderByName(provider_name, MyDatabaseId, MyDatabaseTableSpace), + GetKeyProviderByName(provider_name, MyDatabaseId), MyDatabaseId, MyDatabaseTableSpace, ensure_new_key); @@ -343,15 +343,13 @@ RotatePrincipalKey(TDEPrincipalKey *current_key, const char *new_key_name, const if (new_provider_name != NULL) { new_principal_key.keyInfo.keyringId = GetKeyProviderByName(new_provider_name, - new_principal_key.keyInfo.databaseId, - new_principal_key.keyInfo.tablespaceId)->key_id; + new_principal_key.keyInfo.databaseId)->key_id; } } /* We need a valid keyring structure */ keyring = GetKeyProviderByID(new_principal_key.keyInfo.keyringId, - new_principal_key.keyInfo.databaseId, - new_principal_key.keyInfo.tablespaceId); + new_principal_key.keyInfo.databaseId); keyInfo = load_latest_versioned_key_name(&new_principal_key.keyInfo, keyring, ensure_new_key); @@ -493,7 +491,7 @@ GetPrincipalKeyProviderId(void) * Principal key not present in cache. Try Loading it from the info * file */ - principalKeyInfo = pg_tde_get_principal_key_info(dbOid, MyDatabaseTableSpace); + principalKeyInfo = pg_tde_get_principal_key_info(dbOid); if (principalKeyInfo) { keyringId = principalKeyInfo->keyringId; @@ -582,11 +580,11 @@ principal_key_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, return; } - cleanup_principal_key_info(ext_info->database_id, ext_info->tablespace_id); + cleanup_principal_key_info(ext_info->database_id); } void -cleanup_principal_key_info(Oid databaseId, Oid tablespaceId) +cleanup_principal_key_info(Oid databaseId) { clear_principal_key_cache(databaseId); @@ -596,7 +594,7 @@ cleanup_principal_key_info(Oid databaseId, Oid tablespaceId) */ /* Remove the tde files */ - pg_tde_delete_tde_files(databaseId, tablespaceId); + pg_tde_delete_tde_files(databaseId); } static void @@ -722,7 +720,7 @@ pg_tde_get_key_info(PG_FUNCTION_ARGS, Oid dbOid, Oid spcOid) PG_RETURN_NULL(); } - keyring = GetKeyProviderByID(principal_key->keyInfo.keyringId, dbOid, spcOid); + keyring = GetKeyProviderByID(principal_key->keyInfo.keyringId, dbOid); /* Initialize the values and null flags */ @@ -779,13 +777,13 @@ get_principal_key_from_keyring(Oid dbOid, Oid spcOid) Assert(LWLockHeldByMeInMode(tde_lwlock_enc_keys(), LW_EXCLUSIVE)); - principalKeyInfo = pg_tde_get_principal_key_info(dbOid, spcOid); + principalKeyInfo = pg_tde_get_principal_key_info(dbOid); if (principalKeyInfo == NULL) { return NULL; } - keyring = GetKeyProviderByID(principalKeyInfo->keyringId, dbOid, spcOid); + keyring = GetKeyProviderByID(principalKeyInfo->keyringId, dbOid); if (keyring == NULL) { return NULL; diff --git a/src/common/pg_tde_utils.c b/src/common/pg_tde_utils.c index ce99a972..d12f6040 100644 --- a/src/common/pg_tde_utils.c +++ b/src/common/pg_tde_utils.c @@ -93,22 +93,3 @@ pg_tde_set_globalspace_dir(const char *dir) Assert(dir != NULL); strncpy(globalspace_dir, dir, sizeof(globalspace_dir)); } - -/* returns the palloc'd string */ -char * -pg_tde_get_tde_file_dir(Oid dbOid, Oid spcOid) -{ - /* - * `dbOid` is set to a value for the XLog keys caching but - * GetDatabasePath() expects it (`dbOid`) to be `0` if this is a global - * space. - */ - if (spcOid == GLOBALTABLESPACE_OID) - { - if (strlen(globalspace_dir) > 0) - return pstrdup(globalspace_dir); - - return pstrdup("global"); - } - return GetDatabasePath(dbOid, spcOid); -} diff --git a/src/include/access/pg_tde_tdemap.h b/src/include/access/pg_tde_tdemap.h index c3ae2e59..2c7ec6dd 100644 --- a/src/include/access/pg_tde_tdemap.h +++ b/src/include/access/pg_tde_tdemap.h @@ -8,6 +8,7 @@ #ifndef PG_TDE_MAP_H #define PG_TDE_MAP_H +#include "pg_tde.h" #include "utils/rel.h" #include "access/xlog_internal.h" #include "catalog/pg_tablespace_d.h" @@ -62,9 +63,9 @@ extern RelKeyData *GetSMGRRelationKey(RelFileLocator rel); extern RelKeyData *GetHeapBaiscRelationKey(RelFileLocator rel); extern RelKeyData *GetTdeGlobaleRelationKey(RelFileLocator rel); -extern void pg_tde_delete_tde_files(Oid dbOid, Oid spcOid); +extern void pg_tde_delete_tde_files(Oid dbOid); -extern TDEPrincipalKeyInfo *pg_tde_get_principal_key_info(Oid dbOid, Oid spcOid); +extern TDEPrincipalKeyInfo *pg_tde_get_principal_key_info(Oid dbOid); extern bool pg_tde_save_principal_key(TDEPrincipalKeyInfo *principal_key_info); extern bool pg_tde_perform_rotate_key(TDEPrincipalKey *principal_key, TDEPrincipalKey *new_principal_key); extern bool pg_tde_write_map_keydata_files(off_t map_size, char *m_file_data, off_t keydata_size, char *k_file_data); @@ -74,7 +75,17 @@ extern RelKeyData *tde_decrypt_rel_key(TDEPrincipalKey *principal_key, RelKeyDat extern RelKeyData *pg_tde_get_key_from_file(const RelFileLocator *rlocator, uint32 key_type, bool no_map_ok); extern bool pg_tde_move_rel_key(const RelFileLocator *newrlocator, const RelFileLocator *oldrlocator); -extern void pg_tde_set_db_file_paths(Oid dbOid, Oid spcOid, char *map_path, char *keydata_path); +#define PG_TDE_MAP_FILENAME "pg_tde_%d_map" +#define PG_TDE_KEYDATA_FILENAME "pg_tde_%d_dat" + +static inline void +pg_tde_set_db_file_paths(Oid dbOid, char *map_path, char *keydata_path) +{ + if (map_path) + join_path_components(map_path, PG_TDE_DATA_DIR, psprintf(PG_TDE_MAP_FILENAME, dbOid)); + if (keydata_path) + join_path_components(keydata_path, PG_TDE_DATA_DIR, psprintf(PG_TDE_KEYDATA_FILENAME, dbOid)); +} const char *tde_sprint_key(InternalKey *k); diff --git a/src/include/catalog/tde_global_space.h b/src/include/catalog/tde_global_space.h index 78474960..cca493a1 100644 --- a/src/include/catalog/tde_global_space.h +++ b/src/include/catalog/tde_global_space.h @@ -24,8 +24,6 @@ #define GLOBAL_DATA_TDE_OID InvalidOid #define XLOG_TDE_OID 608 -#define GLOBAL_DATA_TDE_OID InvalidOid - #define GLOBAL_SPACE_RLOCATOR(_obj_oid) (RelFileLocator) { \ GLOBALTABLESPACE_OID, \ GLOBAL_DATA_TDE_OID, \ diff --git a/src/include/catalog/tde_keyring.h b/src/include/catalog/tde_keyring.h index 7a9337da..943be4cc 100644 --- a/src/include/catalog/tde_keyring.h +++ b/src/include/catalog/tde_keyring.h @@ -68,23 +68,19 @@ typedef struct KeyringProvideRecord typedef struct KeyringProviderXLRecord { Oid database_id; - Oid tablespace_id; off_t offset_in_file; KeyringProvideRecord provider; } KeyringProviderXLRecord; -extern List *GetAllKeyringProviders(Oid dbOid, Oid spcOid); -extern GenericKeyring *GetKeyProviderByName(const char *provider_name, Oid dbOid, Oid spcOid); -extern GenericKeyring *GetKeyProviderByID(int provider_id, Oid dbOid, Oid spcOid); +extern List *GetAllKeyringProviders(Oid dbOid); +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 cleanup_key_provider_info(Oid databaseId, Oid tablespaceId); +extern void cleanup_key_provider_info(Oid databaseId); extern void InitializeKeyProviderInfo(void); extern uint32 save_new_key_provider_info(KeyringProvideRecord *provider, Oid databaseId, Oid tablespaceId, bool write_xlog); -extern uint32 copy_key_provider_info(KeyringProvideRecord* provider, - Oid newdatabaseId, Oid newtablespaceId, - bool write_xlog); extern uint32 redo_key_provider_info(KeyringProviderXLRecord *xlrec); extern bool ParseKeyringJSONOptions(ProviderType provider_type, void *out_opts, diff --git a/src/include/catalog/tde_principal_key.h b/src/include/catalog/tde_principal_key.h index 26dc1a11..50828d0f 100644 --- a/src/include/catalog/tde_principal_key.h +++ b/src/include/catalog/tde_principal_key.h @@ -58,7 +58,7 @@ typedef struct XLogPrincipalKeyRotate #define SizeoOfXLogPrincipalKeyRotate offsetof(XLogPrincipalKeyRotate, buff) extern void InitializePrincipalKeyInfo(void); -extern void cleanup_principal_key_info(Oid databaseId, Oid tablespaceId); +extern void cleanup_principal_key_info(Oid databaseId); #ifndef FRONTEND extern LWLock *tde_lwlock_enc_keys(void); diff --git a/src/include/common/pg_tde_utils.h b/src/include/common/pg_tde_utils.h index b49c409e..d94fd3da 100644 --- a/src/include/common/pg_tde_utils.h +++ b/src/include/common/pg_tde_utils.h @@ -19,6 +19,5 @@ extern List *get_all_tde_tables(void); extern int get_tde_tables_count(void); #endif /* !FRONTEND */ -extern char *pg_tde_get_tde_file_dir(Oid dbOid, Oid spcOid); extern void pg_tde_set_globalspace_dir(const char *dir); #endif /* PG_TDE_UTILS_H */ diff --git a/src/include/pg_tde.h b/src/include/pg_tde.h index c9c38727..3c579cff 100644 --- a/src/include/pg_tde.h +++ b/src/include/pg_tde.h @@ -8,6 +8,8 @@ #ifndef PG_TDE_H #define PG_TDE_H +#define PG_TDE_DATA_DIR "pg_tde" + typedef struct XLogExtensionInstall { Oid database_id; @@ -19,4 +21,6 @@ typedef void (*pg_tde_on_ext_install_callback) (int tde_tbl_count, XLogExtension extern void on_ext_install(pg_tde_on_ext_install_callback function, void *arg); extern void extension_install_redo(XLogExtensionInstall *xlrec); + +extern void pg_tde_init_data_dir(void); #endif /* PG_TDE_H */ diff --git a/src/pg_tde.c b/src/pg_tde.c index 2e21c1c6..8f4c54c7 100644 --- a/src/pg_tde.c +++ b/src/pg_tde.c @@ -39,6 +39,8 @@ #include "utils/percona.h" #endif +#include + #define MAX_ON_INSTALLS 5 PG_MODULE_MAGIC; @@ -130,6 +132,8 @@ _PG_init(void) Datum pg_tde_extension_initialize(PG_FUNCTION_ARGS) { + pg_tde_init_data_dir(); + /* Initialize the TDE map */ XLogExtensionInstall xlrec; @@ -174,6 +178,22 @@ on_ext_install(pg_tde_on_ext_install_callback function, void *arg) ++on_ext_install_index; } +/* Creates a tde directory for internal files if not exists */ +void +pg_tde_init_data_dir(void) +{ + struct stat st; + + if (stat(PG_TDE_DATA_DIR, &st) < 0) + { + if (MakePGDirectory(PG_TDE_DATA_DIR) < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not create tde directory \"%s\": %m", + PG_TDE_DATA_DIR))); + } +} + /* ------------------ * Run all of the on_ext_install routines and execute those one by one * ------------------