ProcessInfoNode does not set up alive supervision for State_Manager components

オープン 初心者向け
#957 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
72/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
cpp
領域
backend, testing

調査の方向性

process_info_node.cppを読み、特に75行目付近のコンストラクターと266行目付近の既存のisSupervised()メソッドを確認してください。StateManagerを対象に含めるよう監視の設定を変更し、監視の構築とLCM_ALIVE_INTERFACE_PATHの注入を対象とする単体テストを追加してください。テストでState_Managerコンポーネントが両方を受け取ることを確認できれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Description

Components configured with application_type: "State_Manager" are never alive-supervised by the Launch Manager, and they cannot send alive notifications.

ProcessInfoNode's constructor sets up alive supervision and injects LCM_ALIVE_INTERFACE_PATH only for ReportingAndSupervised:

https://github.com/eclipse-score/lifecycle/blob/c7502b563/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp#L75

if (app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised)
{
    ...
    supervision_handle_ = process_handling_.supervision_factory.constructSupervision(...);
    ...
    config_.deployment_config.environmental_variables.add(
        "LCM_ALIVE_INTERFACE_PATH", supervision_handle_->getConnectionId());
}

But isSupervised() in the same class treats StateManager as supervised too:

https://github.com/eclipse-score/lifecycle/blob/c7502b563/score/launch_manager/src/daemon/src/process_group_manager/details/process_info_node.cpp#L266-L271

bool ProcessInfoNode::isSupervised() const
{
    const auto app_type = config_.component_properties.application_profile.application_type;
    return app_type == configuration::ApplicationType::ReportingAndSupervised ||
           app_type == configuration::ApplicationType::StateManager;
}

Impact
- A State_Manager process gets no LCM_ALIVE_INTERFACE_PATH, so constructing score::mw::lifecycle::Alive throws std::runtime_error("Failed to get interface path") (AliveImpl::connectToPhmDaemon()).
- No supervision worker is created for the State_Manager component, so a hung or stalled State Manager is never detected, and no recovery action is triggered.
- This contradicts the documented behavior of State_Manager: "uses lifecycle APIs, sends alive notifications, and has permission to change the active Run Target" (configuration.rst, launch_manager.schema.json).

### Problem notifications

Notification needed: no external notification is needed. This is a functional defect in alive supervision, not a vulnerability.
It is safety-relevant (a supervised component is not supervised), so the maintainers of the alive supervision / Component refactoring are informed via this issue.
cc @NicolasFussberger @WilliamRoebuck (reviewer / author of the related changes in #779 / #522)

### Analysis results

**Design intent: State_Manager is meant to be supervised**
- `configuration.rst` / `launch_manager.schema.json`: State_Manager "sends alive notifications".
- `scripts/config_mapping/lifecycle_config.py` `is_supervised()` keeps `alive_supervision` for `State_Manager`.
- `ProcessInfoNode::isSupervised()` and `component.cpp` `isSupervised()` both include `StateManager`.
- Review comment in #779 (https://github.com/eclipse-score/lifecycle/pull/779#discussion_r4375950483):
  > The StateManager application type was also meant to be supervised. We don't really use it now, but would be good to add this already.
- AoU draft in #863: `aou_req__health_monitor__lm_alive_cfg` requires processes using the Health Monitor to be configured as `Reporting_And_Supervised` **or `State_Manager`**.

**Regression history**
| PR | Change |
|---|---|
| #248 | `ConfigurationAdapter::appendAliveInterfaceEnvironment()` injected `LCM_ALIVE_INTERFACE_PATH` for both `ReportingAndSupervised` and `StateManager` (correct). |
| #455 | Config adapter removed. Env injection moved to the `ProcessInfoNode` constructor with a `ReportingAndSupervised`-only condition. The PHM daemon still created a worker for State_Manager, so the worker expected alive notifications that the process could never send (supervision expires if `min_indications > 0`). |
| #522 | Supervision construction moved into the same `ReportingAndSupervised`-only block, so State_Manager now has no supervision at all. The same PR added `isSupervised()` including `StateManager`, but did not use it for this condition. |
| #779 | The new `Component` class was fixed after review (`component.cpp` `isSupervised()` includes `StateManager`), but `ProcessInfoNode` was not. `Graph` still uses `std::variant<ProcessInfoNode, RunTarget>`, so the `Component` fix is not on the production path. |

No unit or integration test checks env injection or supervision construction for State_Manager, so the regression was not detected.

### Solution

Use the existing `isSupervised()` in the `ProcessInfoNode` constructor:

```diff
-    if (app_profile.application_type == configuration::ApplicationType::ReportingAndSupervised)
+    if (isSupervised())
     {

and add a unit test asserting that a State_Manager component gets alive supervision and LCM_ALIVE_INTERFACE_PATH.

(Alternatively, this is resolved once Graph switches from ProcessInfoNode to the new Component class, which already handles StateManager correctly. Until then, the production path needs the fix above.)

### Error Occurrence Rate
**Reproducible**

### How to reproduce
```markdown
1. Configure a component with:
   ```json
   "application_profile": {
       "application_type": "State_Manager",
       "alive_supervision": { "reporting_cycle": 0.5, "failed_cycles_tolerance": 2, "min_indications": 1, "max_indications": 3 }
   }
2. In that application, construct score::mw::lifecycle::Alive and call ReportAlive() periodically.
3. Start the Launch Manager.

Expected: the process receives LCM_ALIVE_INTERFACE_PATH, connects to the alive monitor, and is supervised (stopping it, e.g. kill -STOP, leads to a supervision failure and a recovery action).

Actual (main): LCM_ALIVE_INTERFACE_PATH is not set, Alive construction throws "Failed to get interface path", and no supervision is created, so stopping the process is never detected.
(lifecycle v0.4.0 – v0.6.x: env is not set but a worker is created, so supervision expires and a recovery action runs even when the process is healthy.)

### Error Occurrence  Rate

Reproducible

### How to reproduce

**Steps**
1. Configure a component with application type `State_Manager` and alive supervision, e.g.:
   ```json
   "application_profile": {
       "application_type": "State_Manager",
       "alive_supervision": {
           "reporting_cycle": 0.5,
           "failed_cycles_tolerance": 2,
           "min_indications": 1,
           "max_indications": 3
       }
   }
2. In that application, construct score::mw::lifecycle::Alive and call ReportAlive() periodically.
3. Start the Launch Manager so that the component is launched.

Expected
- The process receives LCM_ALIVE_INTERFACE_PATH and connects to the alive monitor.
- The component is alive-supervised: stopping the process (e.g. kill -STOP <pid>) leads to a supervision failure and the configured recovery action.

Actual (main)
- LCM_ALIVE_INTERFACE_PATH is not set for the process.
- Constructing Alive throws std::runtime_error("Failed to get interface path").
- No supervision is created for the component, so stopping the process is never detected.

Actual (lifecycle v0.4.0 – v0.6.x)
- LCM_ALIVE_INTERFACE_PATH is not set, but the alive monitor still creates a supervision worker for the component.
- Because the process can never report alive, supervision expires and the recovery action runs even when the process is healthy (with min_indications > 0).


### Supporting Information

**Operational state**
- Launch Manager startup, while the State_Manager component is launched as part of the initial Run Target.
- The defect is in `ProcessInfoNode` construction (`Graph` setup), so it applies to every launch of a State_Manager component, not just a specific runtime condition.

**Environment**
- Observed on lifecycle v0.6.1 (Yocto, qemuarm64).
- Confirmed by code inspection on main (c7502b563).
- First lifecycle tag containing #455: v0.4.0. First tag containing #522: v0.7.0.

**Observations**
- State_Manager application: `Alive` construction fails with `std::runtime_error("Failed to get interface path")` (`AliveImpl::connectToPhmDaemon()`), because `LCM_ALIVE_INTERFACE_PATH` is not set.
- lifecycle v0.4.0 – v0.6.x: alive supervision of the State_Manager component expires and the recovery action (Run Target switch) is triggered although the process is running normally.
- main: no "Setting up alive supervision for <component>" debug log for the State_Manager component, i.e. no supervision is created.

**Relevant code (main, c7502b563)**
- `process_info_node.cpp#L75`: supervision construction and `LCM_ALIVE_INTERFACE_PATH` injection, `ReportingAndSupervised` only
- `process_info_node.cpp#L266-L271`: `isSupervised()` includes `StateManager`
- `component.cpp#L25-L63`: new `Component` class handles `StateManager` correctly (not used by `Graph` yet)
- `alive/src/details/AliveImpl.cpp`: `readInterfacePath()` / `connectToPhmDaemon()`

**Current workaround**
- The State Manager does not use `Alive`, and `min_indications: 0` is set for its component to avoid supervision expiry.
- With this workaround, a stalled State Manager is not detected.

**Related**
- #606 Escalate ProcessInfoNode construction failures
- #918 PGM can silently miss supervision failures notifications
- #779 review comment: https://github.com/eclipse-score/lifecycle/pull/779#discussion_r4375950483

### Classification

Critical

### First Affected Release

pre-0.5

### Last Affected Release

not released (main)

### Expected Fixed Release

1.0

### Category

- [x] Safety Relevant
- [ ] Security Relevant
主要言語
C++
スター
7
フォーク
37
平均マージ
2日 11時間
マージ済み PR(30日)
114

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

eclipse-score/lifecycle のほかの issue

eclipse-score/lifecycle の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。