From bc714d06fc9f23fa0ac3039c1c87363aa517c8d8 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 10 Oct 2022 14:21:32 +0200 Subject: [PATCH] chore(userspace/falco): do not allow multiple Falco instances. Signed-off-by: Federico Di Pierro --- userspace/falco/CMakeLists.txt | 1 + userspace/falco/app_actions/gain_lock.cpp | 45 +++++++++++++++++++++++ userspace/falco/application.cpp | 4 +- userspace/falco/application.h | 3 ++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 userspace/falco/app_actions/gain_lock.cpp diff --git a/userspace/falco/CMakeLists.txt b/userspace/falco/CMakeLists.txt index 8407f676..2519fa3e 100644 --- a/userspace/falco/CMakeLists.txt +++ b/userspace/falco/CMakeLists.txt @@ -45,6 +45,7 @@ set( app_actions/validate_rules_files.cpp app_actions/create_requested_paths.cpp app_actions/configure_interesting_sets.cpp + app_actions/gain_lock.cpp configuration.cpp logger.cpp falco_outputs.cpp diff --git a/userspace/falco/app_actions/gain_lock.cpp b/userspace/falco/app_actions/gain_lock.cpp new file mode 100644 index 00000000..c0c65340 --- /dev/null +++ b/userspace/falco/app_actions/gain_lock.cpp @@ -0,0 +1,45 @@ +/* +Copyright (C) 2022 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "application.h" +#include + +using namespace falco::app; + +#define FALCO_LOCK_FILE "falco.lock" + +application::run_result application::gain_lock() +{ + m_lock_fd = open(FALCO_LOCK_FILE, O_CREAT | O_WRONLY, 0644); + if (m_lock_fd < 0) + { + return run_result::fatal(std::string("Failed to open " FALCO_LOCK_FILE " lock file: ") + strerror(errno)); + } + if (flock(m_lock_fd, LOCK_EX | LOCK_NB) == -1) + { + return run_result::fatal("A lock is present on " FALCO_LOCK_FILE " Another Falco instance running?"); + } + return run_result::ok(); +} + +bool application::release_lock(std::string &errstr) +{ + if (m_lock_fd > 0) + { + close(m_lock_fd); + } + return true; +} \ No newline at end of file diff --git a/userspace/falco/application.cpp b/userspace/falco/application.cpp index 43933993..2f04adb7 100644 --- a/userspace/falco/application.cpp +++ b/userspace/falco/application.cpp @@ -130,6 +130,7 @@ bool application::run(std::string &errstr, bool &restart) // dependencies are honored (e.g. don't process events before // loading plugins, opening inspector, etc.). std::list> run_steps = { + std::bind(&application::gain_lock, this), std::bind(&application::print_help, this), std::bind(&application::print_version, this), std::bind(&application::print_page_size, this), @@ -165,8 +166,9 @@ bool application::run(std::string &errstr, bool &restart) std::bind(&application::unregister_signal_handlers, this, _1), #ifndef MINIMAL_BUILD std::bind(&application::stop_grpc_server, this, _1), - std::bind(&application::stop_webserver, this, _1) + std::bind(&application::stop_webserver, this, _1), #endif + std::bind(&application::release_lock, this, _1) }; for (auto &func : run_steps) diff --git a/userspace/falco/application.h b/userspace/falco/application.h index 13bc3aaa..eb70c79c 100644 --- a/userspace/falco/application.h +++ b/userspace/falco/application.h @@ -240,6 +240,7 @@ private: // These methods comprise the code the application "runs". The // order in which the methods run is in application.cpp. + run_result gain_lock(); run_result create_signal_handlers(); run_result attach_inotify_signals(); run_result daemonize(); @@ -279,6 +280,7 @@ private: bool stop_grpc_server(std::string &errstr); bool stop_webserver(std::string &errstr); #endif + bool release_lock(std::string &errstr); // Methods called by the above methods int create_dir(const std::string &path); @@ -320,6 +322,7 @@ private: std::unique_ptr m_state; cmdline_options m_options; bool m_initialized; + int m_lock_fd; }; }; // namespace app