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 nix::sys::memfd::{memfd_create, MemFdCreateFlag};
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 = {
    let name = CStr::from_bytes_with_nul(b"guest-ram\0").unwrap();
    let fd = memfd_create(name, MemFdCreateFlag::empty())?;
    unsafe { File::from_raw_fd(fd) }
};
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§

Creates the queues for a virtio-blk device.

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.

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.

Examples found in repository?
src/devices/virtio_blk.rs (line 412)
411
412
413
    pub fn read(&mut self, offset: u64, buf: &mut [u8], context: C) -> Result<(), Error> {
        unsafe { self.read_raw(offset, buf.as_mut_ptr(), buf.len(), context) }
    }

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.

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.

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.

Examples found in repository?
src/devices/virtio_blk.rs (line 463)
462
463
464
    pub fn write(&mut self, offset: u64, buf: &[u8], context: C) -> Result<(), Error> {
        unsafe { self.write_raw(offset, buf.as_ptr(), buf.len(), context) }
    }

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.

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.

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.

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.

Returns the result for any completed requests.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.