Struct VirtioBlkQueue

Source
pub struct VirtioBlkQueue<'a, C> { /* private fields */ }
Expand description

A queue of a virtio-blk device.

This is used to send block I/O requests to the device and receive completions. Note that calling transport specific functions may need to be called before or after certain operations on the VirtioBlkQueue:

When a request is submitted, the user provides a “context” of type C that will later be returned in the completion for that request.

Use setup_queues to create the queues for a device.

§Examples

use rustix::fs::{memfd_create, MemfdFlags};
use std::ffi::CStr;
use std::fs::File;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::sync::{Arc, RwLock};

// Connect to the vhost-user socket and create the queues
let mut vhost = VhostUser::new("/tmp/vhost.sock", VirtioFeatureFlags::VERSION_1.bits())?;
let mut vhost = Arc::new(RwLock::new(Box::new(vhost) as Box<VirtioBlkTransport>));
let mut queues = VirtioBlkQueue::<&'static str>::setup_queues(&vhost, 1, 128)?;

// Create shared memory that is visible for the device
let mem_file: File = memfd_create("guest-ram", MemfdFlags::empty())?.into();
mem_file.set_len(512)?;
let mut mem = unsafe { memmap2::MmapMut::map_mut(&mem_file) }?;
vhost.write().unwrap().map_mem_region(mem.as_ptr() as usize, 512, mem_file.as_raw_fd(), 0)?;

// Submit a request
queues[0].read(0, &mut mem, "my-request-context")?;
vhost.read().unwrap().get_submission_notifier(0).notify()?;

// Wait for its completion
let mut done = false;
while !done {
    let ret = vhost.read().unwrap().get_completion_fd(0).read();
    if ret.is_err() {
        continue;
    }

    for c in queues[0].completions() {
        println!("Completed request with context {:?}, return value {}", c.context, c.ret);
        done = true;
    }
}

Implementations§

Source§

impl<'a, C> VirtioBlkQueue<'a, C>

Source

pub fn setup_queues( transport: &mut VirtioBlkTransport, num_queues: usize, queue_size: u16, ) -> Result<Vec<Self>, Error>

Creates the queues for a virtio-blk device.

Source

pub unsafe fn readv( &mut self, offset: u64, iovec: *const iovec, iovcnt: usize, context: C, ) -> Result<(), Error>

Reads from the disk image into a given iovec.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

§Safety

The caller must ensure that the iovec/iovcnt pair is valid and all memory regions referenced by it are safe to access.

Source

pub unsafe fn read_raw( &mut self, offset: u64, buf: *mut u8, len: usize, context: C, ) -> Result<(), Error>

Reads from the disk image into a given buffer.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

§Safety

The caller must ensure that the buffer described by buf and len is safe to access.

Source

pub fn read( &mut self, offset: u64, buf: &mut [u8], context: C, ) -> Result<(), Error>

Reads from the disk image into a given byte slice.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

Source

pub unsafe fn writev( &mut self, offset: u64, iovec: *const iovec, iovcnt: usize, context: C, ) -> Result<(), Error>

Writes to the disk image from a given iovec.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

§Safety

The caller must ensure that the iovec/iovcnt pair is valid and all memory regions referenced by it are safe to access.

Source

pub unsafe fn write_raw( &mut self, offset: u64, buf: *const u8, len: usize, context: C, ) -> Result<(), Error>

Writes to the disk image from a given buffer.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

§Safety

The caller must ensure that the buffer described by buf and len is safe to access.

Source

pub fn write( &mut self, offset: u64, buf: &[u8], context: C, ) -> Result<(), Error>

Writes to the disk image from a given byte slice.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

Source

pub fn discard( &mut self, offset: u64, len: u64, context: C, ) -> Result<(), Error>

Discards an area in the disk image.

After completion, the content of the specified area is undefined. Discard is only a hint and doing nothing is a valid implementation. This means that the discarded data may remain accessible, this is not a way to safely delete data.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

Source

pub fn write_zeroes( &mut self, offset: u64, len: u64, unmap: bool, context: C, ) -> Result<(), Error>

Zeroes out an area in the disk image.

If unmap is true, the area is tried to be deallocated if we know that it will read back as all zeroes afterwards. If it is false, allocated parts will remain allocated.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

Source

pub fn flush(&mut self, context: C) -> Result<(), Error>

Flushes the disk cache.

This ensures that on successful completion, any requests that had completed before this flush request was issued are not sitting in any writeback cache, but are actually stored on disk.

context is an arbitrary caller-defined value that is returned in the corresponding Completion to allow associating the result with a specific request.

Source

pub fn completions(&mut self) -> CompletionIter<'_, 'a, C>

Returns the result for any completed requests.

Source

pub fn avail_notif_needed(&mut self) -> bool

Source

pub fn set_used_notif_enabled(&mut self, enabled: bool)

Auto Trait Implementations§

§

impl<'a, C> Freeze for VirtioBlkQueue<'a, C>

§

impl<'a, C> !RefUnwindSafe for VirtioBlkQueue<'a, C>

§

impl<'a, C> Send for VirtioBlkQueue<'a, C>
where C: Send,

§

impl<'a, C> Sync for VirtioBlkQueue<'a, C>
where C: Sync,

§

impl<'a, C> Unpin for VirtioBlkQueue<'a, C>

§

impl<'a, C> !UnwindSafe for VirtioBlkQueue<'a, C>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.