Commit Graph

9499 Commits

Author SHA1 Message Date
Peter Oskolkov
8b60b38281 virtio-devices: block: handle corrupted requests with NEEDS_RESET
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Peter Oskolkov
563303b50a virtio-devices: net: handle corrupted requests with NEEDS_RESET
A buggy or malicious guest may write an inappropriate value into
virtqueue's next_avail field. This will result in an error
when iterating over the queue:

863837ef86/virtio-queue/src/queue.rs (L708)

but this error is (logged and) ignored if pop_descriptor_chain()
is used:

863837ef86/virtio-queue/src/queue.rs (L583)

A reasonable approach, implemented here, is to mark the device as
NEEDS_RESET and ignore further queue events until the guest
reinitializes the device.

How this patch was tested:

Linux kernel was patched to trigger a bad next_avail when the
virtqueue queue counter reaches 5000:

--------------- START OF LINUX KERNEL PATCH ----------
$ git diff
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b784aab668670..989f2a0c64a77 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -15,6 +15,9 @@
 #include <linux/spinlock.h>
 #include <xen/xen.h>

+
+void virtqueue_kick_always(struct virtqueue *vq);
+
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
 #define BAD_RING(_vq, fmt, args...)                            \
@@ -677,6 +680,12 @@ static inline int virtqueue_add_split(
                   struct virtqueue *_vq,
         * new available array entries. */
        virtio_wmb(vq->weak_barriers);
        vq->split.avail_idx_shadow++;
+       {
+        if ((vq->split.avail_idx_shadow % 100) == 0)
+            printk(KERN_ERR "avail idx: %d",
+                  (int)vq->split.avail_idx_shadow);
+               if (vq->split.avail_idx_shadow == 5000)
+               vq->split.avail_idx_shadow = 0;
+       }
        vq->split.vring.avail->idx = cpu_to_virtio16(_vq->vdev,
                                      vq->split.avail_idx_shadow);
        vq->num_added++;
@@ -689,6 +698,11 @@ static inline int virtqueue_add_split(
                  struct virtqueue *_vq,
        if (unlikely(vq->num_added == (1 << 16) - 1))
                virtqueue_kick(_vq);

+       {
+               if (unlikely(vq->split.avail_idx_shadow == 0))
+                       virtqueue_kick_always(_vq);
+       }
+
        return 0;

 unmap_release:
@@ -2515,6 +2529,11 @@ bool virtqueue_kick(struct virtqueue *vq)
 }
 EXPORT_SYMBOL_GPL(virtqueue_kick);

+void virtqueue_kick_always(struct virtqueue *vq)
+{
+       virtqueue_kick_prepare(vq);
+       virtqueue_notify(vq);
+}
 /**
  * virtqueue_get_buf_ctx - get the next used buffer
  * @_vq: the struct virtqueue we're talking about.
--------------- END OF LINUX KERNEL PATCH ----------

Then the kernel was booted, and the host pinged until the
nic became unresponsive:

ping -i 0.002 192.168.4.1

Device status was confirmed using

cat /sys/class/net/eth0/device/status

(it was 0x4f).

Then the device was re-initialized:

DEV_NAME=$(basename $(readlink -f /sys/class/net/eth0/device))
echo $DEV_NAME | tee /sys/bus/virtio/drivers/virtio_net/unbind
echo $DEV_NAME | tee /sys/bus/virtio/drivers/virtio_net/bind
ip link set eth0 up

At this point networking became healthly again.

Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Peter Oskolkov
b5053ae4de virtio-devices: wire driver_status to EpollHandler
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Peter Oskolkov
21bd3ae916 virtio-devices: switch driver_status to Arc<AtomicU8>
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Peter Oskolkov
f77c6ef78b virtio-devices: introduce ActivationContext for device activation
Signed-off-by: Peter Oskolkov <posk@google.com>
2026-03-14 00:21:02 +00:00
Rob Bradford
ab8169c855 build: Bump timeout on integration tests
We now have more tests and are hitting up against the timeout

Signed-off-by: Rob Bradford <rbradford@meta.com>
2026-03-13 21:17:21 +00:00
Shayon Mukherjee
ec389c4fae tests: add integration tests for on-demand snapshot restore
Add UFFD restore tests to common_sequential: basic anonymous RAM,
shared memory, and hugepage-backed zone memory. Each exercises the
full snapshot/restore cycle with memory_restore_mode=ondemand and
verifies CPU count, memory size, and device health after resume.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-03-13 21:17:21 +00:00
Shayon Mukherjee
c417924a29 vmm: memory_manager: add on-demand snapshot restore via userfaultfd
When memory_restore_mode=ondemand is specified on the restore command,
the memory manager creates a userfaultfd descriptor, registers each
guest RAM range for missing-page fault interception, and spawns a
handler thread that serves page faults from the snapshot file using
UFFDIO_COPY. This avoids reading the entire memory-ranges file into
guest RAM before restore completes.

The handler uses epoll to multiplex the userfaultfd and a stop eventfd
for clean shutdown. Concurrent faults from multiple vCPUs are handled
by treating EEXIST as a benign race and waking blocked threads with
UFFDIO_WAKE. Once all pages have been served the handler exits
automatically. If the handler thread panics the VMM is signalled to
exit since the VM cannot continue without page fault service.

MemoryZone gains a backing_page_size field so the handler resolves
fault granularity from the zone rather than the top-level config.

Errors from the UFFD setup path use a structured UffdError enum
and a new MigratableError::OnDemandRestore variant, with a From
impl to keep call sites concise.

The seccomp filter is updated to allow the userfaultfd syscall and
the four uffd ioctls (UFFDIO_API, UFFDIO_COPY, UFFDIO_REGISTER,
UFFDIO_WAKE) under the VMM thread profile.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-03-13 21:17:21 +00:00
Shayon Mukherjee
bf85af907e vmm: config: add memory_restore_mode to RestoreConfig
Add a MemoryRestoreMode enum (Copy | OnDemand) to RestoreConfig so
the restore path can be selected at restore time. Copy preserves the
existing eager read-copy behavior. OnDemand enables userfaultfd-based
demand paging and fails restore if the kernel does not support it.

Validate that prefault=on is not combined with OnDemand mode.

Update the OpenAPI spec with the new enum field.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-03-13 21:17:21 +00:00
Shayon Mukherjee
8340307ace vmm: add uffd abstraction module
Add safe Rust wrappers around the raw userfaultfd ioctls: create
(syscall + API handshake), register (missing-page mode), copy
(resolve fault), and wake (unblock threads after EEXIST race).

These are used by the demand-paged snapshot restore handler in a
subsequent commit.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-03-13 21:17:21 +00:00
Shayon Mukherjee
de37f27945 vmm: add userfaultfd constants module
Add a small constants module with the ioctl numbers and protocol
constants needed for userfaultfd-based demand-paged snapshot restore.
These are derived from the kernel's include/uapi/linux/userfaultfd.h.

Signed-off-by: Shayon Mukherjee <shayonj@gmail.com>
2026-03-13 21:17:21 +00:00
Philipp Schuster
fcdb10373b vmm: migration: emit event for each memory iteration
Emit a "vm.migration-memory-iteration" event after every precopy memory
iteration to allow management software to observe forward progress
during migration.

This event is primarily intended for integration with management
software such as libvirt, where it maps to
VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION.

The event is intentionally independent of any upcoming migration
metrics endpoint. Detailed migration statistics will be exposed via
that endpoint, while this event provides a lightweight progress signal
expected by external management layers.

With this event, management software can detect forward progress during
migration without being blocked on any upcoming migration metrics
endpoint.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
39768704f3 vmm: migration: add iteration metrics and downtime estimation
Add infrastructure to collect metrics during precopy memory migration
iterations.

For each iteration we now track transferred bytes, duration, bandwidth,
and estimate the expected downtime based on the remaining memory of the
current iteration and measured bandwidth. These metrics are logged and
used to decide when to stop the precopy phase.

This also introduces basic termination conditions such as:
  - maximum number of iterations
  - reaching a target downtime
  - maximum migration duration

This is the fundament for an upcoming API call to publicly export
statistics about an ongoing live migration. The changes are, however,
self-contained and helpful by themselves.

The new log now looks somewhat as in the following, providing lots of
helpful insights (especially the bandwidth and estimated downtime are
helpful). The metrics were measured with CHV build with `--release`, a
VM under heavy load (lots of memory writes), same-host TCP
migration and prefault=on:

```
cloud-hypervisor:  12.702682s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=0 total=6144MiB curr=6144MiB bw=1986.83MiB/s transfer=3.09s overhead=0ms est_downtime=0ms elapsed=3.11s avg_bw=1975.41MiB/s
cloud-hypervisor:  15.728419s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=1 total=11562MiB curr=5418MiB bw=1824.44MiB/s transfer=2.97s overhead=56ms est_downtime=2726ms elapsed=6.14s avg_bw=1884.21MiB/s
cloud-hypervisor:  18.710428s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=2 total=16980MiB curr=5418MiB bw=1854.25MiB/s transfer=2.92s overhead=59ms est_downtime=2969ms elapsed=9.12s avg_bw=1862.17MiB/s
cloud-hypervisor:  21.783699s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=3 total=22407MiB curr=5428MiB bw=1799.43MiB/s transfer=3.02s overhead=56ms est_downtime=2926ms elapsed=12.19s avg_bw=1837.92MiB/s
cloud-hypervisor:  25.785696s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=4 total=27825MiB curr=5418MiB bw=1375.53MiB/s transfer=3.94s overhead=62ms est_downtime=3010ms elapsed=16.19s avg_bw=1718.26MiB/s
cloud-hypervisor:  29.000349s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=5 total=33243MiB curr=5418MiB bw=1727.60MiB/s transfer=3.14s overhead=78ms est_downtime=3938ms elapsed=19.41s avg_bw=1712.82MiB/s
cloud-hypervisor:  32.215805s: <vmm> DEBUG:vmm/src/lib.rs:1313 -- Precopy: iter=6 total=38671MiB curr=5429MiB bw=1724.03MiB/s transfer=3.15s overhead=66ms est_downtime=3142ms elapsed=22.62s avg_bw=1709.33MiB/s
cloud-hypervisor:  32.275215s: <vmm> DEBUG:vmm/src/lib.rs:1286 -- Precopy converged: iter=7 total=38671MiB curr=5418MiB bw=1720.46MiB/s transfer=3.15s overhead=66ms est_downtime=3142ms elapsed=22.68s avg_bw=1704.85MiB/s
...
cloud-hypervisor:  33.411682s: <vmm> INFO:vmm/src/lib.rs:1365 -- Precopy complete: iter=8 total=44339MiB curr=5668MiB bw=1799.98MiB/s transfer=3.15s overhead=66ms est_downtime=3142ms elapsed=23.82s avg_bw=1861.45MiB/s
```

# Outlook

We can add user-configurable downtimes and migration downtimes next.

These changes are inspired by [0] but differ significantly in details.

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7033

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
beb5808406 vm-migration: add MemoryMigrationContext for precopy metrics
Introduce MemoryMigrationContext to track internal metrics of an ongoing
precopy memory migration.

The context aggregates information such as iteration count, transferred
bytes, durations, bandwidth, and estimated downtime. This enables
migration logic to make decisions based on runtime characteristics,
such as terminating iterations once the expected downtime is below a
target threshold.

The type is used in the next commit to implement iteration-based
migration metrics.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
447a4c236b vmm: migration: add code comment
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
1f5c5093e4 vmm: migration: refactor memory migration into iteration helpers
Refactor the precopy memory migration path into dedicated helpers that
handle the different migration phases:

  - initial full memory transfer
  - repeated dirty-page iterations while the VM is running
  - final iteration after the VM is paused

This separates concerns in the migration code and provides the
infrastructure needed for collecting migration metrics in the following
changes.

These changes are inspired by [0] but differ significantly in details.

[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7033

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
d4b5502472 vmm: reduce verbosity of dirty logging output
Lower several informational messages in the dirty logging path to
debug level.

These messages are noisy in practice and provide little value since
dirty logging is known to work reliably. More useful migration metrics
(e.g., dirty size per iteration) is logged per iteration in subsequent
commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
b90634a887 vmm: migration: emit lifecycle events
Emit migration lifecycle events via the event monitor.

This aligns migration with other VM lifecycle operations such as boot,
pause, and resume, allowing external management software to observe
migration progress consistently.

Events emitted:
  src:
    vm.migration-started
    vm.migration-finished
    vm.migration-failed
  dst:
    vm.migration-receive-started
    vm.migration-receive-finished
    vm.migration-receive-failed

Please note that these features are independent of an upcoming new
endpoint to fetch migration statistics.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
5c93bcf2d7 vmm: migration: only permit migration of running VMs
Currently, it is not possible to migrate a paused VM. It fails with
the following error:

```
[2026-03-09T14:43:42Z ERROR cloud_hypervisor] Fatal error: HttpApiClient(ServerResponse(InternalServerError, Some("[\"Error from API\",\"Error starting migration sender\",\"Failed to pause migratable component\",\"Invalid transition: InvalidStateTransition(Paused, Paused)\"]")))
Error: ch-remote exited with the following chain of errors:
  0: http client error
  1: Server responded with InternalServerError
  2: Error from API
  3: Error starting migration sender
  4: Failed to pause migratable component
  5: Invalid transition: InvalidStateTransition(Paused, Paused)
```

and even worse, after that, the VM is resumed on the source!

Make the behavior explicit by only allowing migration of VMs in the
Running state. This avoids unintended state transitions during
migration and clarifies the current expected semantics.

Future work could extend the migration protocol to work with paused VMs
and preserve the VM runtime state, allowing paused VMs to be migrated
without altering their state.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Philipp Schuster
b5169ff419 vmm: migration: flatten control flow in send_migration()
Move the error branch to the top and remove unnecessary nesting in
send_migration().

This change is purely mechanical and introduces no functional changes.
It simplifies the control flow and prepares the code for the following
migration-related improvements in this series.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 13:18:07 +00:00
Anatol Belski
3cbbce353e tests: Set image_type=raw for rate limiter block test images
The rate limiter tests create raw block images with dd but do not
specify image_type=raw. Without it the VMM autodetects the format
and enables sector 0 write protection for unknown image types,
causing I/O errors when fio writes to sector 0 and making the
test hang until timeout.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-13 11:14:00 +00:00
Muminul Islam
f6a1d821d7 tests: extend timeout for CVM tests
Confidential VMs require additional time during boot to load the IGVM
image, complete page measurements, and perform Reverse Map Table (RMP)
validation. In addition, PSP latency can further delay the boot
process. Extend the test timeout to accommodate these additional
initialization steps.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-13 08:59:00 +00:00
Muminul Islam
4ba2d770d1 scripts: update CVM test script to add thread
- Modified the integration test script to support CVM test threads
- Add more parameters to cargo nextest to match other files

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-13 08:58:15 +00:00
dependabot[bot]
7d582ec0f6 build: Bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-13 01:30:58 +00:00
Julian Schindel
e265543e3c misc: make MSRV workspace-wide for cloud-hypervisor dependencies
Moves the MSRV requirement to the workspace and expands it to all
cloud-hypervisor dependencies and dev-dependencies.
This improves discoverability for new contributors working on crates
other than the cloud-hypervisor itself and creates consistency regarding
the MSRV of cloud-hypervisor dependencies.
Functionally, this doesn't change anything for dependencies of the
cloud-hypervisor crate as the MSRV requirement is already enforced by CI
when building the cloud-hypervisor with the MSRV versioned compiler.

On-behalf-of: SAP julian.schindel@sap.com
Signed-off-by: Julian Schindel <julian.schindel@cyberus-technology.de>
2026-03-13 01:30:25 +00:00
Demi Marie Obenour
f630694bb0 virtio-devices: Use const fn to compute PCI BAR offsets
This is much less error-prone than manual computation.  No functional
change intended.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2026-03-13 01:30:10 +00:00
Philipp Schuster
001adbe15a hypervisor: mshv: cleanup unneeded Arc
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 01:20:25 +00:00
Philipp Schuster
a747e2b72a hypervisor: kvm: cleanup unneeded Arc
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2026-03-13 01:20:25 +00:00
Muminul Islam
4e7f9595c8 vmm: remove nested virtualization check for arm64/riscv64
Remove the architecture check that prevented nested virtualization
control on arm64 and riscv64. This allows nested virtualization to
be disabled where supported, particularly when using MSHV.

Note that on arm64 disabling nested virtualization may not fully
disable the capability depending on the underlying platform.
Use of this functionality is left to the user's discretion.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2026-03-12 20:52:36 +00:00
Sebastian Walz
2df41986b7 main: add .action(ArgAction::Append) to all .num_args(1..)
With `.num_args(1..)`, multiple values can be specified for a CLI
option, but the option cannot be specified more than once. In my
experience, it’s more common to specify flags with a single argument
multiple times to specify multiple arguments. One might thus expect to
call cloud-hypervisor with e.g. `--disk path=foo --disk path==bar`.

With this commit, both `--disk path=foo path=bar path=baz` and
`--disk path=foo -disk path=bar path=baz` (note: combinations as well)
are allowed.

Signed-off-by: Sebastian Walz <sebastian.walz@secunet.com>
2026-03-12 19:17:27 +00:00
Julian Schindel
84b8d25bb6 vm-migration: fix UB in MemoryRangeTable::read_from
The pointer created by `Vec::as_ptr` may not be used for mutation of the
underlying data [0].
This PR switches to `Vec::as_mut_ptr` and uses `cast` to avoid
mutability changes when casting.
Also improves safety reasoning, separates the unsafe call from the
call to `read_exact` to improve clarity and simplifies the vector
creation.

[0]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html#method.as_ptr

On-behalf-of: SAP julian.schindel@sap.com
Signed-off-by: Julian Schindel <julian.schindel@cyberus-technology.de>
2026-03-12 18:30:03 +00:00
Anatol Belski
32d339c59e block: qcow: Migrate debug/test helpers to BlockResult
Switch l2_table(), refcount_block(), and first_zero_refcount()
to BlockResult. These are public inspection helpers with no
callers within the crate.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
1accf47db4 block: qcow: Migrate convert() to BlockResult
Switch the public convert() entry point to BlockResult. Inner
calls to functions already returning BlockResult propagate
naturally; those still returning qcow::Error get map_err
bridges.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
4930d93090 block: qcow: Migrate convert_reader() to BlockResult
Switch convert_reader() to BlockResult, preserving the original
qcow::Error variants as the BlockError source. The inner
convert_reader_writer() call now propagates naturally. Callers
get map_err bridges where they still return qcow::Error.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
748666fe4d block: qcow: Migrate convert_reader_writer() to BlockResult
Switch convert_reader_writer() to BlockResult, preserving the
original qcow::Error variants as the BlockError source. The
inner convert_copy() call now propagates BlockResult naturally.
Callers get map_err bridges where they still return qcow::Error.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
c59c5687d2 block: qcow: Migrate convert_copy() to BlockResult
Switch convert_copy() to BlockResult, preserving the original
qcow::Error variants as the BlockError source for diagnostics.
A map_err bridge at the caller converts back where needed.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
732cddb8b3 block: qcow: Migrate dirty/corrupt bit helpers to BlockResult
Switch the header dirty and corrupt bit helpers from
qcow::Result to BlockResult. Their callers either discard
the result or unwrap in tests, so no caller signatures change.
A map_err bridge in parse_qcow() converts back where needed.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
4fea912d18 block: qcow: Add open_disk_image helper with path context
Add a small helper in the block crate that opens a disk image
file and wraps any failure in a BlockError carrying the file
path and operation context. Use it from the vmm device manager
so that a failed open now reports which path couldn't be opened.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
2bcbe25539 block: qcow: Add backing file path to qcow error context
Extend the BackingFileIo and BackingFileOpen variants of
qcow::Error with a path field so that backing file failures
report which file was involved. The path is populated from
the backing file configuration.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
b1bc376c91 block: Make detect_image_type return BlockResult with context
Convert detect_image_type() from io::Result to BlockResult so
that I/O failures carry the operation name in the error context.
Update the corresponding vmm error variant to wrap BlockError.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
58bdfaee3a block: qcow: QcowDiskSync returns BlockResult with path context
Change QcowDiskSync::new() to return BlockResult instead of
qcow::Result, mapping format specific errors to the appropriate
BlockErrorKind at the crate boundary. The vmm caller attaches
the disk image path to the error so failures identify which
file was being opened.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
8c2794533d block: qcow: impl AsFd for RawFile and QcowRawFile
Implement AsFd for both RawFile and QcowRawFile by delegating to
the inner File handle. This enables safe fd borrowing through the
standard AsFd trait, which is a prerequisite for replacing unsafe
libc::dup calls with BorrowedFd::try_clone_to_owned().

Suggested-by: Rob Bradford <rbradford@rivosinc.com>
Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
9be154b03c block: Add BlockResult, From<io::Error>
Add the public BlockResult type alias and a From<io::Error>
impl so that bare I/O errors automatically convert into
BlockError with BlockErrorKind::Io via the ? operator.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
4c29548736 block: Add BlockError constructors and builder methods
Add the construction and inspection API for BlockError,
consisting on constructors that accept a kind and optional
source, builder methods that attach context after
the fact, and accessors for retrieving the kind, context,
and typed source references. The builder pattern allows
callers to enrich errors at each level of the call stack.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
d5467dca8e block: Add BlockError struct with Display and Error impls
Add the single public crate error type. It combines a
BlockErrorKind for classification, an optional boxed source
for the underlying cause, and an optional ErrorContext for
diagnostics. Display renders the kind and context only,
leaving source traversal to error reporters so the cause
chain is not duplicated in human readable output.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
55504177cb block: Add ErrorContext for path/offset/op diagnostics
Add a struct that carries optional diagnostic metadata - file
path, byte offset, and operation name that can be attached
to any BlockError. This lets errors report *where* and *during
what* a failure occurred, which is especially useful when the
same I/O kind shows up at multiple call sites.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
e4e74a9d93 block: Add BlockErrorKind classification enum
Add a small, stable enum that classifies block errors into
broad categories - I/O, invalid format, unsupported feature,
corrupt image, out of bounds, not found, overflow. Callers
match on this for control flow rather than on format specific
error variants.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Anatol Belski
f184a0f0f3 block: Add error module skeleton
Introduce error.rs as the home for a unified error hierarchy that
will replace the per format error types at the public crate
boundary. This commit is intentionally empty beyond the copyright
header and module declaration in lib.rs.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
2026-03-12 14:18:45 +00:00
Emir Beganovic
623af62743 block: Implement write_zeroes and punch_hole for AIO backend
The AIO block backend advertises VIRTIO_BLK_F_WRITE_ZEROES
and VIRTIO_BLK_F_DISCARD to guests because the filesystem
probe (supports_sparse_operations) returns true on ext4/XFS.
However, RawFileAsyncAio::write_zeroes() and punch_hole()
return errors because Linux AIO (io_submit) has no IOCB
command for fallocate.

When io_uring is unavailable (e.g. io_uring_disabled=2, a
common security hardening on enterprise Linux), Cloud
Hypervisor falls back to the AIO backend. The guest
negotiates the feature, issues WRITE_ZEROES requests, and
gets I/O errors.

Implement write_zeroes and punch_hole using synchronous
libc::fallocate() calls, matching the pattern used by the
sync backend (RawFileSync). A VecDeque-based completion
list signals results to the caller via the existing eventfd
mechanism.

Unit tests mirror the existing raw_sync.rs test suite.
Integration tests add AIO-specific variants of the discard
and fstrim tests using _disable_io_uring=on.

Signed-off-by: Emir Beganovic <beganovic.emir@gmail.com>
2026-03-12 12:08:01 +00:00
dependabot[bot]
8671e193ff build: Bump docker/metadata-action from 5 to 6
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-12 12:28:31 +00:00