From 4fea912d181d41da3699bebb94f62536dc063ad8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 5 Mar 2026 18:26:54 +0100 Subject: [PATCH] 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 --- block/src/lib.rs | 12 +++++++++++- vmm/src/device_manager.rs | 19 ++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/block/src/lib.rs b/block/src/lib.rs index 6507076a7..f477cd36c 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -32,7 +32,7 @@ pub mod vhdx_sync; use std::alloc::{Layout, alloc_zeroed, dealloc}; use std::collections::VecDeque; use std::fmt::{self, Debug}; -use std::fs::File; +use std::fs::{File, OpenOptions}; use std::io::{self, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; use std::os::linux::fs::MetadataExt; use std::os::unix::io::AsRawFd; @@ -1065,6 +1065,16 @@ pub fn read_aligned_block_size(f: &mut File) -> std::io::Result> { Ok(data) } +/// Open a disk image file, returning a [`BlockError`] with path context +/// on failure. +pub fn open_disk_image(path: &Path, options: &OpenOptions) -> BlockResult { + options.open(path).map_err(|e| { + BlockError::new(BlockErrorKind::Io, e) + .with_op(ErrorOp::Open) + .with_path(path) + }) +} + /// Determine image type through file parsing. pub fn detect_image_type(f: &mut File) -> BlockResult { let block = read_aligned_block_size(f) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 325084395..04b9e3b44 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -41,7 +41,7 @@ use block::raw_sync::RawFileDiskSync; use block::vhdx_sync::VhdxDiskSync; use block::{ ImageType, block_aio_is_supported, block_io_uring_is_supported, detect_image_type, - preallocate_disk, vhdx, + open_disk_image, preallocate_disk, vhdx, }; #[cfg(feature = "io_uring")] use block::{fixed_vhd_async::FixedVhdDiskAsync, raw_async::RawFileDisk}; @@ -177,7 +177,7 @@ pub enum DeviceManagerError { /// Cannot open disk path #[error("Cannot open disk path")] - Disk(#[source] io::Error), + Disk(#[source] BlockError), /// Cannot create vhost-user-net device #[error("Cannot create vhost-user-net device")] @@ -2663,15 +2663,12 @@ impl DeviceManager { options.custom_flags(libc::O_DIRECT); } // Open block device path - let mut file: File = options - .open( - disk_cfg - .path - .as_ref() - .ok_or(DeviceManagerError::NoDiskPath)? - .clone(), - ) - .map_err(DeviceManagerError::Disk)?; + let disk_path = disk_cfg + .path + .as_ref() + .ok_or(DeviceManagerError::NoDiskPath)?; + let mut file: File = + open_disk_image(disk_path, &options).map_err(DeviceManagerError::Disk)?; let detected_image_type = detect_image_type(&mut file).map_err(DeviceManagerError::DetectImageType)?;