summary refs log tree commit diff
path: root/disk
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-01-07 17:51:04 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-13 21:16:29 +0000
commitd5aa9954237f9eb9c7ec468362fb8262f0975429 (patch)
treeb003550c00fa349cf0eed758b6a5ce02508f5290 /disk
parent54305cd5e2d52d274c20dd294c9c869a0115e96d (diff)
downloadcrosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar.gz
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar.bz2
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar.lz
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar.xz
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.tar.zst
crosvm-d5aa9954237f9eb9c7ec468362fb8262f0975429.zip
disk: use seek to determine file length
Add a new disk-specific DiskGetLen trait which uses io::Seek instead of
File::metadata() to determine the length so that it works on raw block
devices (e.g. /dev/sda) as well as regular files.

BUG=b:146811529
TEST=`crosvm run --disk /dev/sda` and verify block device length

Change-Id: I6936863490efaa479a3c8745c75c373748c800a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1990855
Reviewed-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Trent Begin <tbegin@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'disk')
-rw-r--r--disk/src/composite.rs8
-rw-r--r--disk/src/disk.rs23
-rw-r--r--disk/src/qcow/mod.rs7
3 files changed, 26 insertions, 12 deletions
diff --git a/disk/src/composite.rs b/disk/src/composite.rs
index bd21b33..06c1545 100644
--- a/disk/src/composite.rs
+++ b/disk/src/composite.rs
@@ -9,13 +9,11 @@ use std::io::{self, ErrorKind, Read, Seek, SeekFrom};
 use std::ops::Range;
 use std::os::unix::io::RawFd;
 
-use crate::{create_disk_file, DiskFile, ImageType};
+use crate::{create_disk_file, DiskFile, DiskGetLen, ImageType};
 use data_model::VolatileSlice;
 use protos::cdisk_spec;
 use remain::sorted;
-use sys_util::{
-    AsRawFds, FileGetLen, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt,
-};
+use sys_util::{AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, WriteZeroesAt};
 
 #[sorted]
 #[derive(Debug)]
@@ -210,7 +208,7 @@ impl CompositeDiskFile {
     }
 }
 
-impl FileGetLen for CompositeDiskFile {
+impl DiskGetLen for CompositeDiskFile {
     fn get_len(&self) -> io::Result<u64> {
         Ok(self.length())
     }
diff --git a/disk/src/disk.rs b/disk/src/disk.rs
index e3e7e63..a67d91a 100644
--- a/disk/src/disk.rs
+++ b/disk/src/disk.rs
@@ -10,8 +10,7 @@ use std::io::{self, Read, Seek, SeekFrom, Write};
 use libc::EINVAL;
 use remain::sorted;
 use sys_util::{
-    AsRawFds, FileGetLen, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole,
-    WriteZeroesAt,
+    AsRawFds, FileReadWriteAtVolatile, FileSetLen, FileSync, PunchHole, SeekHole, WriteZeroesAt,
 };
 
 mod qcow;
@@ -40,11 +39,27 @@ pub enum Error {
 
 pub type Result<T> = std::result::Result<T, Error>;
 
+/// A trait for getting the length of a disk image or raw block device.
+pub trait DiskGetLen {
+    /// Get the current length of the disk in bytes.
+    fn get_len(&self) -> io::Result<u64>;
+}
+
+impl DiskGetLen for File {
+    fn get_len(&self) -> io::Result<u64> {
+        let mut s = self;
+        let orig_seek = s.seek(SeekFrom::Current(0))?;
+        let end = s.seek(SeekFrom::End(0))? as u64;
+        s.seek(SeekFrom::Start(orig_seek))?;
+        Ok(end)
+    }
+}
+
 /// The prerequisites necessary to support a block device.
 #[rustfmt::skip] // rustfmt won't wrap the long list of trait bounds.
 pub trait DiskFile:
     FileSetLen
-    + FileGetLen
+    + DiskGetLen
     + FileSync
     + FileReadWriteAtVolatile
     + PunchHole
@@ -55,7 +70,7 @@ pub trait DiskFile:
 }
 impl<
         D: FileSetLen
-            + FileGetLen
+            + DiskGetLen
             + FileSync
             + PunchHole
             + FileReadWriteAtVolatile
diff --git a/disk/src/qcow/mod.rs b/disk/src/qcow/mod.rs
index f449d1d..6bd9719 100644
--- a/disk/src/qcow/mod.rs
+++ b/disk/src/qcow/mod.rs
@@ -10,8 +10,8 @@ use data_model::{VolatileMemory, VolatileSlice};
 use libc::{EINVAL, ENOSPC, ENOTSUP};
 use remain::sorted;
 use sys_util::{
-    error, FileGetLen, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync,
-    PunchHole, SeekHole, WriteZeroesAt,
+    error, FileReadWriteAtVolatile, FileReadWriteVolatile, FileSetLen, FileSync, PunchHole,
+    SeekHole, WriteZeroesAt,
 };
 
 use std::cmp::{max, min};
@@ -24,6 +24,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
 use crate::qcow::qcow_raw_file::QcowRawFile;
 use crate::qcow::refcount::RefCount;
 use crate::qcow::vec_cache::{CacheMap, Cacheable, VecCache};
+use crate::DiskGetLen;
 
 #[sorted]
 #[derive(Debug)]
@@ -1571,7 +1572,7 @@ impl FileSetLen for QcowFile {
     }
 }
 
-impl FileGetLen for QcowFile {
+impl DiskGetLen for QcowFile {
     fn get_len(&self) -> io::Result<u64> {
         Ok(self.virtual_size())
     }