Commit def48e62 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-8141 InnoDB: background encryption thread uses FIL_DEFAULT_ENCRYPTION_KEY

* check key version per key id (that is, per tablespace).
* wake encryption thread when a tablespace needs re-encryption
parent 6e4c22af
...@@ -104,6 +104,13 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_stat_mutex_key; ...@@ -104,6 +104,13 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_stat_mutex_key;
UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key; UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
#endif #endif
static bool
fil_crypt_needs_rotation(
/*=====================*/
uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age); /*!< in: When to rotate */
/** /**
* Magic pattern in start of crypt data on page 0 * Magic pattern in start of crypt data on page 0
*/ */
...@@ -218,6 +225,24 @@ fil_crypt_get_key( ...@@ -218,6 +225,24 @@ fil_crypt_get_key(
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
} }
/******************************************************************
Get the latest(key-version), waking the encrypt thread, if needed */
static inline
uint
fil_crypt_get_latest_key_version(
/*=====================*/
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
{
uint rc = encryption_key_get_latest_version(crypt_data->key_id);
if (fil_crypt_needs_rotation(crypt_data->min_key_version,
rc, srv_fil_crypt_rotate_key_age)) {
os_event_set(fil_crypt_threads_event);
}
return rc;
}
/****************************************************************** /******************************************************************
Get key bytes for a space/latest(key-version) */ Get key bytes for a space/latest(key-version) */
static inline static inline
...@@ -230,7 +255,7 @@ fil_crypt_get_latest_key( ...@@ -230,7 +255,7 @@ fil_crypt_get_latest_key(
uint* version) /*!< in: Key version */ uint* version) /*!< in: Key version */
{ {
// used for key rotation - get the next key id from the key provider // used for key rotation - get the next key id from the key provider
uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id); uint rc = *version = fil_crypt_get_latest_key_version(crypt_data);
if (rc == ENCRYPTION_KEY_VERSION_INVALID) { if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL, ib_logf(IB_LOG_LEVEL_FATAL,
...@@ -964,12 +989,13 @@ fil_space_verify_crypt_checksum( ...@@ -964,12 +989,13 @@ fil_space_verify_crypt_checksum(
/** A copy of global key state */ /** A copy of global key state */
struct key_state_t { struct key_state_t {
key_state_t() : key_version(0), key_state_t() : key_id(0), key_version(0),
rotate_key_age(srv_fil_crypt_rotate_key_age) {} rotate_key_age(srv_fil_crypt_rotate_key_age) {}
bool operator==(const key_state_t& other) const { bool operator==(const key_state_t& other) const {
return key_version == other.key_version && return key_version == other.key_version &&
rotate_key_age == other.rotate_key_age; rotate_key_age == other.rotate_key_age;
} }
uint key_id;
uint key_version; uint key_version;
uint rotate_key_age; uint rotate_key_age;
}; };
...@@ -983,7 +1009,7 @@ fil_crypt_get_key_state( ...@@ -983,7 +1009,7 @@ fil_crypt_get_key_state(
{ {
if (srv_encrypt_tables) { if (srv_encrypt_tables) {
new_state->key_version = new_state->key_version =
encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); encryption_key_get_latest_version(new_state->key_id);
new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; new_state->rotate_key_age = srv_fil_crypt_rotate_key_age;
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID); ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID);
ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED); ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
...@@ -999,25 +1025,27 @@ Check if a key needs rotation given a key_state ...@@ -999,25 +1025,27 @@ Check if a key needs rotation given a key_state
static bool static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
const key_state_t* key_state) /*!< in: Key state */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age) /*!< in: When to rotate */
{ {
// TODO(jonaso): Add support for rotating encrypted => unencrypted if (key_version == ENCRYPTION_KEY_VERSION_INVALID)
return false;
if (key_version == 0 && key_state->key_version != 0) { if (key_version == 0 && latest_key_version != 0) {
/* this is rotation unencrypted => encrypted /* this is rotation unencrypted => encrypted
* ignore rotate_key_age */ * ignore rotate_key_age */
return true; return true;
} }
if (key_state->key_version == 0 && key_version != 0) { if (latest_key_version == 0 && key_version != 0) {
/* this is rotation encrypted => unencrypted */ /* this is rotation encrypted => unencrypted */
return true; return true;
} }
/* this is rotation encrypted => encrypted, /* this is rotation encrypted => encrypted,
* only reencrypt if key is sufficiently old */ * only reencrypt if key is sufficiently old */
if (key_version + key_state->rotate_key_age < key_state->key_version) { if (key_version + rotate_key_age < latest_key_version) {
return true; return true;
} }
...@@ -1216,7 +1244,7 @@ static ...@@ -1216,7 +1244,7 @@ static
bool bool
fil_crypt_space_needs_rotation( fil_crypt_space_needs_rotation(
uint space, /*!< in: FIL space id */ uint space, /*!< in: FIL space id */
const key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
{ {
if (fil_space_get_type(space) != FIL_TABLESPACE) { if (fil_space_get_type(space) != FIL_TABLESPACE) {
...@@ -1274,8 +1302,14 @@ fil_crypt_space_needs_rotation( ...@@ -1274,8 +1302,14 @@ fil_crypt_space_needs_rotation(
break; break;
} }
if (crypt_data->key_id != key_state->key_id) {
key_state->key_id= crypt_data->key_id;
fil_crypt_get_key_state(key_state);
}
bool need_key_rotation = fil_crypt_needs_rotation( bool need_key_rotation = fil_crypt_needs_rotation(
crypt_data->min_key_version, key_state); crypt_data->min_key_version,
key_state->key_version, key_state->rotate_key_age);
time_t diff = time(0) - crypt_data->rotate_state.scrubbing. time_t diff = time(0) - crypt_data->rotate_state.scrubbing.
last_scrub_completed; last_scrub_completed;
...@@ -1522,7 +1556,7 @@ UNIV_INTERN ...@@ -1522,7 +1556,7 @@ UNIV_INTERN
bool bool
fil_crypt_find_space_to_rotate( fil_crypt_find_space_to_rotate(
/*===========================*/ /*===========================*/
const key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
rotate_thread_t* state, /*!< in: Key rotation state */ rotate_thread_t* state, /*!< in: Key rotation state */
bool* recheck) /*!< out: true if recheck bool* recheck) /*!< out: true if recheck
needed */ needed */
...@@ -1547,6 +1581,7 @@ fil_crypt_find_space_to_rotate( ...@@ -1547,6 +1581,7 @@ fil_crypt_find_space_to_rotate(
ulint space = state->space; ulint space = state->space;
if (fil_crypt_space_needs_rotation(space, key_state, recheck)) { if (fil_crypt_space_needs_rotation(space, key_state, recheck)) {
ut_ad(key_state->key_id);
/* init state->min_key_version_found before /* init state->min_key_version_found before
* starting on a space */ * starting on a space */
state->min_key_version_found = key_state->key_version; state->min_key_version_found = key_state->key_version;
...@@ -1576,6 +1611,7 @@ fil_crypt_start_rotate_space( ...@@ -1576,6 +1611,7 @@ fil_crypt_start_rotate_space(
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* only first thread needs to init */
...@@ -1621,6 +1657,7 @@ fil_crypt_find_page_to_rotate( ...@@ -1621,6 +1657,7 @@ fil_crypt_find_page_to_rotate(
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->closing == false && if (crypt_data->closing == false &&
crypt_data->rotate_state.next_offset < crypt_data->rotate_state.next_offset <
...@@ -1842,7 +1879,8 @@ fil_crypt_rotate_page( ...@@ -1842,7 +1879,8 @@ fil_crypt_rotate_page(
if (kv == 0 && if (kv == 0 &&
fil_crypt_is_page_uninitialized(frame, zip_size)) { fil_crypt_is_page_uninitialized(frame, zip_size)) {
; ;
} else if (fil_crypt_needs_rotation(kv, key_state)) { } else if (fil_crypt_needs_rotation(kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least * kv == 0 or it should have a key version at least
...@@ -2144,30 +2182,21 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2144,30 +2182,21 @@ DECLARE_THREAD(fil_crypt_thread)(
/* if we find a space that is starting, skip over it and recheck it later */ /* if we find a space that is starting, skip over it and recheck it later */
bool recheck = false; bool recheck = false;
key_state_t key_state;
fil_crypt_get_key_state(&key_state);
/* make sure that thread always checks all tablespace when starting.
*
* by decreasing key_version, loop that waits for change in key-state
* should exit immediately causing thread to check all spaces when starting */
key_state.key_version--;
while (!thr.should_shutdown()) { while (!thr.should_shutdown()) {
key_state_t new_state; key_state_t new_state;
fil_crypt_get_key_state(&new_state);
time_t wait_start = time(0); time_t wait_start = time(0);
while (!thr.should_shutdown() && key_state == new_state) { while (!thr.should_shutdown()) {
/* wait for key state changes /* wait for key state changes
* i.e either new key version of change or * i.e either new key version of change or
* new rotate_key_age */ * new rotate_key_age */
os_event_reset(fil_crypt_threads_event); os_event_reset(fil_crypt_threads_event);
os_event_wait_time(fil_crypt_threads_event, 1000000); if (os_event_wait_time(fil_crypt_threads_event, 1000000) == 0) {
fil_crypt_get_key_state(&new_state); break;
}
if (recheck) { if (recheck) {
/* check recheck here, after sleep, so /* check recheck here, after sleep, so
...@@ -2185,7 +2214,6 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2185,7 +2214,6 @@ DECLARE_THREAD(fil_crypt_thread)(
recheck = false; recheck = false;
thr.first = true; // restart from first tablespace thr.first = true; // restart from first tablespace
key_state = new_state; // save for next loop
/* iterate all spaces searching for those needing rotation */ /* iterate all spaces searching for those needing rotation */
while (!thr.should_shutdown() && while (!thr.should_shutdown() &&
...@@ -2215,8 +2243,8 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2215,8 +2243,8 @@ DECLARE_THREAD(fil_crypt_thread)(
/* complete rotation */ /* complete rotation */
fil_crypt_complete_rotate_space(&new_state, &thr); fil_crypt_complete_rotate_space(&new_state, &thr);
/* refresh key state */ /* force key state refresh */
fil_crypt_get_key_state(&new_state); new_state.key_id= 0;
/* return iops */ /* return iops */
fil_crypt_return_iops(&thr); fil_crypt_return_iops(&thr);
...@@ -2448,14 +2476,17 @@ fil_space_crypt_get_status( ...@@ -2448,14 +2476,17 @@ fil_space_crypt_get_status(
} }
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
if (srv_encrypt_tables) { if (srv_encrypt_tables || crypt_data->min_key_version) {
status->current_key_version = status->current_key_version =
encryption_key_get_latest_version(crypt_data->key_id); fil_crypt_get_latest_key_version(crypt_data);
} else { } else {
status->current_key_version = 0; status->current_key_version = 0;
} }
} else { } else {
memset(status, 0, sizeof(*status)); memset(status, 0, sizeof(*status));
if (srv_encrypt_tables) {
os_event_set(fil_crypt_threads_event);
}
} }
return crypt_data == NULL ? 1 : 0; return crypt_data == NULL ? 1 : 0;
......
...@@ -104,6 +104,13 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_stat_mutex_key; ...@@ -104,6 +104,13 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_stat_mutex_key;
UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key; UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
#endif #endif
static bool
fil_crypt_needs_rotation(
/*=====================*/
uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age); /*!< in: When to rotate */
/** /**
* Magic pattern in start of crypt data on page 0 * Magic pattern in start of crypt data on page 0
*/ */
...@@ -218,6 +225,24 @@ fil_crypt_get_key( ...@@ -218,6 +225,24 @@ fil_crypt_get_key(
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
} }
/******************************************************************
Get the latest(key-version), waking the encrypt thread, if needed */
static inline
uint
fil_crypt_get_latest_key_version(
/*=====================*/
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
{
uint rc = encryption_key_get_latest_version(crypt_data->key_id);
if (fil_crypt_needs_rotation(crypt_data->min_key_version,
rc, srv_fil_crypt_rotate_key_age)) {
os_event_set(fil_crypt_threads_event);
}
return rc;
}
/****************************************************************** /******************************************************************
Get key bytes for a space/latest(key-version) */ Get key bytes for a space/latest(key-version) */
static inline static inline
...@@ -230,7 +255,7 @@ fil_crypt_get_latest_key( ...@@ -230,7 +255,7 @@ fil_crypt_get_latest_key(
uint* version) /*!< in: Key version */ uint* version) /*!< in: Key version */
{ {
// used for key rotation - get the next key id from the key provider // used for key rotation - get the next key id from the key provider
uint rc = *version = encryption_key_get_latest_version(crypt_data->key_id); uint rc = *version = fil_crypt_get_latest_key_version(crypt_data);
if (rc == ENCRYPTION_KEY_VERSION_INVALID) { if (rc == ENCRYPTION_KEY_VERSION_INVALID) {
ib_logf(IB_LOG_LEVEL_FATAL, ib_logf(IB_LOG_LEVEL_FATAL,
...@@ -964,12 +989,13 @@ fil_space_verify_crypt_checksum( ...@@ -964,12 +989,13 @@ fil_space_verify_crypt_checksum(
/** A copy of global key state */ /** A copy of global key state */
struct key_state_t { struct key_state_t {
key_state_t() : key_version(0), key_state_t() : key_id(0), key_version(0),
rotate_key_age(srv_fil_crypt_rotate_key_age) {} rotate_key_age(srv_fil_crypt_rotate_key_age) {}
bool operator==(const key_state_t& other) const { bool operator==(const key_state_t& other) const {
return key_version == other.key_version && return key_version == other.key_version &&
rotate_key_age == other.rotate_key_age; rotate_key_age == other.rotate_key_age;
} }
uint key_id;
uint key_version; uint key_version;
uint rotate_key_age; uint rotate_key_age;
}; };
...@@ -983,7 +1009,7 @@ fil_crypt_get_key_state( ...@@ -983,7 +1009,7 @@ fil_crypt_get_key_state(
{ {
if (srv_encrypt_tables) { if (srv_encrypt_tables) {
new_state->key_version = new_state->key_version =
encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); encryption_key_get_latest_version(new_state->key_id);
new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; new_state->rotate_key_age = srv_fil_crypt_rotate_key_age;
ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID); ut_a(new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID);
ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED); ut_a(new_state->key_version != ENCRYPTION_KEY_NOT_ENCRYPTED);
...@@ -999,25 +1025,27 @@ Check if a key needs rotation given a key_state ...@@ -999,25 +1025,27 @@ Check if a key needs rotation given a key_state
static bool static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
const key_state_t* key_state) /*!< in: Key state */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age) /*!< in: When to rotate */
{ {
// TODO(jonaso): Add support for rotating encrypted => unencrypted if (key_version == ENCRYPTION_KEY_VERSION_INVALID)
return false;
if (key_version == 0 && key_state->key_version != 0) { if (key_version == 0 && latest_key_version != 0) {
/* this is rotation unencrypted => encrypted /* this is rotation unencrypted => encrypted
* ignore rotate_key_age */ * ignore rotate_key_age */
return true; return true;
} }
if (key_state->key_version == 0 && key_version != 0) { if (latest_key_version == 0 && key_version != 0) {
/* this is rotation encrypted => unencrypted */ /* this is rotation encrypted => unencrypted */
return true; return true;
} }
/* this is rotation encrypted => encrypted, /* this is rotation encrypted => encrypted,
* only reencrypt if key is sufficiently old */ * only reencrypt if key is sufficiently old */
if (key_version + key_state->rotate_key_age < key_state->key_version) { if (key_version + rotate_key_age < latest_key_version) {
return true; return true;
} }
...@@ -1216,7 +1244,7 @@ static ...@@ -1216,7 +1244,7 @@ static
bool bool
fil_crypt_space_needs_rotation( fil_crypt_space_needs_rotation(
uint space, /*!< in: FIL space id */ uint space, /*!< in: FIL space id */
const key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
{ {
if (fil_space_get_type(space) != FIL_TABLESPACE) { if (fil_space_get_type(space) != FIL_TABLESPACE) {
...@@ -1274,8 +1302,14 @@ fil_crypt_space_needs_rotation( ...@@ -1274,8 +1302,14 @@ fil_crypt_space_needs_rotation(
break; break;
} }
if (crypt_data->key_id != key_state->key_id) {
key_state->key_id= crypt_data->key_id;
fil_crypt_get_key_state(key_state);
}
bool need_key_rotation = fil_crypt_needs_rotation( bool need_key_rotation = fil_crypt_needs_rotation(
crypt_data->min_key_version, key_state); crypt_data->min_key_version,
key_state->key_version, key_state->rotate_key_age);
time_t diff = time(0) - crypt_data->rotate_state.scrubbing. time_t diff = time(0) - crypt_data->rotate_state.scrubbing.
last_scrub_completed; last_scrub_completed;
...@@ -1522,7 +1556,7 @@ UNIV_INTERN ...@@ -1522,7 +1556,7 @@ UNIV_INTERN
bool bool
fil_crypt_find_space_to_rotate( fil_crypt_find_space_to_rotate(
/*===========================*/ /*===========================*/
const key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
rotate_thread_t* state, /*!< in: Key rotation state */ rotate_thread_t* state, /*!< in: Key rotation state */
bool* recheck) /*!< out: true if recheck bool* recheck) /*!< out: true if recheck
needed */ needed */
...@@ -1547,6 +1581,7 @@ fil_crypt_find_space_to_rotate( ...@@ -1547,6 +1581,7 @@ fil_crypt_find_space_to_rotate(
ulint space = state->space; ulint space = state->space;
if (fil_crypt_space_needs_rotation(space, key_state, recheck)) { if (fil_crypt_space_needs_rotation(space, key_state, recheck)) {
ut_ad(key_state->key_id);
/* init state->min_key_version_found before /* init state->min_key_version_found before
* starting on a space */ * starting on a space */
state->min_key_version_found = key_state->key_version; state->min_key_version_found = key_state->key_version;
...@@ -1576,6 +1611,7 @@ fil_crypt_start_rotate_space( ...@@ -1576,6 +1611,7 @@ fil_crypt_start_rotate_space(
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* only first thread needs to init */
...@@ -1621,6 +1657,7 @@ fil_crypt_find_page_to_rotate( ...@@ -1621,6 +1657,7 @@ fil_crypt_find_page_to_rotate(
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->closing == false && if (crypt_data->closing == false &&
crypt_data->rotate_state.next_offset < crypt_data->rotate_state.next_offset <
...@@ -1842,7 +1879,8 @@ fil_crypt_rotate_page( ...@@ -1842,7 +1879,8 @@ fil_crypt_rotate_page(
if (kv == 0 && if (kv == 0 &&
fil_crypt_is_page_uninitialized(frame, zip_size)) { fil_crypt_is_page_uninitialized(frame, zip_size)) {
; ;
} else if (fil_crypt_needs_rotation(kv, key_state)) { } else if (fil_crypt_needs_rotation(kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least * kv == 0 or it should have a key version at least
...@@ -2144,30 +2182,21 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2144,30 +2182,21 @@ DECLARE_THREAD(fil_crypt_thread)(
/* if we find a space that is starting, skip over it and recheck it later */ /* if we find a space that is starting, skip over it and recheck it later */
bool recheck = false; bool recheck = false;
key_state_t key_state;
fil_crypt_get_key_state(&key_state);
/* make sure that thread always checks all tablespace when starting.
*
* by decreasing key_version, loop that waits for change in key-state
* should exit immediately causing thread to check all spaces when starting */
key_state.key_version--;
while (!thr.should_shutdown()) { while (!thr.should_shutdown()) {
key_state_t new_state; key_state_t new_state;
fil_crypt_get_key_state(&new_state);
time_t wait_start = time(0); time_t wait_start = time(0);
while (!thr.should_shutdown() && key_state == new_state) { while (!thr.should_shutdown()) {
/* wait for key state changes /* wait for key state changes
* i.e either new key version of change or * i.e either new key version of change or
* new rotate_key_age */ * new rotate_key_age */
os_event_reset(fil_crypt_threads_event); os_event_reset(fil_crypt_threads_event);
os_event_wait_time(fil_crypt_threads_event, 1000000); if (os_event_wait_time(fil_crypt_threads_event, 1000000) == 0) {
fil_crypt_get_key_state(&new_state); break;
}
if (recheck) { if (recheck) {
/* check recheck here, after sleep, so /* check recheck here, after sleep, so
...@@ -2185,7 +2214,6 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2185,7 +2214,6 @@ DECLARE_THREAD(fil_crypt_thread)(
recheck = false; recheck = false;
thr.first = true; // restart from first tablespace thr.first = true; // restart from first tablespace
key_state = new_state; // save for next loop
/* iterate all spaces searching for those needing rotation */ /* iterate all spaces searching for those needing rotation */
while (!thr.should_shutdown() && while (!thr.should_shutdown() &&
...@@ -2215,8 +2243,8 @@ DECLARE_THREAD(fil_crypt_thread)( ...@@ -2215,8 +2243,8 @@ DECLARE_THREAD(fil_crypt_thread)(
/* complete rotation */ /* complete rotation */
fil_crypt_complete_rotate_space(&new_state, &thr); fil_crypt_complete_rotate_space(&new_state, &thr);
/* refresh key state */ /* force key state refresh */
fil_crypt_get_key_state(&new_state); new_state.key_id= 0;
/* return iops */ /* return iops */
fil_crypt_return_iops(&thr); fil_crypt_return_iops(&thr);
...@@ -2448,14 +2476,17 @@ fil_space_crypt_get_status( ...@@ -2448,14 +2476,17 @@ fil_space_crypt_get_status(
} }
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
if (srv_encrypt_tables) { if (srv_encrypt_tables || crypt_data->min_key_version) {
status->current_key_version = status->current_key_version =
encryption_key_get_latest_version(crypt_data->key_id); fil_crypt_get_latest_key_version(crypt_data);
} else { } else {
status->current_key_version = 0; status->current_key_version = 0;
} }
} else { } else {
memset(status, 0, sizeof(*status)); memset(status, 0, sizeof(*status));
if (srv_encrypt_tables) {
os_event_set(fil_crypt_threads_event);
}
} }
return crypt_data == NULL ? 1 : 0; return crypt_data == NULL ? 1 : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment