vfs/cbe_trust_anchor: sync keyfile-handle close

Closing the keyfile handle after a write operation wasn't synchronised to the
actual end of the write operation.

Issuing a write operation at the back end returns successfull as soon as the
back end has acknowledged that it will execute the operation. However, the
actual writing of the data might still be in progress at this point. But the
plugin used to close the file handle and declare the operation finished at this
point which led to warnings about acks on unknown file handles and leaking
resources. Now, the plugin issues a sync operation directly after the write
operation and waits for the sync to complete. This ensures that the plugin
doesn't declare the operation finished too early.

Ref #4032
This commit is contained in:
Martin Stein 2021-03-30 19:00:31 +02:00 committed by Norman Feske
parent 42490208c2
commit a2d2b874ec

View File

@ -269,7 +269,18 @@ class Trust_anchor
[[fallthrough]];
case Job_state::IN_PROGRESS:
if (!_write_key_file_finished()) {
if (!_write_op_on_key_file_is_in_final_sync_step()) {
break;
}
_job_state = Job_state::FINAL_SYNC;
_job_success = true;
progress |= true;
[[fallthrough]];
case Job_state::FINAL_SYNC:
if (!_final_sync_of_write_op_on_key_file_finished()) {
break;
}
@ -551,33 +562,11 @@ class Trust_anchor
_key_io_job.construct(*_key_handle, Util::Io_job::Operation::WRITE,
_key_io_job_buffer, 0);
if (_key_io_job->execute() && _key_io_job->completed()) {
_state = State::INITIALIZED;
_close_handle(&_key_handle);
_key_io_job.destruct();
return true;
_start_sync_at_key_io_job();
}
return true;
}
bool _write_key_file_finished()
{
if (!_key_io_job.constructed()) {
return true;
}
// XXX trigger sync
bool const progress = _key_io_job->execute();
bool const completed = _key_io_job->completed();
if (completed) {
_state = State::INITIALIZED;
_close_handle(&_key_handle);
_key_io_job.destruct();
}
return progress && completed;
}
/* hash */
@ -647,6 +636,12 @@ class Trust_anchor
_hash_io_job_buffer, 0);
}
void _start_sync_at_key_io_job()
{
_key_io_job.construct(*_key_handle, Util::Io_job::Operation::SYNC,
_key_io_job_buffer, 0);
}
bool _open_hash_file_and_write(Path const &path)
{
using Result = Vfs::Directory_service::Open_result;
@ -712,6 +707,34 @@ class Trust_anchor
return progress && completed;
}
bool _write_op_on_key_file_is_in_final_sync_step()
{
if (_key_io_job->op() == Util::Io_job::Operation::SYNC) {
return true;
}
bool const progress = _key_io_job->execute();
bool const completed = _key_io_job->completed();
if (completed) {
_start_sync_at_key_io_job();
}
return progress && completed;
}
bool _final_sync_of_write_op_on_key_file_finished()
{
if (!_key_io_job.constructed()) {
return true;
}
bool const progress = _key_io_job->execute();
bool const completed = _key_io_job->completed();
if (completed) {
_state = State::INITIALIZED;
_close_handle(&_key_handle);
_key_io_job.destruct();
}
return progress && completed;
}
Path const _base_path;
public: