Skip to content

target: roll back activation state on failed activation - #6

Draft
ozan956 wants to merge 2 commits into
masterfrom
activation-rollback
Draft

target: roll back activation state on failed activation#6
ozan956 wants to merge 2 commits into
masterfrom
activation-rollback

Conversation

@ozan956

@ozan956 ozan956 commented Aug 28, 2026

Copy link
Copy Markdown
Member

Target.activate() activates suppliers recursively before activating the requested client. If a later activation step fails, previously activated suppliers could remain active while the failed client stayed bound.

This could leave shared agents, USB interfaces, ports, locks, or other resources in a stale state and cause subsequent activation attempts to fail.

This issue was encountered while extending FT232H/FTDI GPIO support.

The FTDI driver acquires a shared agent before calling proxy.setup(). When setup fails, the driver must release the agent and restore the FTDI interface state itself. This driver-specific cleanup exposed a more general lifecycle problem in Target.activate().

@ozan956 ozan956 self-assigned this Aug 28, 2026
@ozan956 ozan956 added llm review Request a review from a LLM Reviewer and removed llm review Request a review from a LLM Reviewer labels Aug 28, 2026
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

Target.activate() activates the suppliers of a client recursively. If one of
the activation steps fails, the suppliers that were already activated remain
active.

Keep track of the objects activated during the current call and deactivate
them in reverse order if activation fails. Rollback errors are logged while
the original activation error is kept.

Add tests for direct activation failures, nested suppliers, and already active
suppliers.

Signed-off-by: Ozan Durgut <ozan.durgut@analog.com>
Conflict resolution can deactivate clients that were active before a new
activation was started. In this case, rolling back only the newly activated
objects does not restore the original target state.

Save the active resources and drivers before activation and try to activate
them again if they were deactivated during a failed activation. Errors during
rollback or restoration should not replace the original activation error.

Add tests for restoring conflicting drivers and for failures during restoration.

Signed-off-by: Ozan Durgut <ozan.durgut@analog.com>
@ozan956
ozan956 force-pushed the activation-rollback branch from 2891648 to 2dc0fb7 Compare August 29, 2026 07:14
@ozan956 ozan956 added llm review Request a review from a LLM Reviewer and removed llm review Request a review from a LLM Reviewer labels Aug 29, 2026
@github-actions

Copy link
Copy Markdown

LLM review

This series fixes Target.activate() leaving the target in an inconsistent state when
activation fails partway through: fff0742 rolls back suppliers newly activated during a
failed attempt, and 2dc0fb7 additionally restores pre-existing clients that
resolve_conflicts() deactivated to make room for the new client.

Session: 33240410294

Analysis

No CI logs or PR discussion were available specific to this exact commit range (CI notes
input was empty). The PR discussion history does contain two earlier reviews of what is
functionally the same change under different commit hashes (b03ff48/2891648); both minor
issues raised there — raw-repr logging instead of .display_name, and a missing regression
test for the "restore failure preserves original exception" path — are already fixed in the
current fff0742/2dc0fb7.

Independently traced _activate()/activate()/deactivate() and reproduced two scenarios
beyond the existing tests:

  • A 3-level supplier chain (resource -> intermediate driver -> top driver), all active
    before a conflicting failed activation: rollback and restore both happen in correct
    dependency order (suppliers before clients).
  • An unrelated, previously-active resource/driver pair not involved in the conflict is left
    fully untouched by the rollback/restore logic that fixes up the actually-conflicting
    driver.

Restore ordering correctness relies on self.resources/self.drivers preserving
supplier-before-client order, which holds because bind_driver() requires suppliers to
already be bound (and thus already appended) before a client can bind.

No functional bug found; no fixup patches suggested.

CI warnings

CI notes for this run were empty, so no CI annotations could be reviewed.

Verification data

No datasheets/binary artifacts involved. Verification was code-only:

  • pip install -e ., pip install psutil pytest-mock.
  • python -m pytest tests/test_target.py -q — 46 passed.
  • python -m pytest tests/ -q -k "not test_docker_with_daemon" — 454 passed, 62 skipped, 2
    pre-existing/unrelated errors in tests/test_pb2.py (missing pytest-benchmark).
  • pylint labgrid/target.py — 10.00/10.
  • Two standalone reproduction scripts covering multi-level restore ordering and
    non-interference with unrelated previously-active drivers.

Suggested patches

None. Both issues flagged in earlier review rounds of this change are already resolved in
the current commits.

Install instructions

The following one-liner installs the script if not present already:

curl -fSsL "https://raw.githubusercontent.com/analogdevicesinc/doctools/refs/heads/main/ci/scripts/apply-patches.sh"      -o ~/.local/bin/apply-patches.sh &&   grep -q "/apply-patches.sh" ~/.bashrc || echo "source ~/.local/bin/apply-patches.sh" >> $_ ; . $_

More information at AI Usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llm review Request a review from a LLM Reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant