update(userspace): engine atomic and express lifecycle with a namespace

Signed-off-by: Lorenzo Fontana <lo@linux.com>
This commit is contained in:
Lorenzo Fontana
2020-11-26 19:40:42 +01:00
parent 538e7286bc
commit b90164bac1
6 changed files with 192 additions and 141 deletions

View File

@@ -69,6 +69,32 @@ falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir)
m_json_factory = make_shared<json_event_filter_factory>();
}
falco_engine::falco_engine(const falco_engine &orig_engine)
{
std::cout << "copy ctor" << std::endl;
luaopen_lpeg(m_ls);
luaopen_yaml(m_ls);
m_alternate_lua_dir = orig_engine.m_alternate_lua_dir;
falco_common::init(m_lua_main_filename.c_str(), m_alternate_lua_dir.c_str());
falco_rules::init(m_ls);
m_sinsp_rules.reset(new falco_sinsp_ruleset());
m_k8s_audit_rules.reset(new falco_ruleset());
m_default_ruleset_id = find_ruleset_id(m_default_ruleset);
// Create this now so we can potentially list filters and exit
m_json_factory = make_shared<json_event_filter_factory>();
set_inspector(orig_engine.m_inspector);
std::string extra = orig_engine.m_extra;
set_extra(extra, orig_engine.m_replace_container_info);
set_min_priority(orig_engine.m_min_priority);
set_sampling_multiplier(orig_engine.m_sampling_multiplier);
set_sampling_ratio(orig_engine.m_sampling_ratio);
}
falco_engine::~falco_engine()
{
if (m_rules)

View File

@@ -48,6 +48,7 @@ class falco_engine : public falco_common
{
public:
falco_engine(bool seed_rng=true, const std::string& alternate_lua_dir=FALCO_ENGINE_SOURCE_LUA_DIR);
falco_engine(const falco_engine &orig_engine);
virtual ~falco_engine();
falco_engine *clone();

View File

@@ -50,13 +50,15 @@ limitations under the License.
#endif
#include "banned.h" // This raises a compilation error when certain functions are used
typedef function<void(sinsp* inspector)> open_t;
typedef function<void(sinsp *inspector)> open_t;
bool g_terminate = false;
bool g_reopen_outputs = false;
bool g_restart = false;
bool g_daemonized = false;
std::atomic<falco_engine *> g_engine;
std::mutex g_engine_ready;
std::condition_variable g_engine_cv;
bool g_is_engine_ready = false;
@@ -240,20 +242,19 @@ static std::string read_file(std::string filename)
//
// Event processing loop
//
uint64_t do_inspect(falco_engine **engine,
falco_outputs *outputs,
sinsp* inspector,
falco_configuration &config,
syscall_evt_drop_mgr &sdropmgr,
uint64_t duration_to_tot_ns,
string &stats_filename,
uint64_t stats_interval,
bool all_events,
int &result)
uint64_t do_inspect(falco_outputs *outputs,
sinsp *inspector,
falco_configuration &config,
syscall_evt_drop_mgr &sdropmgr,
uint64_t duration_to_tot_ns,
string &stats_filename,
uint64_t stats_interval,
bool all_events,
int &result)
{
uint64_t num_evts = 0;
int32_t rc;
sinsp_evt* ev;
sinsp_evt *ev;
StatsFileWriter writer;
uint64_t duration_start = 0;
@@ -264,11 +265,11 @@ uint64_t do_inspect(falco_engine **engine,
config.m_syscall_evt_drop_max_burst,
config.m_syscall_evt_simulate_drops);
if (stats_filename != "")
if(stats_filename != "")
{
string errstr;
if (!writer.init(inspector, stats_filename, stats_interval, errstr))
if(!writer.init(inspector, stats_filename, stats_interval, errstr))
{
throw falco_exception(errstr);
}
@@ -280,13 +281,6 @@ uint64_t do_inspect(falco_engine **engine,
g_engine_cv.wait(lk, [] { return g_is_engine_ready; });
}
//
// Loop through the events
//
std::atomic<falco_engine *> e;
falco_engine *engine_to_use = nullptr;
e.compare_exchange_strong(engine_to_use, *engine);
while(1)
{
@@ -305,7 +299,7 @@ uint64_t do_inspect(falco_engine **engine,
falco_logger::log(LOG_INFO, "SIGINT received, exiting...\n");
break;
}
else if (g_restart)
else if(g_restart)
{
falco_logger::log(LOG_INFO, "SIGHUP received, restarting...\n");
break;
@@ -328,10 +322,11 @@ uint64_t do_inspect(falco_engine **engine,
throw sinsp_exception(inspector->getlasterr().c_str());
}
if (duration_start == 0)
if(duration_start == 0)
{
duration_start = ev->get_ts();
} else if(duration_to_tot_ns > 0)
}
else if(duration_to_tot_ns > 0)
{
if(ev->get_ts() - duration_start >= duration_to_tot_ns)
{
@@ -350,17 +345,7 @@ uint64_t do_inspect(falco_engine **engine,
continue;
}
// As the inspector has no filter at its level, all
// events are returned here. Pass them to the Falco
// engine, which will match the event against the set
// of rules. If a match is found, pass the event to
// the outputs.
bool engine_cmp_res = e.compare_exchange_strong(engine_to_use, *engine);
if(engine_cmp_res == false)
{
falco_logger::log(LOG_INFO, "Using new engine with new ruleset\n");
}
unique_ptr<falco_engine::rule_result> res = e.load()->process_sinsp_event(ev);
unique_ptr<falco_engine::rule_result> res = g_engine.load()->process_sinsp_event(ev);
if(res)
{
outputs->handle_event(res->evt, res->rule, res->source, res->priority_num, res->format);
@@ -374,9 +359,9 @@ uint64_t do_inspect(falco_engine **engine,
static void print_all_ignored_events(sinsp *inspector)
{
sinsp_evttables* einfo = inspector->get_event_info_tables();
const struct ppm_event_info* etable = einfo->m_event_info;
const struct ppm_syscall_desc* stable = einfo->m_syscall_info_table;
sinsp_evttables *einfo = inspector->get_event_info_tables();
const struct ppm_event_info *etable = einfo->m_event_info;
const struct ppm_syscall_desc *stable = einfo->m_syscall_info_table;
std::set<string> ignored_event_names;
for(uint32_t j = 0; j < PPM_EVENT_MAX; j++)
@@ -430,12 +415,21 @@ static void list_source_fields(falco_engine *engine, bool verbose, bool names_on
}
}
static void rules_cb(char *rules_content, hawk_engine *engine)
static void rules_cb(char *rules_content)
{
falco_engine *engine_replacement = (*reinterpret_cast<falco_engine **>(engine))->clone();
engine_replacement->load_rules(rules_content, false, true);
*engine = std::ref(engine_replacement);
try
{
// todo(fntlnz): remove clone and use copy constructor here instead
falco_engine *engine_replacement = g_engine.load()->clone();
//auto engine_replacement = new falco_engine(g_engine.load());
engine_replacement->load_rules(rules_content, false, true);
g_engine.store(engine_replacement);
}
catch(const falco_exception &e)
{
falco_logger::log(LOG_WARNING, std::string("rules replacement failed: ") + e.what());
return;
}
// This mutex is only needed for the first synchronization
// it can be discarded the second time rules_cb is needed
@@ -454,12 +448,10 @@ static void rules_cb(char *rules_content, hawk_engine *engine)
int falco_init(int argc, char **argv)
{
int result = EXIT_SUCCESS;
sinsp* inspector = NULL;
sinsp *inspector = NULL;
sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL;
falco_engine *engine_blueprint;
std::thread watchrules_thread;
falco_outputs *outputs = NULL;
libhawk::lifecycle *hawk_lifecycle = NULL;
syscall_evt_drop_mgr sdropmgr;
int op;
int long_index = 0;
@@ -479,9 +471,9 @@ int falco_init(int argc, char **argv)
bool names_only = false;
bool all_events = false;
#ifndef MINIMAL_BUILD
string* k8s_api = 0;
string* k8s_api_cert = 0;
string* mesos_api = 0;
string *k8s_api = 0;
string *k8s_api_cert = 0;
string *mesos_api = 0;
#endif
string output_format = "";
uint32_t snaplen = 0;
@@ -506,7 +498,7 @@ int falco_init(int argc, char **argv)
bool compress = false;
bool buffered_outputs = true;
bool buffered_cmdline = false;
std::map<string,uint64_t> required_engine_versions;
std::map<string, uint64_t> required_engine_versions;
// Used for stats
double duration;
@@ -558,8 +550,8 @@ int falco_init(int argc, char **argv)
// Parse the args
//
while((op = getopt_long(argc, argv,
"hc:AbdD:e:F:ik:K:Ll:m:M:No:P:p:r:S:s:T:t:UuvV:w:",
long_options, &long_index)) != -1)
"hc:AbdD:e:F:ik:K:Ll:m:M:No:P:p:r:S:s:T:t:UuvV:w:",
long_options, &long_index)) != -1)
{
switch(op)
{
@@ -694,18 +686,18 @@ int falco_init(int argc, char **argv)
printf("Driver version: %s\n", DRIVER_VERSION);
return EXIT_SUCCESS;
}
else if (string(long_options[long_index].name) == "cri")
else if(string(long_options[long_index].name) == "cri")
{
if(optarg != NULL)
{
cri_socket_path = optarg;
}
}
else if (string(long_options[long_index].name) == "disable-cri-async")
else if(string(long_options[long_index].name) == "disable-cri-async")
{
cri_async = false;
cri_async = false;
}
else if (string(long_options[long_index].name) == "list")
else if(string(long_options[long_index].name) == "list")
{
list_flds = true;
if(optarg != NULL)
@@ -713,27 +705,28 @@ int falco_init(int argc, char **argv)
list_flds_source = optarg;
}
}
else if (string(long_options[long_index].name) == "stats-interval")
else if(string(long_options[long_index].name) == "stats-interval")
{
stats_interval = atoi(optarg);
}
else if (string(long_options[long_index].name) == "support")
else if(string(long_options[long_index].name) == "support")
{
print_support = true;
}
else if (string(long_options[long_index].name) == "disable-source")
else if(string(long_options[long_index].name) == "disable-source")
{
if(optarg != NULL)
{
disable_sources.insert(optarg);
}
}
else if (string(long_options[long_index].name)== "alternate-lua-dir")
else if(string(long_options[long_index].name) == "alternate-lua-dir")
{
if(optarg != NULL)
{
alternate_lua_dir = optarg;
if (alternate_lua_dir.back() != '/') {
if(alternate_lua_dir.back() != '/')
{
alternate_lua_dir += '/';
}
}
@@ -743,7 +736,6 @@ int falco_init(int argc, char **argv)
default:
break;
}
}
inspector = new sinsp();
@@ -773,9 +765,10 @@ int falco_init(int argc, char **argv)
return EXIT_SUCCESS;
}
engine_blueprint = new falco_engine(true, alternate_lua_dir);
engine_blueprint->set_inspector(inspector);
engine_blueprint->set_extra(output_format, replace_container_info);
falco_engine *initial_engine = new falco_engine(true, alternate_lua_dir);
initial_engine->set_inspector(inspector);
initial_engine->set_extra(output_format, replace_container_info);
g_engine = initial_engine;
if(list_flds)
{
@@ -797,23 +790,25 @@ int falco_init(int argc, char **argv)
}
disable_syscall = disable_sources.count("syscall") > 0;
disable_k8s_audit = disable_sources.count("k8s_audit") > 0;
if (disable_syscall && disable_k8s_audit) {
if(disable_syscall && disable_k8s_audit)
{
throw std::invalid_argument("The event source \"syscall\" and \"k8s_audit\" can not be disabled together");
}
}
// Some combinations of arguments are not allowed.
if (daemon && pidfilename == "") {
if(daemon && pidfilename == "")
{
throw std::invalid_argument("If -d is provided, a pid file must also be provided");
}
hawk_lifecycle = new libhawk::lifecycle();
libhawk::lifecycle::start();
ifstream conf_stream;
if (conf_filename.size())
if(conf_filename.size())
{
conf_stream.open(conf_filename);
if (!conf_stream.is_open())
if(!conf_stream.is_open())
{
throw std::runtime_error("Could not find configuration file at " + conf_filename);
}
@@ -821,14 +816,14 @@ int falco_init(int argc, char **argv)
else
{
conf_stream.open(FALCO_SOURCE_CONF_FILE);
if (conf_stream.is_open())
if(conf_stream.is_open())
{
conf_filename = FALCO_SOURCE_CONF_FILE;
}
else
{
conf_stream.open(FALCO_INSTALL_CONF_FILE);
if (conf_stream.is_open())
if(conf_stream.is_open())
{
conf_filename = FALCO_INSTALL_CONF_FILE;
}
@@ -839,6 +834,7 @@ int falco_init(int argc, char **argv)
}
}
<<<<<<< HEAD
// validate the rules files and exit
// if(validate_rules_filenames.size() > 0)
// {
@@ -865,9 +861,36 @@ int falco_init(int argc, char **argv)
// falco_logger::log(LOG_INFO, "Ok\n");
// goto exit;
// }
=======
if(validate_rules_filenames.size() > 0)
{
falco_logger::log(LOG_INFO, "Validating rules file(s):\n");
for(auto file : validate_rules_filenames)
{
falco_logger::log(LOG_INFO, " " + file + "\n");
}
for(auto file : validate_rules_filenames)
{
// Only include the prefix if there is more than one file
std::string prefix = (validate_rules_filenames.size() > 1 ? file + ": " : "");
try
{
// engine->load_rules_file(file, verbose, all_events);
}
catch(falco_exception &e)
{
printf("%s%s\n", prefix.c_str(), e.what());
throw;
}
printf("%sOk\n", prefix.c_str());
}
falco_logger::log(LOG_INFO, "Ok\n");
goto exit;
}
>>>>>>> e7adf5a (update(userspace): engine atomic and express lifecycle with a namespace)
falco_configuration config;
if (conf_filename.size())
if(conf_filename.size())
{
config.init(conf_filename, cmdline_options);
falco_logger::set_time_format_iso_8601(config.m_time_format_iso_8601);
@@ -881,12 +904,12 @@ int falco_init(int argc, char **argv)
throw std::runtime_error("Could not find configuration file at " + conf_filename);
}
if (rules_filenames.size())
if(rules_filenames.size())
{
config.m_rules_filenames = rules_filenames;
}
engine_blueprint->set_min_priority(config.m_min_priority);
g_engine.load()->set_min_priority(config.m_min_priority);
if(buffered_cmdline)
{
@@ -899,12 +922,12 @@ int falco_init(int argc, char **argv)
}
falco_logger::log(LOG_DEBUG, "Configured rules filenames:\n");
for (auto filename : config.m_rules_filenames)
for(auto filename : config.m_rules_filenames)
{
falco_logger::log(LOG_DEBUG, string(" ") + filename + "\n");
}
for (auto filename : config.m_rules_filenames)
for(auto filename : config.m_rules_filenames)
{
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
uint64_t required_engine_version;
@@ -915,11 +938,12 @@ int falco_init(int argc, char **argv)
// You can't both disable and enable rules
if((disabled_rule_substrings.size() + disabled_rule_tags.size() > 0) &&
enabled_rule_tags.size() > 0) {
enabled_rule_tags.size() > 0)
{
throw std::invalid_argument("You can not specify both disabled (-D/-T) and enabled (-t) rules");
}
for (auto substring : disabled_rule_substrings)
for(auto substring : disabled_rule_substrings)
{
falco_logger::log(LOG_INFO, "Disabling rules matching substring: " + substring + "\n");
// engine->enable_rule(substring, false);
@@ -948,10 +972,9 @@ int falco_init(int argc, char **argv)
}
watchrules_thread = std::thread([&] {
hawk_lifecycle->watch_rules(
(hawk_watch_rules_cb)rules_cb,
reinterpret_cast<hawk_engine *>(&engine_blueprint),
"hawk_example_go");
libhawk::lifecycle::watch_rules(
(hawk_watch_rules_cb)rules_cb,
"hawk_example_go");
});
falco_logger::log(LOG_INFO, "DOPO\n");
@@ -1063,7 +1086,7 @@ int falco_init(int argc, char **argv)
// read hostname
string hostname;
if(char* env_hostname = getenv("FALCO_GRPC_HOSTNAME"))
if(char *env_hostname = getenv("FALCO_GRPC_HOSTNAME"))
{
hostname = env_hostname;
}
@@ -1083,13 +1106,13 @@ int falco_init(int argc, char **argv)
inspector->set_drop_event_flags(EF_DROP_SIMPLE_CONS);
}
if (describe_all_rules)
if(describe_all_rules)
{
// engine->describe_rule(NULL);
goto exit;
}
if (describe_rule != "")
if(describe_rule != "")
{
// engine->describe_rule(&describe_rule);
goto exit;
@@ -1127,21 +1150,25 @@ int falco_init(int argc, char **argv)
// If daemonizing, do it here so any init errors will
// be returned in the foreground process.
if (daemon && !g_daemonized) {
if(daemon && !g_daemonized)
{
pid_t pid, sid;
pid = fork();
if (pid < 0) {
if(pid < 0)
{
// error
falco_logger::log(LOG_ERR, "Could not fork. Exiting.\n");
result = EXIT_FAILURE;
goto exit;
} else if (pid > 0) {
}
else if(pid > 0)
{
// parent. Write child pid to pidfile and exit
std::ofstream pidfile;
pidfile.open(pidfilename);
if (!pidfile.good())
if(!pidfile.good())
{
falco_logger::log(LOG_ERR, "Could not write pid to pid file " + pidfilename + ". Exiting.\n");
result = EXIT_FAILURE;
@@ -1155,7 +1182,8 @@ int falco_init(int argc, char **argv)
// Become own process group.
sid = setsid();
if (sid < 0) {
if(sid < 0)
{
falco_logger::log(LOG_ERR, "Could not set session id. Exiting.\n");
result = EXIT_FAILURE;
goto exit;
@@ -1165,7 +1193,8 @@ int falco_init(int argc, char **argv)
umask(027);
// Change working directory to '/'
if ((chdir("/")) < 0) {
if((chdir("/")) < 0)
{
falco_logger::log(LOG_ERR, "Could not change working directory to '/'. Exiting.\n");
result = EXIT_FAILURE;
goto exit;
@@ -1201,14 +1230,15 @@ int falco_init(int argc, char **argv)
{
// Try to open the trace file as a sysdig
// capture file first.
try {
try
{
inspector->open(trace_filename);
falco_logger::log(LOG_INFO, "Reading system call events from file: " + trace_filename + "\n");
}
catch(sinsp_exception &e)
{
falco_logger::log(LOG_DEBUG, "Could not read trace file \"" + trace_filename + "\": " + string(e.what()));
trace_is_scap=false;
trace_is_scap = false;
}
if(!trace_is_scap)
@@ -1219,7 +1249,8 @@ int falco_init(int argc, char **argv)
result = EXIT_FAILURE;
goto exit;
#else
try {
try
{
string line;
nlohmann::json j;
@@ -1231,13 +1262,13 @@ int falco_init(int argc, char **argv)
falco_logger::log(LOG_INFO, "Reading k8s audit events from file: " + trace_filename + "\n");
}
catch (nlohmann::json::parse_error& e)
catch(nlohmann::json::parse_error &e)
{
fprintf(stderr, "Trace filename %s not recognized as system call events or k8s audit events\n", trace_filename.c_str());
result = EXIT_FAILURE;
goto exit;
}
catch (exception &e)
catch(exception &e)
{
fprintf(stderr, "Could not open trace filename %s for reading: %s\n", trace_filename.c_str(), e.what());
result = EXIT_FAILURE;
@@ -1248,8 +1279,7 @@ int falco_init(int argc, char **argv)
}
else
{
open_t open_cb = [&userspace](sinsp* inspector)
{
open_t open_cb = [&userspace](sinsp *inspector) {
if(userspace)
{
// open_udig() is the underlying method used in the capture code to parse userspace events from the kernel.
@@ -1261,19 +1291,22 @@ int falco_init(int argc, char **argv)
}
inspector->open();
};
open_t open_nodriver_cb = [](sinsp* inspector) {
open_t open_nodriver_cb = [](sinsp *inspector) {
inspector->open_nodriver();
};
open_t open_f;
// Default mode: both event sources enabled
if (!disable_syscall && !disable_k8s_audit) {
if(!disable_syscall && !disable_k8s_audit)
{
open_f = open_cb;
}
if (disable_syscall) {
if(disable_syscall)
{
open_f = open_nodriver_cb;
}
if (disable_k8s_audit) {
if(disable_k8s_audit)
{
open_f = open_cb;
}
@@ -1284,7 +1317,7 @@ int falco_init(int argc, char **argv)
catch(sinsp_exception &e)
{
// If syscall input source is enabled and not through userspace instrumentation
if (!disable_syscall && !userspace)
if(!disable_syscall && !userspace)
{
// Try to insert the Falco kernel module
if(system("modprobe " PROBE_NAME " > /dev/null 2> /dev/null"))
@@ -1292,8 +1325,8 @@ int falco_init(int argc, char **argv)
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
}
open_f(inspector);
}
else
}
else
{
rethrow_exception(current_exception());
}
@@ -1322,7 +1355,7 @@ int falco_init(int argc, char **argv)
{
if(!k8s_api_cert)
{
if(char* k8s_cert_env = getenv("FALCO_K8S_API_CERT"))
if(char *k8s_cert_env = getenv("FALCO_K8S_API_CERT"))
{
k8s_api_cert = new string(k8s_cert_env);
}
@@ -1331,13 +1364,13 @@ int falco_init(int argc, char **argv)
k8s_api = 0;
k8s_api_cert = 0;
}
else if(char* k8s_api_env = getenv("FALCO_K8S_API"))
else if(char *k8s_api_env = getenv("FALCO_K8S_API"))
{
if(k8s_api_env != NULL)
{
if(!k8s_api_cert)
{
if(char* k8s_cert_env = getenv("FALCO_K8S_API_CERT"))
if(char *k8s_cert_env = getenv("FALCO_K8S_API_CERT"))
{
k8s_api_cert = new string(k8s_cert_env);
}
@@ -1361,7 +1394,7 @@ int falco_init(int argc, char **argv)
{
inspector->init_mesos_client(mesos_api, verbose);
}
else if(char* mesos_api_env = getenv("FALCO_MESOS_API"))
else if(char *mesos_api_env = getenv("FALCO_MESOS_API"))
{
if(mesos_api_env != NULL)
{
@@ -1392,18 +1425,16 @@ int falco_init(int argc, char **argv)
config.m_grpc_private_key,
config.m_grpc_cert_chain,
config.m_grpc_root_certs,
config.m_log_level
);
config.m_log_level);
grpc_server_thread = std::thread([&grpc_server] {
grpc_server.run();
});
}
#endif
if(!trace_filename.empty() && !trace_is_scap)
{
#ifndef MINIMAL_BUILD
#ifndef MINIMAL_BUILD
// read_k8s_audit_trace_file(engine,
// outputs,
// trace_filename);
@@ -1413,12 +1444,12 @@ int falco_init(int argc, char **argv)
{
uint64_t num_evts;
num_evts = do_inspect(&engine_blueprint,
outputs,
num_evts = do_inspect(outputs,
inspector,
config,
sdropmgr,
uint64_t(duration_to_tot*ONE_SECOND_IN_NS),
uint64_t(duration_to_tot * ONE_SECOND_IN_NS),
stats_filename,
stats_interval,
all_events,
@@ -1439,13 +1470,12 @@ int falco_init(int argc, char **argv)
num_evts,
num_evts / duration);
}
}
// Honor -M also when using a trace file.
// Since inspection stops as soon as all events have been consumed
// just await the given duration is reached, if needed.
if(!trace_filename.empty() && duration_to_tot>0)
if(!trace_filename.empty() && duration_to_tot > 0)
{
std::this_thread::sleep_for(std::chrono::seconds(duration_to_tot));
}
@@ -1454,7 +1484,7 @@ int falco_init(int argc, char **argv)
// engine->print_stats();
sdropmgr.print_stats();
hawk_lifecycle->stop();
libhawk::lifecycle::stop();
if(watchrules_thread.joinable())
{
watchrules_thread.join();
@@ -1471,7 +1501,7 @@ int falco_init(int argc, char **argv)
catch(exception &e)
{
display_fatal_err("Runtime error: " + string(e.what()) + ". Exiting.\n");
hawk_lifecycle->stop();
libhawk::lifecycle::stop();
if(watchrules_thread.joinable())
{
watchrules_thread.join();
@@ -1491,10 +1521,7 @@ int falco_init(int argc, char **argv)
exit:
delete inspector;
delete engine_blueprint;
delete outputs;
delete hawk_lifecycle;
return result;
}

View File

@@ -6,17 +6,16 @@
#define HAWK_AT_LEAST_VERSION(x, y, z) \
(HAWK_VERSION_CODE >= HAWK_VERSION_BITS(x, y, z))
typedef void* hawk_engine;
typedef void (*hawk_watch_rules_cb)(char* rules_content, hawk_engine* engine);
typedef void (*hawk_watch_rules_cb)(char* rules_content);
typedef struct
{
void (*hawk_init)(void);
void (*hawk_destroy)(void);
void (*hawk_watch_rules)(hawk_watch_rules_cb, hawk_engine*);
void (*hawk_watch_rules)(hawk_watch_rules_cb);
} hawk_plugin_definition;
typedef void(register_plugin_cb)(const char *, hawk_plugin_definition);
typedef void(register_plugin_cb)(const char*, hawk_plugin_definition);
typedef struct
{
@@ -29,7 +28,7 @@ extern hawk_plugin_registry plugin_registry;
void name##_hawk_plugin_init(void) __attribute__((constructor)); \
void name##_hawk_plugin_init(void) \
{ \
plugin_registry.register_plugin(#name, definition); \
plugin_registry.register_plugin(#name, definition); \
}
#endif //HAWK_H

View File

@@ -41,14 +41,14 @@ hawk_plugin_registry plugin_registry = {
.register_plugin = &libhawk_register_plugin,
};
libhawk::lifecycle::lifecycle()
void libhawk::lifecycle::start()
{
if(g_plugins == nullptr)
{
throw hawk_exception("no libhawk plugins registered");
}
for(auto plugin : *g_plugins)
for(const auto& plugin : *g_plugins)
{
if(plugin.second.hawk_init != nullptr)
{
@@ -59,7 +59,7 @@ libhawk::lifecycle::lifecycle()
void libhawk::lifecycle::stop()
{
for(auto plugin : *g_plugins)
for(const auto& plugin : *g_plugins)
{
if(plugin.second.hawk_destroy != nullptr)
{
@@ -68,7 +68,7 @@ void libhawk::lifecycle::stop()
}
}
void libhawk::lifecycle::watch_rules(hawk_watch_rules_cb cb, hawk_engine *engine, const std::string &plugin_name)
void libhawk::lifecycle::watch_rules(hawk_watch_rules_cb cb, const std::string &plugin_name)
{
auto plugin = g_plugins->find(plugin_name);
if(plugin == g_plugins->end())
@@ -79,5 +79,5 @@ void libhawk::lifecycle::watch_rules(hawk_watch_rules_cb cb, hawk_engine *engine
{
throw hawk_plugin_exception(plugin_name, "plugin does not implement hawk_watch_rules");
}
plugin->second.hawk_watch_rules(cb, engine);
plugin->second.hawk_watch_rules(cb);
}

View File

@@ -29,12 +29,10 @@ namespace libhawk
{
extern std::map<std::string, hawk_plugin_definition>* g_plugins;
class lifecycle
namespace lifecycle
{
public:
lifecycle();
void watch_rules(hawk_watch_rules_cb cb, hawk_engine* engine, const std::string& plugin_name);
void stop();
};
void start();
void stop();
void watch_rules(hawk_watch_rules_cb cb, const std::string& plugin_name);
} // namespace lifecycle
} // namespace libhawk