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

@ -1746,6 +1746,10 @@ bool Manager::CloseStore(const string& name)
++i;
}
s->second->have_store = false;
s->second->store_pid = {};
s->second->proxy = {};
s->second->store = {};
Unref(s->second);
data_stores.erase(s);
return true;

View file

@ -114,8 +114,12 @@ private:
*/
class StoreHandleVal : public OpaqueVal {
public:
StoreHandleVal()
: OpaqueVal(Broker::detail::opaque_of_store_handle)
{}
StoreHandleVal(broker::store s)
: OpaqueVal(Broker::detail::opaque_of_store_handle), store{s}, proxy{store}, store_pid{store.frontend_id()}
: OpaqueVal(Broker::detail::opaque_of_store_handle), store{std::move(s)}, proxy{store}, store_pid{store.frontend_id()}, forward_to{}, have_store{true}
{ }
void ValDescribe(ODesc* d) const override;
@ -125,16 +129,13 @@ public:
broker::publisher_id store_pid;
// Zeek table that events are forwarded to.
TableValPtr forward_to;
bool have_store = false;
protected:
IntrusivePtr<Val> DoClone(CloneState* state) override
{ return { NewRef{}, this }; }
StoreHandleVal()
: OpaqueVal(Broker::detail::opaque_of_store_handle)
{}
DECLARE_OPAQUE_VALUE(StoreHandleVal)
};
@ -145,4 +146,4 @@ broker::backend to_backend_type(BifEnum::Broker::BackendType type);
broker::backend_options to_backend_options(broker::backend backend,
RecordVal* options);
} // namespace zeek::Broker
} // namespace zeek::Broker::detail

View file

@ -8,7 +8,10 @@
#include "zeek/Trigger.h"
static zeek::Broker::detail::StoreHandleVal* to_store_handle(zeek::Val* h)
{ return dynamic_cast<zeek::Broker::detail::StoreHandleVal*>(h); }
{
auto rval = dynamic_cast<zeek::Broker::detail::StoreHandleVal*>(h);
return rval && rval->have_store ? rval : nullptr;
}
%%}
module Broker;
@ -41,7 +44,7 @@ function Broker::__create_master%(id: string, b: BackendType,
if ( ! store )
{
zeek::emit_builtin_error(zeek::util::fmt("Could not create Broker master store '%s'", name));
return nullptr;
return make_intrusive<zeek::Broker::detail::StoreHandleVal>();
}
return store;
@ -66,7 +69,7 @@ function Broker::__create_clone%(id: string, resync_interval: interval,
if ( ! store )
{
zeek::emit_builtin_error(zeek::util::fmt("Could not create clone of Broker store '%s'", name));
return nullptr;
return make_intrusive<zeek::Broker::detail::StoreHandleVal>();
}
return store;
@ -75,12 +78,15 @@ function Broker::__create_clone%(id: string, resync_interval: interval,
function Broker::__is_closed%(h: opaque of Broker::Store%): bool
%{
zeek::Broker::Manager::ScriptScopeGuard ssg;
auto handle = to_store_handle(h);
auto handle = dynamic_cast<zeek::Broker::detail::StoreHandleVal*>(h);
if ( ! handle )
zeek::detail::emit_builtin_exception("invalid Broker store handle", h);
return zeek::val_mgr->Bool(broker_mgr->LookupStore(handle->store.name()));
if ( ! handle->have_store )
return zeek::val_mgr->True();
return zeek::val_mgr->Bool(! broker_mgr->LookupStore(handle->store.name()));
%}
function Broker::__close%(h: opaque of Broker::Store%): bool