GH-1426: Improve handling of Broker data store creation failures

Broker::create_master() and Broker::create_clone() now return
a valid value even when there's a failure to open the backend database
(e.g. SQLite filesystem error).  In that case, the returned value can
still be passed into other data store operations, but they'll fail
immediately with an error.  Broker::is_closed() can now also be used to
determine whether the data store creation calls failed.
This commit is contained in:
Jon Siwek 2021-03-05 23:28:57 -08:00
parent 6946cffde2
commit 6af436aad3
8 changed files with 138 additions and 14 deletions

View file

@ -0,0 +1,11 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
error in <...>/create-failure.zeek, line 63: Failed to attach master store backend_failure: (Broker::create_master(../fail, Broker::SQLITE, (coerce [] to Broker::BackendOptions)))
error in <...>/create-failure.zeek, line 63: Could not create Broker master store '../fail' (Broker::create_master(../fail, Broker::SQLITE, (coerce [] to Broker::BackendOptions)))
error in <...>/create-failure.zeek, line 49: invalid Broker store handle (Broker::keys(s) and broker::store::{})
error in <...>/create-failure.zeek, line 27: invalid Broker store handle (Broker::close(m1) and broker::store::{})
error in <...>/create-failure.zeek, line 33: invalid Broker store handle (Broker::close(c2) and broker::store::{})
error in <...>/create-failure.zeek, line 49: invalid Broker store handle (Broker::keys(s) and broker::store::{})
error in <...>/create-failure.zeek, line 49: invalid Broker store handle (Broker::keys(s) and broker::store::{})
error in <...>/create-failure.zeek, line 49: invalid Broker store handle (Broker::keys(s) and broker::store::{})
error in <...>/create-failure.zeek, line 49: invalid Broker store handle (Broker::keys(s) and broker::store::{})
received termination signal

View file

@ -0,0 +1,21 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
T
F
F
F
m1 keys result: [status=Broker::FAILURE, result=[data=<uninitialized>]]
m2 keys result: [status=Broker::SUCCESS, result=[data=broker::data{{}}]]
c2 keys result: [status=Broker::SUCCESS, result=[data=broker::data{{}}]]
T
F
F
F
T
T
T
T
m1 keys result: [status=Broker::FAILURE, result=[data=<uninitialized>]]
c1 keys result: [status=Broker::FAILURE, result=[data=<uninitialized>]]
m2 keys result: [status=Broker::FAILURE, result=[data=<uninitialized>]]
c2 keys result: [status=Broker::FAILURE, result=[data=<uninitialized>]]
c1 timeout

View file

@ -0,0 +1,77 @@
# @TEST-EXEC: mkdir fail.sqlite
# @TEST-EXEC: btest-bg-run zeek "BROKER_FILE_VERBOSITY=error BROKER_CONSOLE_VERBOSITY=quiet zeek -b %INPUT >out 2>err"
# @TEST-EXEC: btest-bg-wait 60
# @TEST-EXEC: btest-diff zeek/out
# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath $SCRIPTS/diff-sort" btest-diff zeek/err
redef exit_only_after_terminate = T;
global c = 0;
global m1: opaque of Broker::Store;
global m2: opaque of Broker::Store;
global c1: opaque of Broker::Store;
global c2: opaque of Broker::Store;
global check_it: function(name: string, s: opaque of Broker::Store);
function check_terminate_conditions()
{
++c;
if ( c == 4 )
{
print Broker::is_closed(m1);
print Broker::is_closed(m2);
print Broker::is_closed(c1);
print Broker::is_closed(c2);
# Failed to originally open m1, so should raise an error.
Broker::close(m1);
Broker::close(m2);
Broker::close(c1);
# Closing c2 is an error since it's actually referring to m2, already
# closed above (i.e. making a clone of a master store that already lives
# in the same process, just returns a handle to the master).
Broker::close(c2);
print Broker::is_closed(m1);
print Broker::is_closed(m2);
print Broker::is_closed(c1);
print Broker::is_closed(c2);
check_it("m1", m1);
check_it("c1", c1);
check_it("m2", m2);
check_it("c2", c2);
}
else if ( c == 8 )
terminate();
}
function check_it(name: string, s: opaque of Broker::Store)
{
when ( local r = Broker::keys(s) )
{
check_terminate_conditions();
print fmt("%s keys result: %s", name, r);
}
timeout 1sec
{
check_terminate_conditions();
print fmt("%s timeout", name);
}
}
event zeek_init()
{
m1 = Broker::create_master("../fail", Broker::SQLITE);
m2 = Broker::create_master("ok");
c1 = Broker::create_clone("../fail");
c2 = Broker::create_clone("ok");
print Broker::is_closed(m1);
print Broker::is_closed(m2);
print Broker::is_closed(c1);
print Broker::is_closed(c2);
check_it("m1", m1);
check_it("c1", c1);
check_it("m2", m2);
check_it("c2", c2);
}