Skip to content

tests: map the host's mapping tables in the adapter's VMs - #878

Open
Enrique Saurez (esaurez) wants to merge 1 commit into
devfrom
esaurez/822-pr08-mapping-tables-vms-20261023
Open

Enrique Saurez (esaurez) wants to merge 1 commit into
devfrom
esaurez/822-pr08-mapping-tables-vms-20261023

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #875; this PR retargets to dev when it merges.

Part of #822 (PR 8 of 11: mapping tables in VMs).

The runtime adapter's mapping probes wrote their own sources below /tmp in the guest and mapped them through the root themselves, so no layered VM scenario mapped a host path: every launch shared nothing, and its guest applied an empty table. With the guest's and the host's order in place (#872, #875), the probes now inspect what the host's mapping table put beneath the root, and the layered scenarios share real host paths.

Changes

Probes (tests/runtime-adapter/src/worker/mapping.rs):

  • map [NAME=PATH...] inspects the mappings that the worker applied from the host's table: the export's mount at hostfs/root (export.count, export.type, export.options), the mode and owner of hostfs, and the mount points below the root, in the mount table's order (mounts). For each NAME=PATH, it reports the options of the topmost mount and the kind: directory, file SIZE, link, other, absent, or denied for a path that the guest may not look up. It also reports a directory's entries or a file's contents, whether a write is allowed or refused, and what the overlay's upper holds there. Last, it reports whether the root is latched.
  • map-checks DIR FILE runs the adapter's own mapper checks from the export's directory DIR and file FILE instead of guest-local sources. The checks cover links and magic links at each component, wrong kinds, nested targets, reserved sets, and the read-only race. The race now uses a directory that the guest may write through the export, so only the mapping keeps it read-only.
  • map-refused is removed: a failed mapping of the table now latches the root in a VM.
  • The worker passes the export's root to the mapping probes.

Scenarios (tests/runtime-adapter/tests/vm_layered.rs). A scenario with the mapping table writes sources/ in its sandbox directory. It shares dir read-only at /srv/maps/dir, dir/inner read-write inside it, file.txt read-only, and out read-write. It hides dir/secret with --deny and authorizes sources alone with --share-root:

Scenario Expects
erofs_over_scratch (no shares) Zero mappings do no work: no export is mounted, and nothing is below the root
erofs_over_scratch_maps_the_table The export, mounted rw,nosuid,nodev below a root-owned hostfs of mode 0700. The four mappings, in the plan's order, each with its access, nosuid, and nodev. Targets created on the overlay, but none inside another mapping. The denied file, which its directory does not list and whose lookup the host refuses. Writes that reach only the writable host sources. Then map-checks from the export
erofs_over_ram_maps_the_table, gpt_over_scratch_maps_the_table, gpt_over_ram_maps_the_table The same table over the other image and upper combinations
a_failed_mapping_tears_the_vm_down A fifth share maps out onto /usr/lib/os-release, a file of the image, and is fourth in the plan's order. The launch reports table=failed and mapped=3, sends no Start, and stops the VM gracefully with success 0 and a complete teardown. It exits with 6, and the sources are unchanged
a_read_only_share_inside_a_writable_one_is_refused_before_launch #552: refused before the VM spawns, with nothing of a launch in the store
a_share_inside_a_reserved_tree_is_refused_before_launch, a_share_over_a_reserved_tree_is_refused_before_launch A share inside, and a share over, a tree that the adapter reserves with --reserved
an_unauthorized_host_path_is_refused_before_launch A share outside --share-root

check_record checks the announced mapping count, and every launch that starts the sandbox checks mapped against its table. The README documents the mapping probes and the layered scenarios.

Validation

On #875's head (e54abbce, on dev 4c29c1c5 with #872 merged):

  • Linux: the adapter's protocol-only, host-only, and guest-only (static musl) configurations: fmt, clippy, build, tests, MSRV.
  • Windows: the protocol-only and host-only configurations: fmt, clippy, build, tests, MSRV.
  • host_session 20 times on Linux and on Windows, without a failure.
  • VM suites (vm_layered 32, vm_restart 3, vm_steps 3): WHP 38/38 and MSHV 38/38. KVM runs in CI once this PR targets dev.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The test-focused changes are consistent with the mapping contracts, with no unresolved blocking findings; runtime validation was not rerun during this review.

No open issues 🎉

What changed in this PR

This PR extends the runtime adapter’s end-to-end sandbox coverage by replacing guest-local mapping fixtures with real host exports, building on the host and guest mapping order.

Changes:

  • Updates mapping probes to inspect host-provided mappings and run mapper checks from the export.
  • Adds layered VM scenarios covering mapping access, hidden paths, failed-mapping teardown, and pre-launch refusals.
  • Documents the revised probes and scenarios.
File Description
tests/​runtime-adapter/​tests/​vm_layered.rs Adds host-share fixtures, mapping scenarios, and guest/host assertions.
tests/​runtime-adapter/​src/​worker/​probes.rs Exposes helpers and mount metadata to mapping probes.
tests/​runtime-adapter/​src/​worker/​mapping.rs Inspects applied mappings and runs checks using host exports.
tests/​runtime-adapter/​src/​worker.rs Passes the mounted export to mapping probes.
tests/​runtime-adapter/​README.md Documents probe arguments, facts, and mapping scenarios.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Static review found no blocking issues in the probes, scenario assertions, or integration; VM validation was not independently rerun.

No open issues 🎉

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Static review found no blocking issues in the probes, scenario assertions, worker integration, or documentation; VM suites were not run during this review.

No open issues 🎉

Review effort: Balanced

Base automatically changed from esaurez/822-pr07-host-order-20261023 to dev October 26, 2026 22:10
The runtime adapter's mapping probes wrote their own sources below /tmp in
the guest and mapped them through the root themselves, so no layered
scenario mapped a host path: every launch shared nothing, and its guest
applied an empty table.

The probes now inspect what the host's mapping table put beneath the root,
and map from the host export. map [NAME=PATH...] reports the export's
mount, with its options, and the mode and owner of the directory above it;
the mounts below the root, in order; and for each path, its mount options,
what it shows, its entries or contents, whether a write is allowed, and
what the overlay's upper holds there. map-checks DIR FILE maps the
export's directory DIR and file FILE through mappers of the adapter's own,
as it mapped its own sources before. map-refused is gone: a failed mapping
of the table now latches the root.

The layered scenarios share host directories and a file with the root
through the launch's --share options:

- the table over each image and upper, in the plan's order, whose writes
  reach the writable host sources alone, and which hides a denied path;
- a failed mapping, which blocks Start: the launch stops the VM, which
  tears the root down and leaves the sources as they were;
- a read-only share inside a writable one, shares at and over a tree that
  the adapter reserves, and a share outside the host directories that it
  authorizes, which the launch refuses before it spawns the VM.

Without shares, the image over the scratch checks that zero mappings do no
work: the guest mounts no export, and nothing is mounted below the root.

Part of #822.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 04632931-537b-49f9-acc9-b12024ad6f3a
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the esaurez/822-pr08-mapping-tables-vms-20261023 branch from 090de0a to 47f8bcd Compare October 26, 2026 22:39
Copilot AI balanced review requested due to automatic review settings October 26, 2026 22:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The test-focused changes consistently exercise the existing mapping flow, including host-source effects and failure cleanup, with no blocking issues identified.

No open issues 🎉

Review effort: Balanced

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.

3 participants