ProcessInfoNode does not set up alive supervision for State_Manager components
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Read process_info_node.cpp, especially the constructor near line 75 and the existing isSupervised() method near line 266. Change the supervision setup to cover StateManager and add a unit test for supervision construction and LCM_ALIVE_INTERFACE_PATH injection. Done when the test confirms a State_Manager component receives both.
Written by the indexing model from the issue text.
Description
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:
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
- Dominant language
- C++
- Stars
- 7
- Forks
- 37
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 119
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from eclipse-score/lifecycle
-
Difficulty 2/5 1-3 hours Newbie friendliness 61/100
eclipse-score/lifecycle#880 ·
Maintainers usually reply within 1 day
-
Make integration tests have debug assertsPossibly taken @hskang-amelia claimed this 11 days ago. Opentests
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
eclipse-score/lifecycle#843 ·
Maintainers usually reply within 1 day
-
Move all "Default" asserts to debugPossibly taken @hskang-amelia claimed this 11 days ago. Opencleanup good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
eclipse-score/lifecycle#842 ·
Maintainers usually reply within 1 day
-
cleanup
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
eclipse-score/lifecycle#375 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
eclipse-score/lifecycle#955 ·
Maintainers usually reply within 1 day
All issues in eclipse-score/lifecycle
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
TokisanGames/Terrain3D#1073 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
metasequoiaime/msime#10989 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
KhronosGroup/SPIRV-LLVM-Translator#4151 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
documentation good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
vek-language/vek-lang#1 · 1 comment ·