|
|
|
@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com |
|
|
|
#include "fil0pagecompress.h"
|
|
|
|
#include <my_crypt.h>
|
|
|
|
|
|
|
|
/** Mutex for keys */ |
|
|
|
static ib_mutex_t fil_crypt_key_mutex; |
|
|
|
|
|
|
|
static bool fil_crypt_threads_inited = false; |
|
|
|
|
|
|
|
/** Is encryption enabled/disabled */ |
|
|
|
@ -113,8 +110,6 @@ UNIV_INTERN |
|
|
|
void |
|
|
|
fil_space_crypt_init() |
|
|
|
{ |
|
|
|
mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex); |
|
|
|
|
|
|
|
fil_crypt_throttle_sleep_event = os_event_create(0); |
|
|
|
|
|
|
|
mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex); |
|
|
|
@ -128,7 +123,6 @@ void |
|
|
|
fil_space_crypt_cleanup() |
|
|
|
{ |
|
|
|
os_event_destroy(fil_crypt_throttle_sleep_event); |
|
|
|
mutex_free(&fil_crypt_key_mutex); |
|
|
|
mutex_free(&crypt_stat_mutex); |
|
|
|
} |
|
|
|
|
|
|
|
@ -1384,6 +1378,94 @@ fil_crypt_return_iops( |
|
|
|
fil_crypt_update_total_stat(state); |
|
|
|
} |
|
|
|
|
|
|
|
/** Return the next tablespace from rotation_list.
|
|
|
|
@param space previous tablespace (NULL to start from the start) |
|
|
|
@param recheck whether the removal condition needs to be rechecked after |
|
|
|
the encryption parameters were changed |
|
|
|
@param encrypt expected state of innodb_encrypt_tables |
|
|
|
@return the next tablespace to process (n_pending_ops incremented) |
|
|
|
@retval NULL if this was the last */ |
|
|
|
inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space, |
|
|
|
bool recheck, bool encrypt) |
|
|
|
{ |
|
|
|
ut_ad(mutex_own(&fil_system->mutex)); |
|
|
|
|
|
|
|
sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it= |
|
|
|
space ? space : fil_system->rotation_list.begin(); |
|
|
|
const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end= |
|
|
|
fil_system->rotation_list.end(); |
|
|
|
|
|
|
|
if (space) |
|
|
|
{ |
|
|
|
while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping())); |
|
|
|
|
|
|
|
/* If one of the encryption threads already started the encryption
|
|
|
|
of the table then don't remove the unencrypted spaces from rotation list |
|
|
|
|
|
|
|
If there is a change in innodb_encrypt_tables variables value then |
|
|
|
don't remove the last processed tablespace from the rotation list. */ |
|
|
|
if (!--space->n_pending_ops && |
|
|
|
(!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables && |
|
|
|
space->is_in_rotation_list) |
|
|
|
{ |
|
|
|
ut_a(!fil_system->rotation_list.empty()); |
|
|
|
fil_system->rotation_list.remove(*space); |
|
|
|
space->is_in_rotation_list= false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (it == end) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
space= &*it; |
|
|
|
space->n_pending_ops++; |
|
|
|
return space; |
|
|
|
} |
|
|
|
|
|
|
|
/** Return the next tablespace.
|
|
|
|
@param space previous tablespace (NULL to start from the beginning) |
|
|
|
@param recheck whether the removal condition needs to be rechecked after |
|
|
|
the encryption parameters were changed |
|
|
|
@param encrypt expected state of innodb_encrypt_tables |
|
|
|
@return pointer to the next tablespace (with n_pending_ops incremented) |
|
|
|
@retval NULL if this was the last */ |
|
|
|
static fil_space_t *fil_space_next(fil_space_t *space, bool recheck, |
|
|
|
bool encrypt) |
|
|
|
{ |
|
|
|
mutex_enter(&fil_system->mutex); |
|
|
|
ut_ad(!space || space->n_pending_ops); |
|
|
|
|
|
|
|
if (!srv_fil_crypt_rotate_key_age) |
|
|
|
space= fil_system->keyrotate_next(space, recheck, encrypt); |
|
|
|
else if (!space) |
|
|
|
{ |
|
|
|
space= UT_LIST_GET_FIRST(fil_system->space_list); |
|
|
|
/* We can trust that space is not NULL because at least the
|
|
|
|
system tablespace is always present and loaded first. */ |
|
|
|
space->n_pending_ops++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
ut_ad(space->n_pending_ops > 0); |
|
|
|
/* Move on to the next fil_space_t */ |
|
|
|
space->n_pending_ops--; |
|
|
|
space= UT_LIST_GET_NEXT(space_list, space); |
|
|
|
|
|
|
|
/* Skip abnormal tablespaces or those that are being created by
|
|
|
|
fil_ibd_create(), or being dropped. */ |
|
|
|
while (space && |
|
|
|
(UT_LIST_GET_LEN(space->chain) == 0 || |
|
|
|
space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE)) |
|
|
|
space= UT_LIST_GET_NEXT(space_list, space); |
|
|
|
|
|
|
|
if (space) |
|
|
|
space->n_pending_ops++; |
|
|
|
} |
|
|
|
|
|
|
|
mutex_exit(&fil_system->mutex); |
|
|
|
return space; |
|
|
|
} |
|
|
|
|
|
|
|
/** Search for a space needing rotation
|
|
|
|
@param[in,out] key_state Key state |
|
|
|
@param[in,out] state Rotation state |
|
|
|
@ -1416,16 +1498,8 @@ static bool fil_crypt_find_space_to_rotate( |
|
|
|
state->space = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* If key rotation is enabled (default) we iterate all tablespaces.
|
|
|
|
If key rotation is not enabled we iterate only the tablespaces |
|
|
|
added to keyrotation list. */ |
|
|
|
if (srv_fil_crypt_rotate_key_age) { |
|
|
|
state->space = fil_space_next(state->space); |
|
|
|
} else { |
|
|
|
state->space = fil_system->keyrotate_next( |
|
|
|
state->space, *recheck, |
|
|
|
key_state->key_version); |
|
|
|
} |
|
|
|
state->space = fil_space_next(state->space, *recheck, |
|
|
|
key_state->key_version != 0); |
|
|
|
|
|
|
|
while (!state->should_shutdown() && state->space) { |
|
|
|
/* If there is no crypt data and we have not yet read
|
|
|
|
@ -1443,16 +1517,16 @@ static bool fil_crypt_find_space_to_rotate( |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (srv_fil_crypt_rotate_key_age) { |
|
|
|
state->space = fil_space_next(state->space); |
|
|
|
} else { |
|
|
|
state->space = fil_system->keyrotate_next( |
|
|
|
state->space, *recheck, |
|
|
|
key_state->key_version); |
|
|
|
} |
|
|
|
state->space = fil_space_next(state->space, *recheck, |
|
|
|
key_state->key_version != 0); |
|
|
|
} |
|
|
|
|
|
|
|
if (state->space) { |
|
|
|
fil_space_release(state->space); |
|
|
|
state->space = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* if we didn't find any space return iops */ |
|
|
|
/* no work to do; release our allocation of I/O capacity */ |
|
|
|
fil_crypt_return_iops(state); |
|
|
|
|
|
|
|
return false; |
|
|
|
|