fix api deadlock that can appears on two simultaneous actions

With this mutex, we can have deadlock in the following case:
    1/ Thread A processes a /v1/actions/acknowledge-problem request and locks the checkable
    2/ Thread B processes a /v1/actions/add-comment and enters first the ConfigItem::ActivateItems() method and locks the static mutex there and starts the just created comment object, which triggers the OnCommentAdded() event.
    3/ Thread A wants to activate the just created ack comment as well but since the mutex is already locked by TB, it blocks.
    4/ Thread B's OnCommentAdded() even dispatch causes the IcingaDB::CommentAddedHandler() to be called and implicitly triggers full state update for the checkable. Now, the state serialization of that checkable (remember that's the same checkable currently locked by TA) also includes computing its severity, thus it calls either service->GetSeverity() or host->GetSeverity(). However, since computing the checkable severity (as of now) requires acquiring the object lock, and boom - they deadlock each other.
This commit is contained in:
Yannick Martin 2025-05-26 15:05:42 +02:00
parent bba6a76f4a
commit ab58ff2928
No known key found for this signature in database
GPG Key ID: AABC9B180F109264

View File

@ -679,9 +679,6 @@ bool ConfigItem::CommitItems(const ActivationContext::Ptr& context, WorkQueue& u
bool ConfigItem::ActivateItems(const std::vector<ConfigItem::Ptr>& newItems, bool runtimeCreated, bool ConfigItem::ActivateItems(const std::vector<ConfigItem::Ptr>& newItems, bool runtimeCreated,
bool mainConfigActivation, bool withModAttrs, const Value& cookie) bool mainConfigActivation, bool withModAttrs, const Value& cookie)
{ {
static std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
if (withModAttrs) { if (withModAttrs) {
/* restore modified attributes */ /* restore modified attributes */
if (Utility::PathExists(Configuration::ModAttrPath)) { if (Utility::PathExists(Configuration::ModAttrPath)) {