From 2c510f46f59f97ff6d45f3cfed085ebe184de104 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 | 5 ++--- 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, 17 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3547d469..d64efadfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -739,9 +739,8 @@ dependencies = [ [[package]] name = "imago" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a94a5babb4a05f462d7736c7263ddd7e721ec0c5e5f26b02d888e9edf75b549" +version = "0.1.0-modified" +source = "git+https://gitlab.com/hreitz/imago.git?branch=main#98627977ec7f99a8395bdd8c3125c4386cf85132" dependencies = [ "async-trait", "bincode", 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 b5024d75a..2b713e37b 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.5", features = ["sync-wrappers", "vm-memory"] } +imago = { features = ["sync-wrappers", "vm-memory"], git = "https://gitlab.com/hreitz/imago.git", branch = "main" } [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 c4999accc..af9dc6d4b 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; 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}; @@ -240,6 +240,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(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;