Skip to content

Retry NM-owned retryable suspend failures before releasing network teardown #121

Description

@Staphylococcus

Problem

The NetworkManager pre-down path treats the same retryable suspend-rail result differently depending on which source acquired the rail first.

When logind already owns the cycle, NetworkManager joins it, observes RetryableTransportFailure, and performs one follow-up attempt before releasing network teardown. When NetworkManager itself owns the cycle and its first attempt produces SuspendRailDisposition::RetryableFailure, handle_network_teardown_rail_disposition returns immediately because its retry branch only handles JoinedInProgress.

The result is a source-ordering asymmetry: an otherwise recoverable first transport failure gets a second opportunity in the logind-first ordering, but not in the NetworkManager-first ordering.

Confirmed reproduction

Reproduced deterministically against dev commit 857535aa0ef6b669b670656ffedb3417fb454239 with this sequence:

  1. logind reports PreparingForSleep=true;
  2. NetworkManager acquires the empty suspend rail as owner;
  3. the configured TV input matches;
  4. the first power_off attempt returns a retryable transport failure;
  5. a second attempt would succeed.

A regression test expecting the cycle to complete currently fails with:

left:  Some(RetryableTransportFailure)
right: Some(Completed)

Only one power_off attempt is made, no system ownership marker is created, and NetworkManager releases teardown.

Expected behavior

An NM-owned RetryableFailure should receive the same single follow-up opportunity that already exists when NetworkManager joins a logind-owned retryable cycle. Retry eligibility must not depend on which event source happened to acquire the rail first.

Acceptance criteria

  • Add a regression test for an NM-owned cycle whose first retryable transport failure is followed by a successful attempt.
  • Make exactly one follow-up attempt before releasing NetworkManager teardown.
  • Record Completed and create the system ownership marker when the follow-up succeeds.
  • Release teardown after the follow-up fails; do not introduce an unbounded retry loop.
  • Preserve existing behavior for authentication failures, non-retryable outcomes, completed cycles, duplicate events, disabled policy, and ordinary network disconnects.
  • Keep the existing joined-owner retry test passing.

Scope

This issue is limited to making the existing suspend-rail retry opportunity source-independent.

It does not introduce or require:

  • a long-lived TV actor or persistent WebSocket;
  • IPC or lifecycle service ownership changes;
  • a new global deadline model;
  • a redesign of transport-delivery or ambiguous-effect semantics;
  • additional retries beyond the existing single follow-up opportunity;
  • NetworkManager route retention, NIC Wake-on-LAN configuration, or topology detection;
  • changes to TV platform selection or pairing behavior.

Future hardening may refine which transport outcomes qualify as retryable. That refinement should remain compatible with the source-independent rail behavior established here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions