summary refs log tree commit diff
path: root/devices/src/virtio/block.rs
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2018-01-09 08:10:43 +0000
committerchrome-bot <chrome-bot@chromium.org>2018-01-16 21:26:24 -0800
commitc2051921b5b5fb98da43dc91aa49c2a9e6d20a0a (patch)
treefafbb049e2268ce6ddd4983cdd98f36039c07301 /devices/src/virtio/block.rs
parent2b2a7d4d7667a974022a17b6a23d7bc00470be01 (diff)
downloadcrosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar.gz
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar.bz2
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar.lz
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar.xz
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.tar.zst
crosvm-c2051921b5b5fb98da43dc91aa49c2a9e6d20a0a.zip
devices: block: require traits not a file
Allow block to take anything that satisfies the traits it uses. This
will allow for different backends to be used in addition to normal
files. The first new backend will be qcow2 added in subsequent commits.

Change-Id: I571ffc8ad4b5d56f286e134f47a60261d639b160
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/862627
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/virtio/block.rs')
-rw-r--r--devices/src/virtio/block.rs25
1 files changed, 14 insertions, 11 deletions
diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs
index ed78849..1fe2b6b 100644
--- a/devices/src/virtio/block.rs
+++ b/devices/src/virtio/block.rs
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 use std::cmp;
-use std::fs::File;
 use std::io::{self, Seek, SeekFrom, Read, Write};
 use std::os::unix::io::{AsRawFd, RawFd};
 use std::result;
@@ -29,6 +28,9 @@ const VIRTIO_BLK_S_OK: u8 = 0;
 const VIRTIO_BLK_S_IOERR: u8 = 1;
 const VIRTIO_BLK_S_UNSUPP: u8 = 2;
 
+pub trait DiskFile: Read + Seek + Write {}
+impl<D: Read + Seek + Write> DiskFile for D {}
+
 #[derive(PartialEq)]
 enum RequestType {
     In,
@@ -150,7 +152,7 @@ impl Request {
            })
     }
 
-    fn execute<T: Seek + Read + Write>(&self,
+    fn execute<T: DiskFile>(&self,
                                        disk: &mut T,
                                        mem: &GuestMemory)
                                        -> result::Result<u32, ExecuteError> {
@@ -173,15 +175,15 @@ impl Request {
     }
 }
 
-struct Worker {
+struct Worker<T: DiskFile> {
     queues: Vec<Queue>,
     mem: GuestMemory,
-    disk_image: File,
+    disk_image: T,
     interrupt_status: Arc<AtomicUsize>,
     interrupt_evt: EventFd,
 }
 
-impl Worker {
+impl<T: DiskFile> Worker<T> {
     fn process_queue(&mut self, queue_index: usize) -> bool {
         let queue = &mut self.queues[queue_index];
 
@@ -265,9 +267,9 @@ impl Worker {
 }
 
 /// Virtio device for exposing block level read/write operations on a host file.
-pub struct Block {
+pub struct Block<T: DiskFile> {
     kill_evt: Option<EventFd>,
-    disk_image: Option<File>,
+    disk_image: Option<T>,
     config_space: Vec<u8>,
 }
 
@@ -283,11 +285,11 @@ fn build_config_space(disk_size: u64) -> Vec<u8> {
     config
 }
 
-impl Block {
+impl<T: DiskFile> Block<T> {
     /// Create a new virtio block device that operates on the given file.
     ///
     /// The given file must be seekable and sizable.
-    pub fn new(mut disk_image: File) -> SysResult<Block> {
+    pub fn new(mut disk_image: T) -> SysResult<Block<T>> {
         let disk_size = disk_image.seek(SeekFrom::End(0))? as u64;
         if disk_size % SECTOR_SIZE != 0 {
             warn!("Disk size {} is not a multiple of sector size {}; \
@@ -303,7 +305,7 @@ impl Block {
     }
 }
 
-impl Drop for Block {
+impl<T: DiskFile> Drop for Block<T> {
     fn drop(&mut self) {
         if let Some(kill_evt) = self.kill_evt.take() {
             // Ignore the result because there is nothing we can do about it.
@@ -312,7 +314,7 @@ impl Drop for Block {
     }
 }
 
-impl VirtioDevice for Block {
+impl<T: 'static + AsRawFd + DiskFile + Send> VirtioDevice for Block<T> {
     fn keep_fds(&self) -> Vec<RawFd> {
         let mut keep_fds = Vec::new();
 
@@ -387,6 +389,7 @@ impl VirtioDevice for Block {
 
 #[cfg(test)]
 mod tests {
+    use std::fs::File;
     use std::path::PathBuf;
     use sys_util::TempDir;