@@ -186,6 +186,26 @@ pub async fn new(file: BdrvChild) -> io::Result<Self> {
impl BlockDriver for BochsImage {
type Options = bindings::BlockdevOptionsGenericFormat;
+ fn probe(buf: &[u8], _filename: &str) -> u16 {
+ let header = match BochsHeader::from_byte_slice(buf) {
+ Some(header) => header,
+ None => return 0,
+ };
+
+ if header.magic != HEADER_MAGIC
+ || header.imgtype != HEADER_TYPE_REDOLOG
+ || header.subtype != HEADER_SUBTYPE_GROWING
+ {
+ return 0;
+ }
+
+ // This driver is better than the C one which returns 100, give it priority
+ match header.version {
+ HEADER_VERSION | HEADER_V1 => 200,
+ _ => 0,
+ }
+ }
+
unsafe fn parse_options(
v: &mut bindings::Visitor,
opts: &mut *mut Self::Options,
@@ -6,7 +6,7 @@
use qemu_api::bindings;
use qemu_api::futures::qemu_co_run_future;
use std::cmp::min;
-use std::ffi::c_void;
+use std::ffi::{c_void, CStr};
use std::io::{self, Error, ErrorKind};
use std::mem::MaybeUninit;
use std::ptr;
@@ -65,6 +65,16 @@ unsafe fn open(
errp: *mut *mut bindings::Error,
) -> std::os::raw::c_int;
+ /// Returns the image format probing priority of this block driver for disk images starting
+ /// with the byte sequence in `buf`. Probing selects the driver that returns the highest
+ /// number.
+ ///
+ /// If the driver doesn't support images starting with `buf`, 0 is returned.
+ fn probe(buf: &[u8], filename: &str) -> u16 {
+ let _ = (buf, filename);
+ 0
+ }
+
/// Returns the size of the image in bytes
fn size(&self) -> u64;
@@ -156,6 +166,19 @@ pub async fn read_uninit<T: SizedIoBuffer>(
}
}
+#[doc(hidden)]
+pub unsafe extern "C" fn bdrv_probe<D: BlockDriver>(
+ buf: *const u8,
+ buf_size: std::os::raw::c_int,
+ filename: *const std::os::raw::c_char,
+) -> std::os::raw::c_int {
+ let buf = unsafe { std::slice::from_raw_parts(buf, buf_size as usize) };
+ match unsafe { CStr::from_ptr(filename) }.to_str() {
+ Ok(filename) => D::probe(buf, filename).into(),
+ Err(_) => 0,
+ }
+}
+
#[doc(hidden)]
pub unsafe extern "C" fn bdrv_open<D: BlockDriver>(
bs: *mut bindings::BlockDriverState,
@@ -266,6 +289,7 @@ macro_rules! block_driver {
::qemu_api::bindings::BlockDriver {
format_name: ::qemu_api::c_str!($fmtname).as_ptr(),
instance_size: ::std::mem::size_of::<$typ>() as i32,
+ bdrv_probe: Some($crate::driver::bdrv_probe::<$typ>),
bdrv_open: Some($crate::driver::bdrv_open::<$typ>),
bdrv_close: Some($crate::driver::bdrv_close::<$typ>),
bdrv_co_preadv_part: Some($crate::driver::bdrv_co_preadv_part::<$typ>),
This adds format probing both to the BlockDriver trait and the bochs-rs block driver. With this, bochs-rs achieves feature parity with its C counterpart. Its probe function returns a higher priority so that it is preferred when both drivers are available. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- rust/block/src/bochs.rs | 20 ++++++++++++++++++++ rust/block/src/driver.rs | 26 +++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-)