Skip to content
This repository was archived by the owner on Oct 6, 2023. It is now read-only.

Commit

Permalink
fix(connector): Connector is working now.
Browse files Browse the repository at this point in the history
* fix(connector): A big fix on connector. If the connector falls, it is restarted automatically.
* fix(tests): bin_connector_test_run contained a bug in its parsing procedure
* fix(various): warnings raised by clang-tidy fixed and coding style applied.
* fix(command_listener): when the listener is destroyed, the command must be notified.
* fix(tests):anomalydetection may fail because of a file not flushed
* cleanup(tests): Dead class removed.
* fix(connector): closing connector is sometimes impossible (crash).
* fix(connector): several potential deadlocks removed
* enh(my_lock): new classes to debug mutexes.
* fix(connector): logs cannot be written when engine is closing
* wip(_thread_m): cleanup

Co-authored-by: Gres Remi <[email protected]>

REFS: MON-6508
  • Loading branch information
bouda1 authored Mar 26, 2021
1 parent 288835e commit 09f58ef
Show file tree
Hide file tree
Showing 40 changed files with 655 additions and 662 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ the timeperiod are now filtered for the contact
and now don't push the notification with time period empty.
these macro are now available without parameters ($HOSTGROUPNAME$, $CONTACTGROUPNAME$, $SERVICEGROUPNAME$)

*Connectors*

When a Perl connector or an SSH connector is used, engine could crash when we
stop it.

When a connector is destroyed, a deadlock could appear while waiting its
destruction.

*Connector restart*

If a connector stops working because of a crash or whatever else, it was not
restarted automatically. It is fixed now.

*Check commands*

When many commands are running, engine could crash when we stop it.
## 20.10.2

`January 20, 2021`
Expand Down
9 changes: 3 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,11 @@ option(WITH_ASAN "Add the libasan to check memory leaks and other memory issues.
if (WITH_ASAN)
set(CMAKE_BUILD_TYPE Debug)
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
set (CMAKE_LINKER_FLAGS_DEBUG
"${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
endif ()

if (USE_CXX11_ABI)
add_definitions("-D_GLIBCXX_USE_CXX11_ABI=1")
else ()
add_definitions("-D_GLIBCXX_USE_CXX11_ABI=0")
endif ()
add_definitions("-D_GLIBCXX_USE_CXX11_ABI=1")
set(INC_DIR "${PROJECT_SOURCE_DIR}/inc")
set(SCRIPT_DIR "${PROJECT_SOURCE_DIR}/scripts")
set(SRC_DIR "${PROJECT_SOURCE_DIR}/src")
Expand Down
39 changes: 19 additions & 20 deletions inc/com/centreon/engine/commands/command.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,35 @@ namespace commands {
* notify listener at the end of the command.
*/
class command {
protected:
static uint64_t get_uniq_id();

std::string _command_line;
command_listener* _listener;
std::string _name;

public:
command(std::string const& name,
std::string const& command_line,
command_listener* listener = NULL);
command(const std::string& name,
const std::string& command_line,
command_listener* listener = nullptr);
virtual ~command() noexcept;
bool operator==(command const& right) const noexcept;
bool operator!=(command const& right) const noexcept;
virtual command* clone() const = 0;
virtual std::string const& get_command_line() const noexcept;
virtual std::string const& get_name() const noexcept;
command(const command&) = delete;
command& operator=(const command&) = delete;
bool operator==(const command& right) const noexcept;
bool operator!=(const command& right) const noexcept;
virtual const std::string& get_command_line() const noexcept;
virtual const std::string& get_name() const noexcept;
virtual std::string process_cmd(nagios_macros* macros) const;
virtual uint64_t run(std::string const& processed_cmd,
virtual uint64_t run(const std::string& processed_cmd,
nagios_macros& macors,
uint32_t timeout) = 0;
virtual void run(std::string const& process_cmd,
virtual void run(const std::string& process_cmd,
nagios_macros& macros,
uint32_t timeout,
result& res) = 0;
virtual void set_command_line(std::string const& command_line);
virtual void set_command_line(const std::string& command_line);
void set_listener(command_listener* listener) noexcept;
static command_map commands;

protected:
command(command const& right);
command& operator=(command const& right);
static uint64_t get_uniq_id();

std::string _command_line;
command_listener* _listener;
std::string _name;
};
} // namespace commands

Expand Down
22 changes: 20 additions & 2 deletions inc/com/centreon/engine/commands/command_listener.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,40 @@
#ifndef CCE_COMMANDS_COMMAND_LISTENER_HH
#define CCE_COMMANDS_COMMAND_LISTENER_HH

#include <functional>
#include <unordered_map>

#include "com/centreon/engine/commands/result.hh"
#include "com/centreon/engine/namespace.hh"

CCE_BEGIN()

namespace commands {
class command;
/**
* @class command_listener command_listener.hh
* @brief Notify command events.
*
* This class provide interface to notify command events.
*/
class command_listener {
std::unordered_map<command*, std::function<void()>> _clean_callbacks;

public:
virtual ~command_listener() throw() {}
virtual void finished(result const& res) throw() = 0;
virtual ~command_listener() noexcept {
for (auto it = _clean_callbacks.begin(), end = _clean_callbacks.end();
it != end; ++it) {
(it->second)();
}
}

virtual void finished(result const& res) noexcept = 0;
void reg(command* const ptr, std::function<void()>& regf) {
_clean_callbacks.insert({ptr, regf});
}
void unreg(command* const ptr) {
_clean_callbacks.erase(ptr);
}
};
} // namespace commands

Expand Down
98 changes: 64 additions & 34 deletions inc/com/centreon/engine/commands/connector.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,60 @@ namespace commands {
* @class connector commands/connector.hh
* @brief Command is a specific implementation of commands::command.
*
* Command is a specific implementation of commands::command who
* provide connector, is more efficiente that a raw command.
* connector is a specific implementation of commands::command that
* is more efficient than a raw command. A connector is an external software
* that launches checks and returns when available their result. For example,
* we have a perl connector. Since, it centralizes various checks, it compiles
* them while reading and then they are are already compiled and can be
* executed faster.
*
* A connector usually executes many checks, whereas a commands::raw works
* with only one check. This is a significant difference.
*
* To exchange with scripts executed by the connector, we use specific commands
* to the connector. Those internal functions all begins with _recv_query_ or
* _send_query_.
*
* The connector is connected to an external program named connector and also
* has an internal thread used to restart the connector if needed. So, we have
* several variables to control all that:
* * _is_running: the connector is up and running.
* * _try_to_restart: This boolean tells if the connector is stopped, if we
* should start it again. Usually it is the case but when we want to stop
* everything, we don't want.
* * _thread_running: The thread is running, so it is possible to restart the
* the connector.
* * _thread_action: This enum asks the thread to start/stop the connector.
* * _thread_cv: Here is the condition variable used in pair with
* _thread_action.
*
*/
class connector : public command, public process_listener {
public:
connector(std::string const& connector_name,
std::string const& connector_line,
command_listener* listener = NULL);
connector(connector const& right);
~connector() noexcept override;
connector& operator=(connector const& right) = delete;
commands::command* clone() const override;
uint64_t run(std::string const& processed_cmd,
nagios_macros& macros,
uint32_t timeout) override;
void run(std::string const& processed_cmd,
nagios_macros& macros,
uint32_t timeout,
result& res) override;
void set_command_line(std::string const& command_line) override;

static connector_map connectors;

private:

struct query_info {
std::string processed_cmd;
timestamp start_time;
uint32_t timeout;
bool waiting_result;
};

enum thread_action { none, start, stop };
std::condition_variable _cv_query;
std::string _data_available;
bool _is_running;
std::unordered_map<uint64_t, std::shared_ptr<query_info> > _queries;
bool _query_quit_ok;
bool _query_version_ok;
mutable std::mutex _lock;
process _process;
std::unordered_map<uint64_t, result> _results;
bool _try_to_restart;

std::thread _restart;
bool _thread_running;
thread_action _thread_action;
std::mutex _thread_m;
std::condition_variable _thread_cv;

void data_is_available(process& p) noexcept override;
void data_is_available_err(process& p) noexcept override;
void finished(process& p) noexcept override;
Expand All @@ -98,18 +120,26 @@ class connector : public command, public process_listener {
void _send_query_quit();
void _send_query_version();
void _run_restart();
void _restart_loop();

std::condition_variable _cv_query;
std::string _data_available;
bool _is_running;
std::unordered_map<uint64_t, std::shared_ptr<query_info> > _queries;
bool _query_quit_ok;
bool _query_version_ok;
mutable std::mutex _lock;
process _process;
std::unordered_map<uint64_t, result> _results;
std::thread* _restart;
bool _try_to_restart;
public:
connector(std::string const& connector_name,
std::string const& connector_line,
command_listener* listener = nullptr);
~connector() noexcept override;
connector(const connector&) = delete;
connector& operator=(const connector&) = delete;
uint64_t run(std::string const& processed_cmd,
nagios_macros& macros,
uint32_t timeout) override;
void run(std::string const& processed_cmd,
nagios_macros& macros,
uint32_t timeout,
result& res) override;
void set_command_line(std::string const& command_line) override;
void restart_connector();

static connector_map connectors;
};
} // namespace commands

Expand Down
61 changes: 29 additions & 32 deletions inc/com/centreon/engine/commands/forward.hh
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
/*
** Copyright 2011-2013 Merethis
**
** This file is part of Centreon Engine.
**
** Centreon Engine is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Engine is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Engine. If not, see
** <http://www.gnu.org/licenses/>.
*/

* Copyright 2011-2013,2015,2019-2021 Centreon (https://www.centreon.com/)
*
* 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.
*
* For more information : [email protected]
*
*/
#ifndef CCE_COMMANDS_FORWARD_HH
#define CCE_COMMANDS_FORWARD_HH

#include <string>
#include "com/centreon/engine/commands/command.hh"
#include "com/centreon/engine/commands/connector.hh"
#include "com/centreon/engine/namespace.hh"

CCE_BEGIN()
Expand All @@ -35,26 +35,23 @@ namespace commands {
* provide forward, is more efficiente that a raw command.
*/
class forward : public command {
std::shared_ptr<command> _s_command;
command* _command;

public:
forward(std::string const& command_name,
std::string const& command_line,
command& cmd);
forward(forward const& right);
~forward() throw() override;
forward& operator=(forward const& right);
commands::command* clone() const override;
uint64_t run(std::string const& processed_cmd,
forward(const std::string& command_name,
const std::string& command_line,
std::shared_ptr<connector>& cmd);
~forward() noexcept = default;
forward(const forward&) = delete;
forward& operator=(const forward&) = delete;
uint64_t run(const std::string& processed_cmd,
nagios_macros& macros,
uint32_t timeout) override;
void run(std::string const& processed_cmd,
void run(const std::string& processed_cmd,
nagios_macros& macros,
uint32_t timeout,
result& res) override;

private:
void _internal_copy(forward const& right);

command* _command;
};
} // namespace commands

Expand Down
15 changes: 7 additions & 8 deletions inc/com/centreon/engine/commands/raw.hh
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,16 @@ class raw : public command, public process_listener {
process* _get_free_process();

public:
raw(std::string const& name,
std::string const& command_line,
command_listener* listener = NULL);
raw(raw const& right);
raw(const std::string& name,
const std::string& command_line,
command_listener* listener = nullptr);
~raw() noexcept override;
raw& operator=(raw const& right);
command* clone() const override;
uint64_t run(std::string const& process_cmd,
raw(const raw&) = delete;
raw& operator=(const raw&) = delete;
uint64_t run(const std::string& process_cmd,
nagios_macros& macros,
uint32_t timeout) override;
void run(std::string const& process_cmd,
void run(const std::string& process_cmd,
nagios_macros& macros,
uint32_t timeout,
result& res) override;
Expand Down
12 changes: 6 additions & 6 deletions inc/com/centreon/engine/events/loop.hh
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ namespace events {
* and dispatch the Centreon Engine events.
*/
class loop {
loop();
loop(loop const&) = delete;
~loop() = default;
loop& operator=(loop const&) = delete;
void _dispatching();

time_t _last_status_update;
time_t _last_time;
unsigned int _need_reload;
Expand All @@ -56,6 +50,12 @@ class loop {
timed_event_list _event_list_high;
timed_event_list _event_list_low;

loop();
loop(const loop&) = delete;
~loop() noexcept = default;
loop& operator=(const loop&) = delete;
void _dispatching();

public:
enum priority {
low = 0,
Expand Down
Loading

0 comments on commit 09f58ef

Please sign in to comment.