Move SMGR specific logic out of the TDE map code

Especially all code realted to the keys of temporary tables did not
belong in the TDE map code and fit better in the SMGR code.

Additionally we speed up pg_tde_is_encrypted() by relying on the SMGR to
cache the relations. This might in some cases lead to blow up of the
SMGR relation cache if you query every relation in the database but
given the small size I am not overly worried.
pull/230/head
Andreas Karlsson 4 months ago committed by Andreas Karlsson
parent 5fd8d16df3
commit 9618f6934b
  1. 212
      contrib/pg_tde/src/access/pg_tde_tdemap.c
  2. 3
      contrib/pg_tde/src/access/pg_tde_xlog.c
  3. 6
      contrib/pg_tde/src/common/pg_tde_utils.c
  4. 25
      contrib/pg_tde/src/encryption/enc_tde.c
  5. 9
      contrib/pg_tde/src/include/access/pg_tde_tdemap.h
  6. 1
      contrib/pg_tde/src/include/encryption/enc_tde.h
  7. 5
      contrib/pg_tde/src/include/smgr/pg_tde_smgr.h
  8. 172
      contrib/pg_tde/src/smgr/pg_tde_smgr.c
  9. 5
      src/bin/pg_checksums/pg_checksums.c

@ -20,7 +20,6 @@
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "utils/builtins.h"
#include "utils/hsearch.h"
#include "miscadmin.h"
#include "access/pg_tde_tdemap.h"
@ -28,6 +27,7 @@
#include "catalog/tde_global_space.h"
#include "catalog/tde_principal_key.h"
#include "encryption/enc_aes.h"
#include "encryption/enc_tde.h"
#include "keyring/keyring_api.h"
#include <openssl/rand.h>
@ -66,24 +66,6 @@ typedef struct TDEFileHeader
TDESignedPrincipalKeyInfo signed_key_info;
} TDEFileHeader;
typedef struct
{
RelFileLocator rel;
InternalKey key;
} TempRelKeyEntry;
#ifndef FRONTEND
/* Arbitrarily picked small number of temporary relations */
#define INIT_TEMP_RELS 16
/*
* Each backend has a hashtable that stores the keys for all temporary tables.
*/
static HTAB *TempRelKeys = NULL;
#endif
static WALKeyCacheRec *tde_wal_key_cache = NULL;
static WALKeyCacheRec *tde_wal_key_last_rec = NULL;
@ -98,72 +80,25 @@ static int pg_tde_open_file_read(const char *tde_filename, bool ignore_missing,
static WALKeyCacheRec *pg_tde_add_wal_key_to_cache(InternalKey *cached_key, XLogRecPtr start_lsn);
#ifndef FRONTEND
static InternalKey *pg_tde_create_smgr_key_temp(const RelFileLocator *newrlocator);
static InternalKey *pg_tde_create_smgr_key_perm(const RelFileLocator *newrlocator);
static void pg_tde_generate_internal_key(InternalKey *int_key, TDEMapEntryType entry_type);
static int pg_tde_file_header_write(const char *tde_filename, int fd, const TDESignedPrincipalKeyInfo *signed_key_info, off_t *bytes_written);
static void pg_tde_sign_principal_key_info(TDESignedPrincipalKeyInfo *signed_key_info, const TDEPrincipalKey *principal_key);
static void pg_tde_write_one_map_entry(int fd, const TDEMapEntry *map_entry, off_t *offset, const char *db_map_path);
static void pg_tde_write_key_map_entry(const RelFileLocator *rlocator, InternalKey *rel_key_data, TDEPrincipalKey *principal_key);
static void pg_tde_free_key_map_entry(const RelFileLocator *rlocator);
static void pg_tde_write_key_map_entry(const RelFileLocator *rlocator, const InternalKey *rel_key_data, TDEPrincipalKey *principal_key);
static int keyrotation_init_file(const TDESignedPrincipalKeyInfo *signed_key_info, char *rotated_filename, const char *filename, off_t *curr_pos);
static void finalize_key_rotation(const char *path_old, const char *path_new);
static int pg_tde_open_file_write(const char *tde_filename, const TDESignedPrincipalKeyInfo *signed_key_info, bool truncate, off_t *curr_pos);
InternalKey *
pg_tde_create_smgr_key(const RelFileLocatorBackend *newrlocator)
{
if (RelFileLocatorBackendIsTemp(*newrlocator))
return pg_tde_create_smgr_key_temp(&newrlocator->locator);
else
return pg_tde_create_smgr_key_perm(&newrlocator->locator);
}
static InternalKey *
pg_tde_create_smgr_key_temp(const RelFileLocator *newrlocator)
{
InternalKey *rel_key_data = palloc_object(InternalKey);
TempRelKeyEntry *entry;
bool found;
pg_tde_generate_internal_key(rel_key_data, TDE_KEY_TYPE_SMGR);
if (TempRelKeys == NULL)
{
HASHCTL ctl;
ctl.keysize = sizeof(RelFileLocator);
ctl.entrysize = sizeof(TempRelKeyEntry);
TempRelKeys = hash_create("pg_tde temporary relation keys",
INIT_TEMP_RELS,
&ctl,
HASH_ELEM | HASH_BLOBS);
}
entry = (TempRelKeyEntry *) hash_search(TempRelKeys,
newrlocator,
HASH_ENTER, &found);
Assert(!found);
entry->key = *rel_key_data;
return rel_key_data;
}
static InternalKey *
pg_tde_create_smgr_key_perm(const RelFileLocator *newrlocator)
void
pg_tde_save_smgr_key(RelFileLocator rel, const InternalKey *rel_key_data, bool write_xlog)
{
InternalKey *rel_key_data = palloc_object(InternalKey);
TDEPrincipalKey *principal_key;
LWLock *lock_pk = tde_lwlock_enc_keys();
XLogRelKey xlrec = {
.rlocator = *newrlocator,
.rlocator = rel,
};
pg_tde_generate_internal_key(rel_key_data, TDE_KEY_TYPE_SMGR);
LWLockAcquire(lock_pk, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(newrlocator->dbOid, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(rel.dbOid, LW_EXCLUSIVE);
if (principal_key == NULL)
{
ereport(ERROR,
@ -171,65 +106,19 @@ pg_tde_create_smgr_key_perm(const RelFileLocator *newrlocator)
errhint("create one using pg_tde_set_key before using encrypted tables"));
}
pg_tde_write_key_map_entry(newrlocator, rel_key_data, principal_key);
pg_tde_write_key_map_entry(&rel, rel_key_data, principal_key);
LWLockRelease(lock_pk);
/*
* It is fine to write the to WAL after writing to the file since we have
* not WAL logged the SMGR CREATE event either.
*/
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, sizeof(xlrec));
XLogInsert(RM_TDERMGR_ID, XLOG_TDE_ADD_RELATION_KEY);
return rel_key_data;
}
void
pg_tde_create_smgr_key_perm_redo(const RelFileLocator *newrlocator)
{
InternalKey rel_key_data;
InternalKey *old_key;
TDEPrincipalKey *principal_key;
LWLock *lock_pk = tde_lwlock_enc_keys();
if ((old_key = pg_tde_get_key_from_file(newrlocator, TDE_KEY_TYPE_SMGR)))
{
pfree(old_key);
return;
}
pg_tde_generate_internal_key(&rel_key_data, TDE_KEY_TYPE_SMGR);
LWLockAcquire(lock_pk, LW_EXCLUSIVE);
principal_key = GetPrincipalKey(newrlocator->dbOid, LW_EXCLUSIVE);
if (principal_key == NULL)
if (write_xlog)
{
ereport(ERROR,
errmsg("principal key not configured"),
errhint("create one using pg_tde_set_key before using encrypted tables"));
/*
* It is fine to write the to WAL after writing to the file since we
* have not WAL logged the SMGR CREATE event either.
*/
XLogBeginInsert();
XLogRegisterData((char *) &xlrec, sizeof(xlrec));
XLogInsert(RM_TDERMGR_ID, XLOG_TDE_ADD_RELATION_KEY);
}
pg_tde_write_key_map_entry(newrlocator, &rel_key_data, principal_key);
LWLockRelease(lock_pk);
}
static void
pg_tde_generate_internal_key(InternalKey *int_key, TDEMapEntryType entry_type)
{
int_key->type = entry_type;
int_key->start_lsn = InvalidXLogRecPtr;
if (!RAND_bytes(int_key->key, INTERNAL_KEY_LEN))
ereport(ERROR,
errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate internal key: %s",
ERR_error_string(ERR_get_error(), NULL)));
if (!RAND_bytes(int_key->base_iv, INTERNAL_KEY_IV_LEN))
ereport(ERROR,
errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate IV: %s",
ERR_error_string(ERR_get_error(), NULL)));
}
const char *
@ -275,18 +164,6 @@ pg_tde_create_wal_key(InternalKey *rel_key_data, const RelFileLocator *newrlocat
LWLockRelease(tde_lwlock_enc_keys());
}
void
DeleteSMGRRelationKey(RelFileLocatorBackend rel)
{
if (RelFileLocatorBackendIsTemp(rel))
{
Assert(TempRelKeys);
hash_search(TempRelKeys, &rel.locator, HASH_REMOVE, NULL);
}
else
pg_tde_free_key_map_entry(&rel.locator);
}
/*
* Deletes the key map file for a given database.
*/
@ -463,7 +340,7 @@ pg_tde_write_one_map_entry(int fd, const TDEMapEntry *map_entry, off_t *offset,
* concurrent in place updates leading to data conflicts.
*/
void
pg_tde_write_key_map_entry(const RelFileLocator *rlocator, InternalKey *rel_key_data, TDEPrincipalKey *principal_key)
pg_tde_write_key_map_entry(const RelFileLocator *rlocator, const InternalKey *rel_key_data, TDEPrincipalKey *principal_key)
{
char db_map_path[MAXPGPATH];
int map_fd;
@ -518,16 +395,14 @@ pg_tde_write_key_map_entry(const RelFileLocator *rlocator, InternalKey *rel_key_
* This fucntion is called by the pg_tde SMGR when storage is unlinked on
* transaction commit/abort.
*/
static void
pg_tde_free_key_map_entry(const RelFileLocator *rlocator)
void
pg_tde_free_key_map_entry(const RelFileLocator rlocator)
{
char db_map_path[MAXPGPATH];
File map_fd;
off_t curr_pos = 0;
Assert(rlocator);
pg_tde_set_db_file_path(rlocator->dbOid, db_map_path);
pg_tde_set_db_file_path(rlocator.dbOid, db_map_path);
LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE);
@ -542,7 +417,7 @@ pg_tde_free_key_map_entry(const RelFileLocator *rlocator)
if (!pg_tde_read_one_map_entry(map_fd, &map_entry, &curr_pos))
break;
if (map_entry.type != MAP_ENTRY_EMPTY && map_entry.spcOid == rlocator->spcOid && map_entry.relNumber == rlocator->relNumber)
if (map_entry.type != MAP_ENTRY_EMPTY && map_entry.spcOid == rlocator.spcOid && map_entry.relNumber == rlocator.relNumber)
{
TDEMapEntry empty_map_entry = {
.type = MAP_ENTRY_EMPTY,
@ -1084,57 +959,27 @@ pg_tde_get_principal_key_info(Oid dbOid)
return signed_key_info;
}
static InternalKey *
pg_tde_get_temporary_rel_key(const RelFileLocator *rel)
{
#ifndef FRONTEND
TempRelKeyEntry *entry;
if (TempRelKeys == NULL)
return NULL;
entry = hash_search(TempRelKeys, rel, HASH_FIND, NULL);
if (entry)
{
InternalKey *key = palloc_object(InternalKey);
*key = entry->key;
return key;
}
#endif
return NULL;
}
/*
* Figures out whether a relation is encrypted or not, but without trying to
* decrypt the key if it is.
*/
bool
IsSMGRRelationEncrypted(RelFileLocatorBackend rel)
pg_tde_has_smgr_key(RelFileLocator rel)
{
bool result;
TDEMapEntry map_entry;
char db_map_path[MAXPGPATH];
Assert(rel.locator.relNumber != InvalidRelFileNumber);
if (RelFileLocatorBackendIsTemp(rel))
#ifndef FRONTEND
return TempRelKeys && hash_search(TempRelKeys, &rel.locator, HASH_FIND, NULL);
#else
return false;
#endif
Assert(rel.relNumber != InvalidRelFileNumber);
pg_tde_set_db_file_path(rel.locator.dbOid, db_map_path);
pg_tde_set_db_file_path(rel.dbOid, db_map_path);
if (access(db_map_path, F_OK) == -1)
return false;
LWLockAcquire(tde_lwlock_enc_keys(), LW_SHARED);
result = pg_tde_find_map_entry(&rel.locator, TDE_KEY_TYPE_SMGR, db_map_path, &map_entry);
result = pg_tde_find_map_entry(&rel, TDE_KEY_TYPE_SMGR, db_map_path, &map_entry);
LWLockRelease(tde_lwlock_enc_keys());
return result;
@ -1144,14 +989,11 @@ IsSMGRRelationEncrypted(RelFileLocatorBackend rel)
* Returns TDE key for a given relation.
*/
InternalKey *
GetSMGRRelationKey(RelFileLocatorBackend rel)
pg_tde_get_smgr_key(RelFileLocator rel)
{
Assert(rel.locator.relNumber != InvalidRelFileNumber);
Assert(rel.relNumber != InvalidRelFileNumber);
if (RelFileLocatorBackendIsTemp(rel))
return pg_tde_get_temporary_rel_key(&rel.locator);
else
return pg_tde_get_key_from_file(&rel.locator, TDE_KEY_TYPE_SMGR);
return pg_tde_get_key_from_file(&rel, TDE_KEY_TYPE_SMGR);
}
/*

@ -25,6 +25,7 @@
#include "access/pg_tde_xlog.h"
#include "encryption/enc_tde.h"
#include "smgr/pg_tde_smgr.h"
static void tdeheap_rmgr_redo(XLogReaderState *record);
static void tdeheap_rmgr_desc(StringInfo buf, XLogReaderState *record);
@ -52,7 +53,7 @@ tdeheap_rmgr_redo(XLogReaderState *record)
{
XLogRelKey *xlrec = (XLogRelKey *) XLogRecGetData(record);
pg_tde_create_smgr_key_perm_redo(&xlrec->rlocator);
tde_smgr_create_key_redo(&xlrec->rlocator);
}
else if (info == XLOG_TDE_ADD_PRINCIPAL_KEY)
{

@ -16,8 +16,7 @@
#ifndef FRONTEND
#include "fmgr.h"
#include "catalog/pg_class.h"
#include "access/pg_tde_tdemap.h"
#include "smgr/pg_tde_smgr.h"
#include "access/relation.h"
#include "utils/rel.h"
@ -28,7 +27,6 @@ pg_tde_is_encrypted(PG_FUNCTION_ARGS)
Oid relationOid = PG_GETARG_OID(0);
LOCKMODE lockmode = AccessShareLock;
Relation rel = relation_open(relationOid, lockmode);
RelFileLocatorBackend rlocator = {.locator = rel->rd_locator,.backend = rel->rd_backend};
bool result;
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
@ -42,7 +40,7 @@ pg_tde_is_encrypted(PG_FUNCTION_ARGS)
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("we cannot check if temporary relations from other backends are encrypted"));
result = IsSMGRRelationEncrypted(rlocator);
result = tde_smgr_rel_is_encrypted(RelationGetSmgr(rel));
relation_close(rel, lockmode);

@ -7,6 +7,13 @@
#include "encryption/enc_aes.h"
#include "storage/bufmgr.h"
#ifdef FRONTEND
#include "pg_tde_fe.h"
#endif
#include <openssl/rand.h>
#include <openssl/err.h>
#define AES_BLOCK_SIZE 16
#define NUM_AES_BLOCKS_IN_BATCH 200
#define DATA_BYTES_PER_AES_BATCH (NUM_AES_BLOCKS_IN_BATCH * AES_BLOCK_SIZE)
@ -23,6 +30,24 @@ iv_prefix_debug(const char *iv_prefix, char *out_hex)
}
#endif
void
pg_tde_generate_internal_key(InternalKey *int_key, TDEMapEntryType entry_type)
{
int_key->type = entry_type;
int_key->start_lsn = InvalidXLogRecPtr;
if (!RAND_bytes(int_key->key, INTERNAL_KEY_LEN))
ereport(ERROR,
errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate internal key: %s",
ERR_error_string(ERR_get_error(), NULL)));
if (!RAND_bytes(int_key->base_iv, INTERNAL_KEY_IV_LEN))
ereport(ERROR,
errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate IV: %s",
ERR_error_string(ERR_get_error(), NULL)));
}
/*
* Encrypts/decrypts `data` with a given `key`. The result is written to `out`.
*

@ -83,8 +83,6 @@ extern WALKeyCacheRec *pg_tde_fetch_wal_keys(XLogRecPtr start_lsn);
extern WALKeyCacheRec *pg_tde_get_wal_cache_keys(void);
extern void pg_tde_wal_last_key_set_lsn(XLogRecPtr lsn, const char *keyfile_path);
extern InternalKey *pg_tde_create_smgr_key(const RelFileLocatorBackend *newrlocator);
extern void pg_tde_create_smgr_key_perm_redo(const RelFileLocator *newrlocator);
extern void pg_tde_create_wal_key(InternalKey *rel_key_data, const RelFileLocator *newrlocator, TDEMapEntryType flags);
#define PG_TDE_MAP_FILENAME "%d_keys"
@ -95,9 +93,10 @@ pg_tde_set_db_file_path(Oid dbOid, char *path)
join_path_components(path, pg_tde_get_data_dir(), psprintf(PG_TDE_MAP_FILENAME, dbOid));
}
extern bool IsSMGRRelationEncrypted(RelFileLocatorBackend rel);
extern InternalKey *GetSMGRRelationKey(RelFileLocatorBackend rel);
extern void DeleteSMGRRelationKey(RelFileLocatorBackend rel);
extern void pg_tde_save_smgr_key(RelFileLocator rel, const InternalKey *key, bool write_xlog);
extern bool pg_tde_has_smgr_key(RelFileLocator rel);
extern InternalKey *pg_tde_get_smgr_key(RelFileLocator rel);
extern void pg_tde_free_key_map_entry(RelFileLocator rel);
extern int pg_tde_count_relations(Oid dbOid);

@ -12,6 +12,7 @@
#include "access/pg_tde_tdemap.h"
extern void pg_tde_generate_internal_key(InternalKey *int_key, TDEMapEntryType entry_type);
extern void pg_tde_stream_crypt(const char *iv_prefix, uint32 start_offset, const char *data, uint32 data_len, char *out, InternalKey *key, void **ctxPtr);
#endif /* ENC_TDE_H */

@ -9,6 +9,11 @@
#ifndef PG_TDE_SMGR_H
#define PG_TDE_SMGR_H
#include "storage/relfilelocator.h"
#include "storage/smgr.h"
extern void RegisterStorageMgr(void);
extern void tde_smgr_create_key_redo(const RelFileLocator *rlocator);
extern bool tde_smgr_rel_is_encrypted(SMgrRelation reln);
#endif /* PG_TDE_SMGR_H */

@ -1,10 +1,13 @@
#include "smgr/pg_tde_smgr.h"
#include "postgres.h"
#include "smgr/pg_tde_smgr.h"
#include "storage/smgr.h"
#include "storage/md.h"
#include "catalog/catalog.h"
#include "encryption/enc_aes.h"
#include "encryption/enc_tde.h"
#include "access/pg_tde_tdemap.h"
#include "utils/hsearch.h"
#include "pg_tde_event_capture.h"
typedef enum TDEMgrRelationEncryptionStatus
@ -43,8 +46,82 @@ typedef struct TDESMgrRelation
InternalKey relKey;
} TDESMgrRelation;
typedef struct
{
RelFileLocator rel;
InternalKey key;
} TempRelKeyEntry;
#define INIT_TEMP_RELS 16
/*
* Each backend has a hashtable that stores the keys for all temproary tables.
*/
static HTAB *TempRelKeys = NULL;
static SMgrId OurSMgrId = MaxSMgrId;
static void tde_smgr_save_temp_key(const RelFileLocator *newrlocator, const InternalKey *key);
static InternalKey *tde_smgr_get_temp_key(const RelFileLocator *rel);
static bool tde_smgr_has_temp_key(const RelFileLocator *rel);
static void tde_smgr_remove_temp_key(const RelFileLocator *rel);
static void CalcBlockIv(ForkNumber forknum, BlockNumber bn, const unsigned char *base_iv, unsigned char *iv);
static InternalKey *
tde_smgr_create_key(const RelFileLocatorBackend *smgr_rlocator)
{
InternalKey *key = palloc_object(InternalKey);
pg_tde_generate_internal_key(key, TDE_KEY_TYPE_SMGR);
if (RelFileLocatorBackendIsTemp(*smgr_rlocator))
tde_smgr_save_temp_key(&smgr_rlocator->locator, key);
else
pg_tde_save_smgr_key(smgr_rlocator->locator, key, true);
return key;
}
void
tde_smgr_create_key_redo(const RelFileLocator *rlocator)
{
InternalKey key;
if (pg_tde_has_smgr_key(*rlocator))
return;
pg_tde_generate_internal_key(&key, TDE_KEY_TYPE_SMGR);
pg_tde_save_smgr_key(*rlocator, &key, false);
}
static bool
tde_smgr_is_encrypted(const RelFileLocatorBackend *smgr_rlocator)
{
if (RelFileLocatorBackendIsTemp(*smgr_rlocator))
return tde_smgr_has_temp_key(&smgr_rlocator->locator);
else
return pg_tde_has_smgr_key(smgr_rlocator->locator);
}
static InternalKey *
tde_smgr_get_key(const RelFileLocatorBackend *smgr_rlocator)
{
if (RelFileLocatorBackendIsTemp(*smgr_rlocator))
return tde_smgr_get_temp_key(&smgr_rlocator->locator);
else
return pg_tde_get_smgr_key(smgr_rlocator->locator);
}
static void
tde_smgr_remove_key(const RelFileLocatorBackend *smgr_rlocator)
{
if (RelFileLocatorBackendIsTemp(*smgr_rlocator))
tde_smgr_remove_temp_key(&smgr_rlocator->locator);
else
pg_tde_free_key_map_entry(smgr_rlocator->locator);
}
static bool
tde_smgr_should_encrypt(const RelFileLocatorBackend *smgr_rlocator, RelFileLocator *old_locator)
{
@ -66,13 +143,25 @@ tde_smgr_should_encrypt(const RelFileLocatorBackend *smgr_rlocator, RelFileLocat
.backend = smgr_rlocator->backend,
};
return IsSMGRRelationEncrypted(old_smgr_locator);
return tde_smgr_is_encrypted(&old_smgr_locator);
}
}
return false;
}
bool
tde_smgr_rel_is_encrypted(SMgrRelation reln)
{
TDESMgrRelation *tdereln = (TDESMgrRelation *) reln;
if (reln->smgr_which != OurSMgrId)
return false;
return tdereln->encryption_status == RELATION_KEY_AVAILABLE ||
tdereln->encryption_status == RELATION_KEY_NOT_AVAILABLE;
}
static void
tde_mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
const void **buffers, BlockNumber nblocks, bool skipFsync)
@ -90,7 +179,7 @@ tde_mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
if (tdereln->encryption_status == RELATION_KEY_NOT_AVAILABLE)
{
InternalKey *int_key = GetSMGRRelationKey(reln->smgr_rlocator);
InternalKey *int_key = tde_smgr_get_key(&reln->smgr_rlocator);
tdereln->relKey = *int_key;
tdereln->encryption_status = RELATION_KEY_AVAILABLE;
@ -139,8 +228,8 @@ tde_mdunlink(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
*/
if (forknum == MAIN_FORKNUM || forknum == InvalidForkNumber)
{
if (IsSMGRRelationEncrypted(rlocator))
DeleteSMGRRelationKey(rlocator);
if (tde_smgr_is_encrypted(&rlocator))
tde_smgr_remove_key(&rlocator);
}
}
@ -161,7 +250,7 @@ tde_mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
if (tdereln->encryption_status == RELATION_KEY_NOT_AVAILABLE)
{
InternalKey *int_key = GetSMGRRelationKey(reln->smgr_rlocator);
InternalKey *int_key = tde_smgr_get_key(&reln->smgr_rlocator);
tdereln->relKey = *int_key;
tdereln->encryption_status = RELATION_KEY_AVAILABLE;
@ -190,7 +279,7 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
return;
else if (tdereln->encryption_status == RELATION_KEY_NOT_AVAILABLE)
{
InternalKey *int_key = GetSMGRRelationKey(reln->smgr_rlocator);
InternalKey *int_key = tde_smgr_get_key(&reln->smgr_rlocator);
tdereln->relKey = *int_key;
tdereln->encryption_status = RELATION_KEY_AVAILABLE;
@ -259,10 +348,10 @@ tde_mdcreate(RelFileLocator relold, SMgrRelation reln, ForkNumber forknum, bool
* Since event triggers do not fire on the standby or in recovery we
* do not try to generate any new keys and instead trust the xlog.
*/
InternalKey *key = GetSMGRRelationKey(reln->smgr_rlocator);
InternalKey *key = tde_smgr_get_key(&reln->smgr_rlocator);
if (!isRedo && !key && tde_smgr_should_encrypt(&reln->smgr_rlocator, &relold))
key = pg_tde_create_smgr_key(&reln->smgr_rlocator);
key = tde_smgr_create_key(&reln->smgr_rlocator);
if (key)
{
@ -291,7 +380,7 @@ tde_mdopen(SMgrRelation reln)
mdopen(reln);
if (IsSMGRRelationEncrypted(reln->smgr_rlocator))
if (tde_smgr_is_encrypted(&reln->smgr_rlocator))
{
tdereln->encryption_status = RELATION_KEY_NOT_AVAILABLE;
}
@ -327,7 +416,68 @@ RegisterStorageMgr(void)
{
if (storage_manager_id != MdSMgrId)
elog(FATAL, "Another storage manager was loaded before pg_tde. Multiple storage managers is unsupported.");
storage_manager_id = smgr_register(&tde_smgr, sizeof(TDESMgrRelation));
OurSMgrId = smgr_register(&tde_smgr, sizeof(TDESMgrRelation));
storage_manager_id = OurSMgrId;
}
static void
tde_smgr_save_temp_key(const RelFileLocator *newrlocator, const InternalKey *key)
{
TempRelKeyEntry *entry;
bool found;
if (TempRelKeys == NULL)
{
HASHCTL ctl;
ctl.keysize = sizeof(RelFileLocator);
ctl.entrysize = sizeof(TempRelKeyEntry);
TempRelKeys = hash_create("pg_tde temporary relation keys",
INIT_TEMP_RELS,
&ctl,
HASH_ELEM | HASH_BLOBS);
}
entry = (TempRelKeyEntry *) hash_search(TempRelKeys,
newrlocator,
HASH_ENTER, &found);
Assert(!found);
entry->key = *key;
}
static InternalKey *
tde_smgr_get_temp_key(const RelFileLocator *rel)
{
TempRelKeyEntry *entry;
if (TempRelKeys == NULL)
return NULL;
entry = hash_search(TempRelKeys, rel, HASH_FIND, NULL);
if (entry)
{
InternalKey *key = palloc_object(InternalKey);
*key = entry->key;
return key;
}
return NULL;
}
static bool
tde_smgr_has_temp_key(const RelFileLocator *rel)
{
return TempRelKeys && hash_search(TempRelKeys, rel, HASH_FIND, NULL);
}
static void
tde_smgr_remove_temp_key(const RelFileLocator *rel)
{
Assert(TempRelKeys);
hash_search(TempRelKeys, rel, HASH_REMOVE, NULL);
}
/*

@ -138,10 +138,9 @@ pg_tde_init(const char *datadir)
static bool
is_pg_tde_encypted(Oid spcOid, Oid dbOid, RelFileNumber relNumber)
{
RelFileLocator locator = {.spcOid = spcOid, .dbOid = dbOid,.relNumber = relNumber};
RelFileLocatorBackend rlocator = {.locator = locator,.backend = INVALID_PROC_NUMBER};
RelFileLocator locator = {.spcOid = spcOid,.dbOid = dbOid,.relNumber = relNumber};
return IsSMGRRelationEncrypted(rlocator);
return pg_tde_has_smgr_key(locator);
}
#endif

Loading…
Cancel
Save