Commit Graph

92 Commits

Author SHA1 Message Date
Philipp Schuster
5f66a26b2e misc: block: drop extern crate, use modern rust
This commit is part of a series of similar commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-24 22:36:46 +00:00
Eugene Korenevsky
aa67250049 block: qcow: support compressed clusters (zlib, zstd)
Add support of reading and writing compressed clusters.
Support zlib and zstd compressions.

L2 cache: store entire L2 entries, not only standard cluster addresses.

Read path. Offsets of compressed clusters cannot be determined,
therefore replace QcowFile.file_offset_read() with QcowFile.file_read().
This method reads the cluster, decompresses it if necessary and returns
the data to the caller.

Write path. QcowFile.file_offset_write(): since writing to compressed
clusters is not generally possible, allocate a new standard
(non-compressed) cluster if compressed L2 entry is encountered; then
decompress compressed cluster into new cluster; then return offset
inside new cluster to the caller. Processing of standard clusters is
not changed.

Signed-off-by: Eugene Korenevsky <ekorenevsky@aliyun.com>
2025-11-24 08:52:13 +00:00
Philipp Schuster
f5d2973546 block: advisory locks: use byte-range locks to match QEMU behavior
The granularity has significant implications in typical cloud
deployments with network storage. The Linux kernel will sync advisory
locks to network file systems, but these backends may have different
policies and handle locks differently. For example, Netapp speaks a NFS
API but will treat advisory OFD locks for the whole file as mandatory
locks, whereas byte-range locks for the whole file will remain
advisory [0].

As it is a valid use case to prevent multiple CHV instances from
accessing the same disk but disk management software (e.g., Cinder in
OpenStack) should be able to snapshot disks while VMs are running, we
need special control over the lock granularity. Therefore, it is a valid
use case to lock the whole byte range of a disk image without
technically locking the whole file - to get the best of both worlds.

This also brings CHVs behavior in line with QEMU [1].

Whole-file locks remain a valid use case and could be supported later.
This patch only provides the necessary groundwork; making it
configurable is out of scope for now.

[0] https://kb.netapp.com/on-prem/ontap/da/NAS/NAS-KBs/How_is_Mandatory_Locking_supported_for_NFSv4_on_ONTAP_9
[1] <qemu>/util/osdep.c::qemu_lock_fcntl()

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-22 10:38:38 +00:00
Demi Marie Obenour
2be304b392 misc: Check that get_slice() returned a big enough slice
This should be guaranteed by GuestMemory and GuestMemoryRegion, but
those traits are currently safe, so add checks to guard against
incorrect implementations of them.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2025-11-22 10:24:13 +00:00
Philipp Schuster
b4c62bf159 misc: clippy: add semicolon_if_nothing_returned
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-21 09:32:11 +00:00
Philipp Schuster
ea4f07d3bf misc: clippy: add uninlined_format_args
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-21 09:32:11 +00:00
Philipp Schuster
7cb73e9e56 misc: clippy: add unnecessary_semicolon
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-21 09:32:11 +00:00
Philipp Schuster
d1680b9ff9 tests: streamline module names to unit_tests
This better aligns with the rest of the code and makes it clearer
that these tests can run "as is" in a normal hosted environments
without the special test environment.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-11-20 21:15:03 +00:00
Eugene Korenevsky
3791062b23 block: qcow: refactor: extract method cache_l2_cluster()
There are several copy-pasted code fragments in impl QcowFile. All of
them add L2 entry to the cache and one of them (in file_offset_write())
does also allocating new L2 entry if necessary.

Fold all these code fragments (except of one in l2_table() which does
error handling in special way) into cache_l2_cluster() method without
changing the logic.
This will make the code more compact and clean.

Signed-off-by: Eugene Korenevsky <ekorenevsky@aliyun.com>
2025-11-05 16:58:24 +00:00
Philipp Schuster
7536a95424 misc: cleanup &Arc<dyn T> -> &dyn T
Consuming `&Arc<T>` as argument is almost always an antipattern as it
hides whether the callee is going to take over (shared) ownership
(by .clone()) or not. Instead, it is better to consume `&dyn T` or
`Arc<dyn T>` to be more explicit. This commit cleans up the code.

The change is very mechanic and was very easy to implement across the
code base.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-10-28 17:37:49 +00:00
Philipp Schuster
f1206a19df block: fix error style
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-25 21:17:06 +00:00
Ruoqing He
f2dfa7f6e0 misc: Use variables directly in format! string
Fix clippy warning `uninlined_format_args` reported by rustc rustc
1.89.0 (29483883e 2025-08-04).

```console
warning: variables can be used directly in the `format!` string
   --> block/src/lib.rs:649:17
    |
649 |                 info!("{} failed to create io_uring instance: {}", error_msg, e);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
    = note: `#[warn(clippy::uninlined_format_args)]` on by default
help: change this to
    |
649 -                 info!("{} failed to create io_uring instance: {}", error_msg, e);
649 +                 info!("{error_msg} failed to create io_uring instance: {e}");
    |
```

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-09-24 02:28:12 +00:00
Philipp Schuster
c995b72384 build: treewide: clippy: collapse nested ifs, use let chains
This bumps the MSRV to 1.88 (also, Rust edition 2024 is mandatory).

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Philipp Schuster
363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00
Muminul Islam
a9d6807522 block: batch submit requests for fixed VHD
Updated VHD async implementation to call the batch submit
method via the raw async IO layer.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
c4bab33020 block: Enable request submission in batch when using io_uring
Implement the batch submission function for raw disk, default it is
enabled. After parsing the requests this method is
called for better IO latency and bandwidth.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
245bce23fa block, virtio-devices: Support request submission in batch
Cache and batch IO requests after parsing all
items in the queue, improving performance—especially
for small block sizes—by reducing per-request overhead.

Introduced two methods in the AsyncIo trait for batch
submission, with implementation in the raw disk backend.
This method should be called during/after parsing all block IO requests
in the available queue. If the batch submission is not enabled, by
default it does the old way of submitting requests.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Muminul Islam
67ab81874a block: virtio-devices: block: Clarify the return of execute_async()
Instead of returning boolean return an struct of completion status
so that it can be cached for batch submission.

Signed-off-by: Bo Chen <bchen@crusoe.ai>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
2025-09-02 16:29:25 +00:00
Songqian Li
92370e8ff1 block: Using feature bits to check the read-only flag
This patch changes the read-only check using acked features bit, which
will help to check more features.

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-26 15:45:45 +00:00
Songqian Li
cd2c43b489 misc: Fix beta clippy errors
Fix clippy error: "error: manual implementation of `.is_multiple_of()
`" from rustc 1.90.0-beta.1 (788da80fc 2025-08-04).

Signed-off-by: Songqian Li <sionli@tencent.com>
2025-08-07 16:53:59 +00:00
Wei Liu
930a911862 block: Simplify AsyncAdaptor
It shouldn't be necessary to lock the file for the adaptor. This removes
two layers of indirection for QcowDiskSync and VhdxDiskSync.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-07-22 22:00:35 +00:00
Jinank Jain
190d90196f build: Bump vfio and all the dependent crates to latest version
Recently vfio crates have moved to crates.io, thus we should start
consuming the crate from crates.io instead git url.

This results in better versioning instead of tracking some git commit
sha.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2025-07-07 03:05:38 +00:00
Demi Marie Obenour
269976c7b3 block: Remove unnecessary pointer indirection
No functional change intended.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
2025-06-20 10:21:04 +00:00
Yi Wang
80f4bfac00 block: keep lifetime consistent from input to output
Cargo fuzz build report an error:
error: lifetime flowing from input to output with different syntax can be confusing
   --> /home/runner/work/cloud-hypervisor/cloud-hypervisor/block/src/lib.rs:747:13
    |
747 |     fn file(&mut self) -> MutexGuard<F>;
    |             ^^^^^^^^^     ------------- the lifetime gets resolved as `'_`
    |             |
    |             this lifetime flows to the output

error: lifetime flowing from input to output with different syntax can be confusing
  --> /home/runner/work/cloud-hypervisor/cloud-hypervisor/block/src/async_io.rs:68:11
   |
68 |     fn fd(&mut self) -> BorrowedDiskFd;
   |           ^^^^^^^^^     -------------- the lifetime gets resolved as `'_`
   |           |
   |           this lifetime flows to the output

Signed-off-by: Yi Wang <foxywang@tencent.com>
2025-06-16 06:25:57 +00:00
Philipp Schuster
aebbd1aecd misc: block: streamline error Display::fmt()
The changes were mostly automatically applied using the Python
script mentioned in the first commit of this series.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-06-13 19:55:54 +00:00
Philipp Schuster
12b72ba3c1 ci: bump typos
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-06-10 15:52:12 +00:00
Jinank Jain
2bc8d51a60 misc: Fix missing lifetime syntax clippy warning
This was caught by the nightly compiler during cargo fuzz build.

error: lifetime flowing from input to output with different syntax can be confusing
   --> /home/runner/work/cloud-hypervisor/cloud-hypervisor/hypervisor/src/arch/x86/emulator/mod.rs:493:26
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<T> {
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     ----------- the lifetime gets resolved as `'_`
    |                          |
    |                          this lifetime flows to the output
    |
    = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`
help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
    |
493 |     pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<'_, T> {

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2025-06-09 11:19:11 +00:00
Philipp Schuster
dd9bce31e8 misc: block: streamline #[source] and Error impl
This streamlines the Error implementation in the Cloud Hypervisor code
base to match the remaining parts so that everything follows the agreed
conventions. These are leftovers missed in the previous commits.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-22 12:17:13 +00:00
Philipp Schuster
01761c2596 misc: block: streamline #[source] and Error
This streamlines the code base to follow best practices for
error handling in Rust: Each error struct implements
std::error::Error (most due via thiserror::Error derive macro)
and sets its source accordingly.

This allows future work that nicely prints the error chains,
for example.

So far, the convention is that each error prints its
sub error as part of its Display::fmt() impl.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-21 09:09:30 +00:00
Philipp Schuster
71a36e0c69 block: add fcntl module for locking
This is a prerequisite for the next steps.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 08:07:32 +00:00
Philipp Schuster
2da5e10689 block: bind FD lifetime of DiskFile
As we can't use BorrowedFd, we should at least create a similar
safe alternative.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 08:07:32 +00:00
Philipp Schuster
a647d7863c block: enable to get a raw FD of each block device's DiskFile
This is a prerequisite for the next steps.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-05-16 08:07:32 +00:00
Bo Chen
10ee003d66 misc: Fix beta clippy issues
Fixing the following clippy issue using `cargo clippy --fix`:

error: variables can be used directly in the `format!` string
  --> build.rs:25:27
   |
25 |         version.push_str(&format!("-{}", extra_version));
   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args

Signed-off-by: Bo Chen <bchen@crusoe.ai>
2025-05-14 03:44:12 +00:00
Jinank Jain
ea4693a091 misc: Fix clippy error from beta compiler
Rust has a new way of constructing other error and clippy complains if
we are still using the older way to construct error message. Thus,
migrate to the new approach suggested by the clippy.

Warning from beta compiler:

error: this can be `std::io::Error::other(_)`
--> block/src/vhdx/mod.rs:142:17
 |
 | /                 std::io::Error::new(
 | |                     std::io::ErrorKind::Other,
 | |                     format!("Failed to update VHDx header: {e}"),
 | |                 )
 | |_________________^
 |
 = help: for further information visit
https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error
help: use `std::io::Error::other`

                 std::io::Error::other(
                     format!("Failed to update VHDx header: {e}"),

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
2025-04-03 13:11:49 +00:00
Ruoqing He
4de422ad69 misc: Fix clippy - manually reimplementing div_ceil
Reported by 1.86.0-beta.1 (f0cb41030 2025-02-17).

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
2025-03-01 01:02:17 +00:00
Wei Liu
5b29eba636 block: vhdx: use C ABI-qualification for packed structures
This fixes the following issue from beta Clippy:

error: item uses `packed` representation without ABI-qualification
Error:    --> block/src/vhdx/vhdx_header.rs:333:1
    |
331 |   #[repr(packed)]
    |          ------ `packed` representation set here
332 |   #[derive(Clone, Copy, Debug)]
333 | / pub struct RegionTableEntry {
334 | |     pub guid: Uuid,
335 | |     pub file_offset: u64,
336 | |     pub length: u32,
337 | |     pub required: u32,
338 | | }
    | |_^
    |
    = warning: unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI
    = help: qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#repr_packed_without_abi

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-09 13:51:42 +00:00
Wei Liu
e6e78e5986 block: vhdx: reject zero size virtual disk
Some calculation down the road depends on that value not being zero.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-08 22:45:58 +00:00
Wei Liu
bc4a1fd16c block: vhdx: use checked_add in read and write functions
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-08 22:45:58 +00:00
Wei Liu
463c9b8e56 block: vhdx: hoist a check out of IO loops
This reduces one indentation level in the IO loops in the read and write
functions.

No functional change.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-08 22:45:58 +00:00
Rob Bradford
abf5748f64 block: qcow: Use constant in error message
This avoids ambiguity of parameters:

error: ambiguous reference to positional arguments by number in a tuple variant; change this to a named argument
  --> block/src/qcow/mod.rs:48:48
   |
48 |     #[error("File larger than max of {}: {0}", MAX_QCOW_FILE_SIZE)]
   |                                                ^^^^^^^^^^^^^^^^^^

Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
2025-01-06 17:39:45 +00:00
Wei Liu
a66fef407c block: vhdx: properly account for bytes read and written
The counter value in vhdx_io::{read,write} should've been accumulated
over the loop.

Fixes: #6897
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-03 10:25:53 +00:00
Wei Liu
1f7b809619 block: increase the size of temporary vectors
The size was set to one because without VIRTIO_BLK_F_SEG_MAX, the guest
only used one data descriptor per request.

The value 32 is empirically derived from booting a guest. This value
eliminates all SmallVec allocations observable by DHAT.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2025-01-01 18:50:39 +00:00
Wei Liu
ef88b2778e block: vhdx: advance file offset after read and write
This is needed to handle multiple reads or writes in a loop.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
8b55d1e2d4 block: vhdx: rename Header::get_header_as_buffer
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
2df285effd block: vhdx: use calculate_checksum in Header::update_header
It doesn't make sense to open code the same calculation when there is
already a helper function.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
4ea4391f45 block: vhdx: adjust calculate_checksum
It doesn't need to be public. None of its code path returns an error.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
8f8d3c0139 block: vhdx: fix checksum calculation
The checksum field in the original buffer should be zeroed.

The code was zeroing a temporary buffer. That's wrong.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
408467a05f block: vhdx: do not update the VHDX header during parsing
The original code was buggy. It always attempted to update the header,
even when the file was opened as read-only. That led to an error.

The specification states that the headers should be updated when the
first user visible write happens. We can just drop the incorrect code.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
f27b028c18 block: vhdx: drop pub keyword from update_header
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-28 23:59:59 +00:00
Wei Liu
9973d28849 block: drop unused function create_disk_file
Signed-off-by: Wei Liu <liuwe@microsoft.com>
2024-12-21 20:20:29 +00:00