summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0crypt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0crypt.cc')
-rw-r--r--storage/innobase/fil/fil0crypt.cc162
1 files changed, 105 insertions, 57 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 7a6d21dba13..b242b57714f 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -417,45 +417,6 @@ fil_space_crypt_t::write_page0(
}
/******************************************************************
-Set crypt data for a tablespace
-@param[in,out] space Tablespace
-@param[in,out] crypt_data Crypt data to be set
-@return crypt_data in tablespace */
-static
-fil_space_crypt_t*
-fil_space_set_crypt_data(
- fil_space_t* space,
- fil_space_crypt_t* crypt_data)
-{
- fil_space_crypt_t* free_crypt_data = NULL;
- fil_space_crypt_t* ret_crypt_data = NULL;
-
- /* Provided space is protected using fil_space_acquire()
- from concurrent operations. */
- if (space->crypt_data != NULL) {
- /* There is already crypt data present,
- merge new crypt_data */
- fil_space_merge_crypt_data(space->crypt_data,
- crypt_data);
- ret_crypt_data = space->crypt_data;
- free_crypt_data = crypt_data;
- } else {
- space->crypt_data = crypt_data;
- ret_crypt_data = space->crypt_data;
- }
-
- if (free_crypt_data != NULL) {
- /* there was already crypt data present and the new crypt
- * data provided as argument to this function has been merged
- * into that => free new crypt data
- */
- fil_space_destroy_crypt_data(&free_crypt_data);
- }
-
- return ret_crypt_data;
-}
-
-/******************************************************************
Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry
@param[in] ptr Log entry start
@param[in] end_ptr Log entry end
@@ -512,26 +473,36 @@ fil_parse_write_crypt_data(
return NULL;
}
- fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(encryption, key_id);
- /* Need to overwrite these as above will initialize fields. */
+ mutex_enter(&fil_system.mutex);
+
+ fil_space_t* space = fil_space_get_by_id(space_id);
+
+ if (!space) {
+ mutex_exit(&fil_system.mutex);
+ return ptr + len;
+ }
+
+ fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(
+ encryption, key_id);
+
crypt_data->page0_offset = offset;
crypt_data->min_key_version = min_key_version;
- crypt_data->encryption = encryption;
crypt_data->type = type;
memcpy(crypt_data->iv, ptr, len);
ptr += len;
- /* update fil_space memory cache with crypt_data */
- if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- space->release();
- /* Check is used key found from encryption plugin */
- if (crypt_data->should_encrypt()
- && !crypt_data->is_key_found()) {
- *err = DB_DECRYPTION_FAILED;
- }
- } else {
+ if (space->crypt_data) {
+ fil_space_merge_crypt_data(space->crypt_data, crypt_data);
fil_space_destroy_crypt_data(&crypt_data);
+ crypt_data = space->crypt_data;
+ } else {
+ space->crypt_data = crypt_data;
+ }
+
+ mutex_exit(&fil_system.mutex);
+
+ if (crypt_data->should_encrypt() && !crypt_data->is_key_found()) {
+ *err = DB_DECRYPTION_FAILED;
}
return ptr;
@@ -1138,11 +1109,15 @@ fil_crypt_needs_rotation(
if (crypt_data->encryption == FIL_ENCRYPTION_DEFAULT
&& crypt_data->type == CRYPT_SCHEME_1
- && srv_encrypt_tables == 0 ) {
+ && !srv_encrypt_tables) {
/* This is rotation encrypted => unencrypted */
return true;
}
+ if (rotate_key_age == 0) {
+ return false;
+ }
+
/* this is rotation encrypted => encrypted,
* only reencrypt if key is sufficiently old */
if (key_version + rotate_key_age < latest_key_version) {
@@ -1225,7 +1200,8 @@ fil_crypt_start_encrypting_space(
* crypt data in page 0 */
/* 1 - create crypt data */
- crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ crypt_data = fil_space_create_crypt_data(
+ FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
if (crypt_data == NULL) {
mutex_exit(&fil_crypt_threads_mutex);
@@ -1238,9 +1214,9 @@ fil_crypt_start_encrypting_space(
crypt_data->rotate_state.starting = true;
crypt_data->rotate_state.active_threads = 1;
- mutex_enter(&crypt_data->mutex);
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- mutex_exit(&crypt_data->mutex);
+ mutex_enter(&fil_system.mutex);
+ space->crypt_data = crypt_data;
+ mutex_exit(&fil_system.mutex);
fil_crypt_start_converting = true;
mutex_exit(&fil_crypt_threads_mutex);
@@ -2505,6 +2481,64 @@ fil_crypt_set_thread_cnt(
}
}
+/** Initialize the tablespace rotation_list
+if innodb_encryption_rotate_key_age=0. */
+static void fil_crypt_rotation_list_fill()
+{
+ ut_ad(mutex_own(&fil_system.mutex));
+
+ for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
+ if (space->purpose != FIL_TYPE_TABLESPACE
+ || space->is_in_rotation_list()
+ || space->is_stopping()
+ || UT_LIST_GET_LEN(space->chain) == 0) {
+ continue;
+ }
+
+ /* Ensure that crypt_data has been initialized. */
+ if (!space->size) {
+ /* Protect the tablespace while we may
+ release fil_system.mutex. */
+ space->n_pending_ops++;
+ fil_space_t* s= fil_system.read_page0(
+ space->id);
+ ut_ad(!s || s == space);
+ space->n_pending_ops--;
+ if (!space->size) {
+ /* Page 0 was not loaded.
+ Skip this tablespace. */
+ continue;
+ }
+ }
+
+ /* Skip ENCRYPTION!=DEFAULT tablespaces. */
+ if (space->crypt_data
+ && !space->crypt_data->is_default_encryption()) {
+ continue;
+ }
+
+ if (srv_encrypt_tables) {
+ /* Skip encrypted tablespaces if
+ innodb_encrypt_tables!=OFF */
+ if (space->crypt_data
+ && space->crypt_data->min_key_version) {
+ continue;
+ }
+ } else {
+ /* Skip unencrypted tablespaces if
+ innodb_encrypt_tables=OFF */
+ if (!space->crypt_data
+ || !space->crypt_data->min_key_version) {
+ continue;
+ }
+ }
+
+ UT_LIST_ADD_LAST(fil_system.rotation_list, space);
+ }
+}
+
/*********************************************************************
Adjust max key age
@param[in] val New max key age */
@@ -2513,7 +2547,12 @@ void
fil_crypt_set_rotate_key_age(
uint val)
{
+ mutex_enter(&fil_system.mutex);
srv_fil_crypt_rotate_key_age = val;
+ if (val == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+ mutex_exit(&fil_system.mutex);
os_event_set(fil_crypt_threads_event);
}
@@ -2537,7 +2576,16 @@ void
fil_crypt_set_encrypt_tables(
uint val)
{
+ mutex_enter(&fil_system.mutex);
+
srv_encrypt_tables = val;
+
+ if (srv_fil_crypt_rotate_key_age == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+
+ mutex_exit(&fil_system.mutex);
+
os_event_set(fil_crypt_threads_event);
}