Skip to content

Commit

Permalink
An Interface for Informing the Shared Memory Manager about Lock Requi…
Browse files Browse the repository at this point in the history
…rements

This commit addresses PostgreSQL core's requirement for upfront information
regarding the number of locks needed by the extension. Given the connection
between locks and the shared memory interface, a new callback routine
is introduced. This routine allows modules to specify
the number of locks they require.

In addition to this functionality, the commit includes code cleanups
and adjustments to nomenclature for improved clarity and consistency.
  • Loading branch information
codeforall committed Feb 15, 2024
1 parent 3cd5235 commit 680b10a
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 101 deletions.
4 changes: 2 additions & 2 deletions src/access/pg_tde_tdemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pg_tde_add_rel_keys(const RelFileLocator *rlocator, InternalKey *key, InternalKe
* the cache as well */
data = (RelKeysData *) MemoryContextAlloc(TopMemoryContext, SizeOfRelKeysData(1));

strncpy(data->master_key_name, masterkeyname, MASTER_KEY_NAME_LEN);
strncpy(data->master_key_name, masterkeyname, TDE_KEY_NAME_LEN);
data->internal_key[0] = *key;
data->internal_keys_len = 1;

Expand Down Expand Up @@ -392,7 +392,7 @@ pg_tde_xlog_create_fork(XLogReaderState *record)
InternalKey int_key = {0};
InternalKey int_key_enc = {0};
uint8 mkey_len;
char mkey_name[MASTER_KEY_NAME_LEN];
char mkey_name[TDE_KEY_NAME_LEN];

if (XLogRecGetDataLen(record) < sizeof(InternalKey)+sizeof(RelFileLocator))
{
Expand Down
54 changes: 25 additions & 29 deletions src/catalog/tde_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
#define PG_TDE_KEY_PROVIDER_NAME_ATTRNUM 3
#define PG_TDE_KEY_PROVIDER_OPTIONS_ATTRNUM 4

/* JSON keys for option field */
#define VALUTV2_KEYRING_TOKEN_KEY "token"
#define VALUTV2_KEYRING_URL_KEY "url"
#define VALUTV2_KEYRING_MOUNT_PATH_KEY "mountPath"
#define VALUTV2_KEYRING_CA_PATH_KEY "caPath"

#define FILE_KEYRING_PATH_KEY "path"
#define FILE_KEYRING_TYPE_KEY "type"


static FileKeyring* load_file_keyring_provider_options(Datum keyring_options);
static ProviderType get_keyring_provider_from_typename(char *provider_type);
static GenericKeyring* load_keyring_provider_options(ProviderType provider_type, Datum keyring_options);
Expand All @@ -53,10 +63,10 @@ static GenericKeyring*
load_keyring_provider_from_tuple(HeapTuple tuple, TupleDesc tupDesc)
{
Datum datum;
Datum options_datum;
bool isnull;
char *keyring_name;
char *keyring_type;
char *keyring_options = NULL;
int provider_id;
ProviderType provider_type = UNKNOWN_KEY_PROVIDER;
GenericKeyring *keyring = NULL;
Expand All @@ -70,12 +80,12 @@ load_keyring_provider_from_tuple(HeapTuple tuple, TupleDesc tupDesc)
datum = heap_getattr(tuple, PG_TDE_KEY_PROVIDER_NAME_ATTRNUM, tupDesc, &isnull);
keyring_name = TextDatumGetCString(datum);

datum = heap_getattr(tuple, PG_TDE_KEY_PROVIDER_OPTIONS_ATTRNUM, tupDesc, &isnull);
keyring_options = TextDatumGetCString(datum);
options_datum = heap_getattr(tuple, PG_TDE_KEY_PROVIDER_OPTIONS_ATTRNUM, tupDesc, &isnull);
/*keyring_options = TextDatumGetCString(options_datum);*/

provider_type = get_keyring_provider_from_typename(keyring_type);

keyring = load_keyring_provider_options(provider_type, datum);
keyring = load_keyring_provider_options(provider_type, options_datum);
if (keyring)
{
strncpy(keyring->keyName, keyring_name, sizeof(keyring->keyName));
Expand Down Expand Up @@ -113,7 +123,6 @@ GetAllKeyringProviders(void)
heap_endscan(scan);
relation_close(kp_table_relation, AccessShareLock);

ereport(NOTICE,(errmsg( "Finsih Loading all keyring providers")));
return keyring_list;
}

Expand Down Expand Up @@ -146,8 +155,6 @@ GetKeyProviderByName(const char *provider_name)
}
heap_endscan(scan);
relation_close(kp_table_relation, AccessShareLock);

ereport(NOTICE,(errmsg( "Exiting GetKeyProviderByName")));
return keyring;
}

Expand Down Expand Up @@ -181,7 +188,6 @@ GetKeyProviderByID(int provider_id)
heap_endscan(scan);
relation_close(kp_table_relation, AccessShareLock);

ereport(NOTICE,(errmsg( "Exiting GetKeyProviderByID")));
return keyring;
}

Expand All @@ -205,19 +211,13 @@ load_keyring_provider_options(ProviderType provider_type, Datum keyring_options)
static FileKeyring*
load_file_keyring_provider_options(Datum keyring_options)
{
#define FILE_KEYRING_PATH_KEY "path"
#define FILE_KEYRING_TYPE_KEY "type"

Datum file_type;
Datum file_path;

FileKeyring *file_keyring = palloc0(sizeof(FileKeyring));
elog(NOTICE, "Parsing file type keyring options");
file_type = DirectFunctionCall2(json_object_field_text, keyring_options, CStringGetTextDatum(FILE_KEYRING_TYPE_KEY));
file_path = DirectFunctionCall2(json_object_field_text, keyring_options, CStringGetTextDatum(FILE_KEYRING_PATH_KEY));
elog(NOTICE, "file_type Option : %s", TextDatumGetCString(file_type));
elog(NOTICE, "Path Option : %s", TextDatumGetCString(file_path));
/* TODO check NULL */
/* TODO check NULL and verify type */
file_keyring->keyring.type = FILE_KEY_PROVIDER;
strncpy(file_keyring->file_name,TextDatumGetCString(file_path), sizeof(file_keyring->file_name));
return file_keyring;
Expand All @@ -226,10 +226,6 @@ load_file_keyring_provider_options(Datum keyring_options)
static ValutV2Keyring*
load_valutV2_keyring_provider_options(Datum keyring_options)
{
#define VALUTV2_KEYRING_TOKEN_KEY "token"
#define VALUTV2_KEYRING_URL_KEY "url"
#define VALUTV2_KEYRING_MOUNT_PATH_KEY "mountPath"
#define VALUTV2_KEYRING_CA_PATH_KEY "caPath"
ValutV2Keyring *valutV2_keyring = palloc0(sizeof(ValutV2Keyring));
Datum token = DirectFunctionCall2(json_object_field_text, keyring_options, CStringGetTextDatum(VALUTV2_KEYRING_TOKEN_KEY));
Datum url = DirectFunctionCall2(json_object_field_text, keyring_options, CStringGetTextDatum(VALUTV2_KEYRING_URL_KEY));
Expand All @@ -248,27 +244,27 @@ load_valutV2_keyring_provider_options(Datum keyring_options)
static void
debug_print_kerying(GenericKeyring* keyring)
{
elog(NOTICE, "Keyring type: %d", keyring->type);
elog(NOTICE, "Keyring name: %s", keyring->keyName);
elog(NOTICE, "Keyring id: %d", keyring->keyId);
elog(DEBUG2, "Keyring type: %d", keyring->type);
elog(DEBUG2, "Keyring name: %s", keyring->keyName);
elog(DEBUG2, "Keyring id: %d", keyring->keyId);
switch(keyring->type)
{
case FILE_KEY_PROVIDER:
elog(NOTICE, "File Keyring Path: %s", ((FileKeyring*)keyring)->file_name);
elog(DEBUG2, "File Keyring Path: %s", ((FileKeyring*)keyring)->file_name);
break;
case VAULT_V2_KEY_PROVIDER:
elog(NOTICE, "Vault Keyring Token: %s", ((ValutV2Keyring*)keyring)->vault_token);
elog(NOTICE, "Vault Keyring URL: %s", ((ValutV2Keyring*)keyring)->vault_url);
elog(NOTICE, "Vault Keyring Mount Path: %s", ((ValutV2Keyring*)keyring)->vault_mount_path);
elog(NOTICE, "Vault Keyring CA Path: %s", ((ValutV2Keyring*)keyring)->vault_ca_path);
elog(DEBUG2, "Vault Keyring Token: %s", ((ValutV2Keyring*)keyring)->vault_token);
elog(DEBUG2, "Vault Keyring URL: %s", ((ValutV2Keyring*)keyring)->vault_url);
elog(DEBUG2, "Vault Keyring Mount Path: %s", ((ValutV2Keyring*)keyring)->vault_mount_path);
elog(DEBUG2, "Vault Keyring CA Path: %s", ((ValutV2Keyring*)keyring)->vault_ca_path);
break;
case UNKNOWN_KEY_PROVIDER:
elog(NOTICE, "Unknown Keyring ");
elog(DEBUG2, "Unknown Keyring ");
break;
}
}

/* Testing function */
/* TODOL Debug function, Remove once not needed */
PG_FUNCTION_INFO_V1(pg_tde_get_keyprovider);
Datum pg_tde_get_keyprovider(PG_FUNCTION_ARGS);

Expand Down
67 changes: 47 additions & 20 deletions src/catalog/tde_master_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/
#include "postgres.h"
#include "catalog/tde_master_key.h"
#include "keyring/keyring_api.h"
#include "pg_tde_shmem.h"
#include "storage/lwlock.h"
#include "storage/fd.h"
Expand Down Expand Up @@ -63,6 +62,7 @@ static Size initialize_shared_state(void* start_address);
static void initialize_objects_in_dsa_area(dsa_area *dsa, void* raw_dsa_area);
static Size cache_area_size(void);
static Size required_shared_mem_size(void);
static int required_locks_count(void);
static void shared_memory_shutdown(int code, Datum arg);

static TDEMasterKeyInfo* save_master_key_info(TDEMasterKey* master_key, GenericKeyring* keyring);
Expand All @@ -76,15 +76,24 @@ static const TDEShmemSetupRoutine master_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
.shmem_kill = shared_memory_shutdown,
.required_locks_count = required_locks_count
};

void InitializeMasterKeyInfo(void)
void
InitializeMasterKeyInfo(void)
{
ereport(LOG,(errmsg("Initializing TDE master key info")));
RegisterShmemRequest(&master_key_info_shmem_routine);
}

static int
required_locks_count(void)
{
/* We just need one lock as for now */
return 1;
}

static Size
cache_area_size(void)
{
Expand All @@ -108,7 +117,7 @@ static Size
initialize_shared_state(void* start_address)
{
TdeMasterKeySharedState *sharedState = (TdeMasterKeySharedState *)start_address;
ereport(NOTICE,(errmsg("initializing shared state for master key")));
ereport(LOG,(errmsg("initializing shared state for master key")));
masterKeyLocalState.dsa = NULL;
masterKeyLocalState.sharedHash = NULL;

Expand All @@ -123,7 +132,7 @@ initialize_objects_in_dsa_area(dsa_area *dsa, void* raw_dsa_area)
dshash_table *dsh;
TdeMasterKeySharedState *sharedState = masterKeyLocalState.sharedMasterKeyState;

ereport(NOTICE,(errmsg("initializing dsa area objects for master key")));
ereport(LOG,(errmsg("initializing dsa area objects for master key")));

Assert(sharedState != NULL);

Expand All @@ -135,16 +144,16 @@ initialize_objects_in_dsa_area(dsa_area *dsa, void* raw_dsa_area)
dshash_detach(dsh);
}

/*
* Attaches to the DSA to local backend
*/
static void
master_key_info_attach_shmem(void)
{
MemoryContext oldcontext;

if (masterKeyLocalState.dsa)
{
ereport(NOTICE,(errmsg("DSA already attached")));
return;
}

/*
* We want the dsa to remain valid throughout the lifecycle of this
Expand All @@ -154,8 +163,6 @@ master_key_info_attach_shmem(void)

masterKeyLocalState.dsa = dsa_attach_in_place(masterKeyLocalState.sharedMasterKeyState->rawDsaArea,
NULL);
ereport(NOTICE,(errmsg("DSA attached")));

/*
* pin the attached area to keep the area attached until end of session or
* explicit detach.
Expand Down Expand Up @@ -203,7 +210,7 @@ save_master_key_info(TDEMasterKey* master_key, GenericKeyring* keyring)
masterKeyInfo->databaseId = MyDatabaseId;
masterKeyInfo->keyVersion = 1;
gettimeofday(&masterKeyInfo->creationTime, NULL);
strncpy(masterKeyInfo->keyName, master_key->keyName, TDE_MASTER_KEY_LEN);
strncpy(masterKeyInfo->keyName, master_key->keyName, TDE_KEY_NAME_LEN);
masterKeyInfo->keyringId = keyring->keyId;

master_key_file = PathNameOpenFile(info_file_path, O_CREAT | O_EXCL | O_RDWR | PG_BINARY);
Expand All @@ -228,6 +235,10 @@ save_master_key_info(TDEMasterKey* master_key, GenericKeyring* keyring)
return masterKeyInfo;
}

/*
* Reads the master key info from the file
* the file gets created by the set_master_key interface
*/
static TDEMasterKeyInfo*
get_master_key_info(void)
{
Expand Down Expand Up @@ -265,7 +276,13 @@ get_master_key_info(void)
return masterKeyInfo;
}


/*
* Public interface to get the master key for the current database
* If the master key is not present in the cache, it is loaded from
* the keyring and stored in the cache.
* When the master key is not set for the database. The function returns
* throws an error.
*/
TDEMasterKey*
GetMasterKey(void)
{
Expand Down Expand Up @@ -311,7 +328,7 @@ GetMasterKey(void)
masterKey->databaseId = MyDatabaseId;
masterKey->keyVersion = 1;
masterKey->keyringId = masterKeyInfo->keyringId;
strncpy(masterKey->keyName, masterKeyInfo->keyName, TDE_MASTER_KEY_LEN);
strncpy(masterKey->keyName, masterKeyInfo->keyName, TDE_KEY_NAME_LEN);
masterKey->keyLength = keyInfo->data.len;
memcpy(masterKey->keyData, keyInfo->data.data, keyInfo->data.len);
push_master_key_to_cache(masterKey);
Expand Down Expand Up @@ -376,12 +393,12 @@ set_master_key_with_keyring(const char* key_name, GenericKeyring* keyring)
masterKey->databaseId = MyDatabaseId;
masterKey->keyVersion = 1;
masterKey->keyringId = keyring->keyId;
strncpy(masterKey->keyName, key_name, TDE_MASTER_KEY_LEN);
strncpy(masterKey->keyName, key_name, TDE_KEY_NAME_LEN);
/* We need to get the key from keyring */

keyInfo = KeyringGetKey(keyring, key_name, false, &keyring_ret);
if(keyInfo == NULL) /* TODO: check if the key was not present or there was a problem with key provider*/
keyInfo = keyringGenerateNewKeyAndStore(keyring, key_name, MASTER_KEY_LEN, false);
keyInfo = keyringGenerateNewKeyAndStore(keyring, key_name, INTERNAL_KEY_LEN, false);

if(keyInfo == NULL)
{
Expand Down Expand Up @@ -413,7 +430,10 @@ SetMasterKey(const char* key_name, const char* provider_name)
return set_master_key_with_keyring(key_name, keyring);
}

/* Master key cache realted stuff */
/*
* ------------------------------
* Master key cache realted stuff
*/

static inline dshash_table*
get_master_key_Hash(void)
Expand All @@ -422,7 +442,9 @@ get_master_key_Hash(void)
return masterKeyLocalState.sharedHash;
}

/* Gets the master key for current database from cache */
/*
* Gets the master key for current database from cache
*/
static TDEMasterKey*
get_master_key_from_cache(void)
{
Expand All @@ -437,7 +459,9 @@ get_master_key_from_cache(void)
return cacheEntry;
}

/* Gets the master key for current database from cache */
/*
* push the master key for current database to the shared memory cache
*/
static void
push_master_key_to_cache(TDEMasterKey *masterKey)
{
Expand All @@ -453,7 +477,9 @@ push_master_key_to_cache(TDEMasterKey *masterKey)
dshash_release_lock(get_master_key_Hash(), cacheEntry);
}

/* SQL interface to set master key */
/*
* SQL interface to set master key
*/
PG_FUNCTION_INFO_V1(pg_tde_set_master_key);
Datum pg_tde_set_master_key(PG_FUNCTION_ARGS);

Expand All @@ -463,7 +489,8 @@ pg_tde_set_master_key(PG_FUNCTION_ARGS)
char *master_key_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
char *provider_name = text_to_cstring(PG_GETARG_TEXT_PP(1));

ereport(NOTICE,(errmsg("Setting master key [%s : %s] for the database",master_key_name, provider_name)));
ereport(LOG,
(errmsg("Setting master key [%s : %s] for the database",master_key_name, provider_name)));
SetMasterKey(master_key_name, provider_name);
PG_RETURN_NULL();
}
5 changes: 2 additions & 3 deletions src/include/access/pg_tde_tdemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include "utils/rel.h"
#include "storage/relfilelocator.h"
#include "access/xlog_internal.h"
#include "keyring/keyring_api.h"

#define TDE_FORK_EXT "tde"

#define INTERNAL_KEY_LEN 16
typedef struct InternalKey
{
uint8 key[INTERNAL_KEY_LEN];
Expand All @@ -26,10 +26,9 @@ typedef struct InternalKey
void* ctx; // TODO: shouldn't be here / written to the disk
} InternalKey;

#define MASTER_KEY_NAME_LEN 256
typedef struct RelKeysData
{
char master_key_name[MASTER_KEY_NAME_LEN];
char master_key_name[TDE_KEY_NAME_LEN];
Size internal_keys_len;
InternalKey internal_key[FLEXIBLE_ARRAY_MEMBER];
} RelKeysData;
Expand Down
Loading

0 comments on commit 680b10a

Please sign in to comment.