Skip to content

fix qcow2 backing and container status checks#525

Open
GatewayJ wants to merge 3 commits into
boxlite-ai:mainfrom
GatewayJ:codex/fix-qcow2-backing-status
Open

fix qcow2 backing and container status checks#525
GatewayJ wants to merge 3 commits into
boxlite-ai:mainfrom
GatewayJ:codex/fix-qcow2-backing-status

Conversation

@GatewayJ
Copy link
Copy Markdown
Contributor

@GatewayJ GatewayJ commented May 14, 2026

Summary

  • Stop qcow2 backing chain walks cleanly when they reach a raw/ext4 backing file instead of logging an invalid qcow2 magic warning.
  • Refresh libcontainer status before deciding whether a newly started container init process is running.
  • Add focused coverage for raw backing files as terminal backing-chain nodes.

Root Cause

Raw backing files are valid terminal nodes for qcow2 COW children, but the backing-chain walker tried to parse every backing file as qcow2. Separately, the container init health check read the persisted libcontainer state immediately after start without refreshing it from the process state, which could treat a stale Created state as a failed init.

Validation

  • make fmt
  • git diff --check
  • env BOXLITE_DEPS_STUB=1 make test:unit:rust

test:unit:rust ran the full unit suite with native dependency stubs. The boxlite crate had one environment failure unrelated to this change: jailer::tests::test_jailer_full_flow_with_real_tempdir failed because AppArmor disallows bwrap unprivileged user namespaces on this host. All other boxlite tests passed, including the new qcow2 tests; boxlite-shared passed 36/36.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Enhanced QCOW2 disk image handling to properly traverse backing chains containing mixed file types
    • Fixed container status reporting to ensure current state is always reflected instead of returning cached values

@GatewayJ GatewayJ force-pushed the codex/fix-qcow2-backing-status branch from 5e9081b to 2636c09 Compare May 14, 2026 13:45
@GatewayJ GatewayJ changed the title [codex] fix qcow2 backing and container status checks fix qcow2 backing and container status checks May 15, 2026
@GatewayJ GatewayJ marked this pull request as ready for review May 15, 2026 01:28
Comment thread src/guest/src/container/start.rs
@GatewayJ GatewayJ requested a review from DorianZheng June 4, 2026 15:15
@cla-assistant
Copy link
Copy Markdown

cla-assistant Bot commented Jun 4, 2026

CLA assistant check
All committers have signed the CLA.

@cla-assistant
Copy link
Copy Markdown

cla-assistant Bot commented Jun 4, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Two independent fixes address backing-file handling and container state consistency. QCOW2 backing chains now validate candidate files for QCOW2 magic bytes and stop at raw backing files instead of failing to parse them. Container status loading explicitly refreshes stale persisted state before returning status.

Changes

QCOW2 Backing-Chain Magic Validation

Layer / File(s) Summary
QCOW2 Magic Check Infrastructure
src/boxlite/src/disk/qcow2.rs
std::io imports now include Read and Write. New private helper has_qcow2_magic(path) opens a file, reads the first 4 bytes, compares to QCOW2_MAGIC, returns Ok(false) on unexpected EOF, and errors on other failures.
Backing-Chain Magic Validation Integration
src/boxlite/src/disk/qcow2.rs
read_backing_chain pre-checks each backing candidate for QCOW2 magic and breaks traversal when a non-QCOW2 file is detected; unit tests verify that raw disk files are treated as non-QCOW2 and that chain termination occurs at raw backing files.

Container Status Refresh

Layer / File(s) Summary
Container Status Refresh Implementation
src/guest/src/container/start.rs
load_container_status now explicitly calls refresh_status() after loading the container and maps refresh errors to BoxliteError::Internal, returning the refreshed container.status(); unit test verifies that a persisted Stopped state is refreshed to Running.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A hare hops through backing chains,
Checking magic, stopping gains—
Raw files welcome, QCOW2 checked,
And containers refresh, as one'd expect!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix qcow2 backing and container status checks' directly and concisely summarizes the two main changes: qcow2 backing-chain handling for raw files and container status refresh logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/guest/src/container/start.rs (1)

304-310: ⚡ Quick win

Test uses Stopped status but PR describes Created state issue.

The PR summary explains the fix prevents "stale Created state from being treated as a failed init," but this test creates a State with ContainerStatus::Stopped. Consider adding a second test case with ContainerStatus::Created to cover the exact regression scenario described in the PR.

📋 Additional test case for Created status
#[test]
fn load_container_status_refreshes_stale_created_status() {
    let dir = tempfile::TempDir::new().expect("create temp dir");
    let state = State::new(
        "test-container-created",
        ContainerStatus::Created,
        Some(i32::try_from(std::process::id()).expect("current pid fits in i32")),
        dir.path().to_path_buf(),
    );
    state.save(dir.path()).expect("save libcontainer state");

    let status = load_container_status(dir.path()).expect("load container status");

    assert_eq!(status, ContainerStatus::Running);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/guest/src/container/start.rs` around lines 304 - 310, Add a new test that
mirrors the existing Stopped-case but uses ContainerStatus::Created to reproduce
the regression described; create a temp dir, construct a State via State::new
with ContainerStatus::Created (and the current pid), call state.save(...), then
call load_container_status(dir.path()) and assert the returned status equals
ContainerStatus::Running. Name the test to reflect behavior (e.g.,
load_container_status_refreshes_stale_created_status) and reference State::new,
ContainerStatus::Created, state.save, and load_container_status when locating
where to add it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/guest/src/container/start.rs`:
- Around line 304-310: Add a new test that mirrors the existing Stopped-case but
uses ContainerStatus::Created to reproduce the regression described; create a
temp dir, construct a State via State::new with ContainerStatus::Created (and
the current pid), call state.save(...), then call
load_container_status(dir.path()) and assert the returned status equals
ContainerStatus::Running. Name the test to reflect behavior (e.g.,
load_container_status_refreshes_stale_created_status) and reference State::new,
ContainerStatus::Created, state.save, and load_container_status when locating
where to add it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 36bd0b07-6747-4c07-98ee-7c34529071bf

📥 Commits

Reviewing files that changed from the base of the PR and between 2d02d76 and b2206fb.

📒 Files selected for processing (2)
  • src/boxlite/src/disk/qcow2.rs
  • src/guest/src/container/start.rs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants