From 04b656e6df460a38e13a6db563f51d64e6b99aa3 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Thu, 20 Nov 2025 11:45:36 +0800 Subject: [PATCH] Add support for readonly FLAT/ZERO VMDK format Currently, it's mainly used for EROFS to merge hundreds of sub-blobs (container image layers) into one block device to avoid having too many block devices (and it would even be impossible for virtio-mmio since legacy IRQs is much limited in libkrun). Why VMDK is useful? Since it seems to be the only standard and simple way to support one-single block device that consists of a collection of multiple file parts among popular virtualization products such as QEMU and VirtualBox. Update the `krun_add_disk2` API to specify the VMDK format: - KRUN_DISK_FORMAT_VMDK Signed-off-by: Gao Xiang --- Cargo.lock | 53 ++++++++++++++++++++++---- include/libkrun.h | 3 ++ src/devices/Cargo.toml | 2 +- src/devices/src/virtio/block/device.rs | 11 +++++- src/devices/src/virtio/block/mod.rs | 1 + src/libkrun/src/lib.rs | 1 + 6 files changed, 61 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30dfe7dff..c713e34f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,6 +164,25 @@ dependencies = [ "serde", ] +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bindgen" version = "0.69.5" @@ -739,23 +758,22 @@ dependencies = [ [[package]] name = "imago" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e45dce78f8a4700ea570488b35af0d192ee0dd355a1d625f07f6ea49ac25bd" +checksum = "5a46885ecbabe024b9e6e3ee9ee3a32ad05adf2b6269f45aa912793d9c54c805" dependencies = [ "async-trait", - "bincode", + "bincode 2.0.1", "cfg-if", "libc", "miniz_oxide", - "nix 0.29.0", + "nix 0.30.1", "page_size", "rustc_version", - "serde", "tokio", "tracing", "vm-memory", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1588,7 +1606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1750ba11a6a6bba3c220da714caa0226aa34e417dce3975d2953062240717dea" dependencies = [ "base64", - "bincode", + "bincode 1.3.3", "bitfield", "bitflags 2.9.1", "byteorder", @@ -1883,6 +1901,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1937,6 +1961,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "804f498a26d5a63be7bbb8bdcd3869c3f286c4c4a17108905276454da0caf8cb" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "vm-fdt" version = "0.3.0" @@ -2136,6 +2166,15 @@ dependencies = [ "windows-targets 0.53.5", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" diff --git a/include/libkrun.h b/include/libkrun.h index af6e70982..1506797d4 100644 --- a/include/libkrun.h +++ b/include/libkrun.h @@ -167,6 +167,9 @@ int32_t krun_add_disk(uint32_t ctx_id, const char *block_id, const char *disk_pa /* Supported disk image formats */ #define KRUN_DISK_FORMAT_RAW 0 #define KRUN_DISK_FORMAT_QCOW2 1 +/* Note: Only supports FLAT/ZERO formats without delta links */ +#define KRUN_DISK_FORMAT_VMDK 2 + /** * Adds a disk image to be used as a general partition for the microVM. The supported * image formats are: "raw" and "qcow2". diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index 298c4dcdf..9ec04c141 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -38,7 +38,7 @@ arch = { path = "../arch" } utils = { path = "../utils" } polly = { path = "../polly" } rutabaga_gfx = { path = "../rutabaga_gfx", features = ["virgl_renderer", "virgl_renderer_next"], optional = true } -imago = { version = "0.1.6", features = ["sync-wrappers", "vm-memory"] } +imago = { version = "0.2.1", features = ["sync-wrappers", "vm-memory"] } [target.'cfg(target_os = "macos")'.dependencies] hvf = { path = "../hvf" } diff --git a/src/devices/src/virtio/block/device.rs b/src/devices/src/virtio/block/device.rs index 5ba02319e..a9ba18f79 100644 --- a/src/devices/src/virtio/block/device.rs +++ b/src/devices/src/virtio/block/device.rs @@ -19,8 +19,8 @@ use std::sync::{Arc, Mutex}; use std::thread::JoinHandle; use imago::{ - file::File as ImagoFile, qcow2::Qcow2, raw::Raw, DynStorage, Storage, StorageOpenOptions, - SyncFormatAccess, + file::File as ImagoFile, qcow2::Qcow2, raw::Raw, vmdk::Vmdk, DynStorage, FormatDriverBuilder, + PermissiveImplicitOpenGate, Storage, StorageOpenOptions, SyncFormatAccess, }; use log::{error, warn}; use utils::eventfd::{EventFd, EFD_NONBLOCK}; @@ -266,6 +266,13 @@ impl Block { )?; SyncFormatAccess::new(raw)? } + ImageType::Vmdk => { + let vmdk = Vmdk::, Arc>>::builder( + Box::new(file), + ) + .open_sync(PermissiveImplicitOpenGate::default())?; + SyncFormatAccess::new(vmdk)? + } }; let disk_image = Arc::new(Mutex::new(disk_image)); diff --git a/src/devices/src/virtio/block/mod.rs b/src/devices/src/virtio/block/mod.rs index 7fe4fb4d4..af0d99d97 100644 --- a/src/devices/src/virtio/block/mod.rs +++ b/src/devices/src/virtio/block/mod.rs @@ -38,4 +38,5 @@ pub enum Error { pub enum ImageType { Raw, Qcow2, + Vmdk, } diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index b5df8c298..2df75efc1 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -703,6 +703,7 @@ pub unsafe extern "C" fn krun_add_disk2( let format = match disk_format { 0 => ImageType::Raw, 1 => ImageType::Qcow2, + 2 => ImageType::Vmdk, _ => { // Do not continue if the user cannot specify a valid disk format return -libc::EINVAL;