summary refs log tree commit diff
path: root/sys_util/src
diff options
context:
space:
mode:
authorStephen Barber <smbarber@chromium.org>2019-10-25 13:09:32 +0200
committerCommit Bot <commit-bot@chromium.org>2019-11-05 19:49:39 +0000
commit34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7 (patch)
tree4e1c7b9484b7a2bed9503834daa0648af81decac /sys_util/src
parent102278e944dcdc9a489a41644a53c225d8985380 (diff)
downloadcrosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar.gz
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar.bz2
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar.lz
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar.xz
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.tar.zst
crosvm-34fa09918f206c92e5d3a1b3b0d2a7718e2a45d7.zip
sys_util: split volatile_impl macro into volatile_{,at_}impl
Certain types of file descriptors, such as tap devices, aren't compatible with
writing at offsets. Split the volatile_impl macro into two, one for
FileReadWriteVolatile and another for FileReadWriteAtVolatile.

Tweak the macros be usable from other crates.

BUG=chromium:753630
TEST=cargo build

Change-Id: I0671024e24e8b5eaedbde2c1da80e3ec684c06a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1881417
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Commit-Queue: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'sys_util/src')
-rw-r--r--sys_util/src/file_traits.rs160
-rw-r--r--sys_util/src/lib.rs2
2 files changed, 104 insertions, 58 deletions
diff --git a/sys_util/src/file_traits.rs b/sys_util/src/file_traits.rs
index f296d9b..0e4d919 100644
--- a/sys_util/src/file_traits.rs
+++ b/sys_util/src/file_traits.rs
@@ -8,11 +8,6 @@ use std::os::unix::io::{AsRawFd, RawFd};
 
 use data_model::VolatileSlice;
 
-use libc::{
-    c_int, c_void, off64_t, pread64, preadv64, pwrite64, pwritev64, read, readv, size_t, write,
-    writev,
-};
-
 use crate::SharedMemory;
 
 /// A trait for flushing the contents of a file to disk.
@@ -234,32 +229,50 @@ impl<'a, T: FileReadWriteAtVolatile + ?Sized> FileReadWriteAtVolatile for &'a mu
     }
 }
 
+// This module allows the below macros to refer to $crate::file_traits::lib::X and ensures other
+// crates don't need to add additional crates to their Cargo.toml.
+pub mod lib {
+    pub use libc::{
+        c_int, c_void, iovec, off64_t, pread64, preadv64, pwrite64, pwritev64, read, readv, size_t,
+        write, writev,
+    };
+
+    pub use data_model::VolatileSlice;
+}
+
+#[macro_export]
 macro_rules! volatile_impl {
     ($ty:ty) => {
         impl FileReadWriteVolatile for $ty {
-            fn read_volatile(&mut self, slice: VolatileSlice) -> Result<usize> {
+            fn read_volatile(
+                &mut self,
+                slice: $crate::file_traits::lib::VolatileSlice,
+            ) -> std::io::Result<usize> {
                 // Safe because only bytes inside the slice are accessed and the kernel is expected
                 // to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    read(
+                    $crate::file_traits::lib::read(
                         self.as_raw_fd(),
-                        slice.as_ptr() as *mut c_void,
+                        slice.as_ptr() as *mut std::ffi::c_void,
                         slice.size() as usize,
                     )
                 };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
-            fn read_vectored_volatile(&mut self, bufs: &[VolatileSlice]) -> Result<usize> {
-                let iovecs: Vec<libc::iovec> = bufs
+            fn read_vectored_volatile(
+                &mut self,
+                bufs: &[$crate::file_traits::lib::VolatileSlice],
+            ) -> std::io::Result<usize> {
+                let iovecs: Vec<$crate::file_traits::lib::iovec> = bufs
                     .iter()
-                    .map(|s| libc::iovec {
-                        iov_base: s.as_ptr() as *mut c_void,
-                        iov_len: s.size() as size_t,
+                    .map(|s| $crate::file_traits::lib::iovec {
+                        iov_base: s.as_ptr() as *mut std::ffi::c_void,
+                        iov_len: s.size() as $crate::file_traits::lib::size_t,
                     })
                     .collect();
 
@@ -269,37 +282,49 @@ macro_rules! volatile_impl {
 
                 // Safe because only bytes inside the buffers are accessed and the kernel is
                 // expected to handle arbitrary memory for I/O.
-                let ret = unsafe { readv(self.as_raw_fd(), &iovecs[0], iovecs.len() as c_int) };
+                let ret = unsafe {
+                    $crate::file_traits::lib::readv(
+                        self.as_raw_fd(),
+                        &iovecs[0],
+                        iovecs.len() as std::os::raw::c_int,
+                    )
+                };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
-            fn write_volatile(&mut self, slice: VolatileSlice) -> Result<usize> {
+            fn write_volatile(
+                &mut self,
+                slice: $crate::file_traits::lib::VolatileSlice,
+            ) -> std::io::Result<usize> {
                 // Safe because only bytes inside the slice are accessed and the kernel is expected
                 // to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    write(
+                    $crate::file_traits::lib::write(
                         self.as_raw_fd(),
-                        slice.as_ptr() as *const c_void,
+                        slice.as_ptr() as *const std::ffi::c_void,
                         slice.size() as usize,
                     )
                 };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
-            fn write_vectored_volatile(&mut self, bufs: &[VolatileSlice]) -> Result<usize> {
-                let iovecs: Vec<libc::iovec> = bufs
+            fn write_vectored_volatile(
+                &mut self,
+                bufs: &[$crate::file_traits::lib::VolatileSlice],
+            ) -> std::io::Result<usize> {
+                let iovecs: Vec<$crate::file_traits::lib::iovec> = bufs
                     .iter()
-                    .map(|s| libc::iovec {
-                        iov_base: s.as_ptr() as *mut c_void,
-                        iov_len: s.size() as size_t,
+                    .map(|s| $crate::file_traits::lib::iovec {
+                        iov_base: s.as_ptr() as *mut std::ffi::c_void,
+                        iov_len: s.size() as $crate::file_traits::lib::size_t,
                     })
                     .collect();
 
@@ -309,45 +334,60 @@ macro_rules! volatile_impl {
 
                 // Safe because only bytes inside the buffers are accessed and the kernel is
                 // expected to handle arbitrary memory for I/O.
-                let ret = unsafe { writev(self.as_raw_fd(), &iovecs[0], iovecs.len() as c_int) };
+                let ret = unsafe {
+                    $crate::file_traits::lib::writev(
+                        self.as_raw_fd(),
+                        &iovecs[0],
+                        iovecs.len() as std::os::raw::c_int,
+                    )
+                };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
         }
+    };
+}
 
+#[macro_export]
+macro_rules! volatile_at_impl {
+    ($ty:ty) => {
         impl FileReadWriteAtVolatile for $ty {
-            fn read_at_volatile(&mut self, slice: VolatileSlice, offset: u64) -> Result<usize> {
+            fn read_at_volatile(
+                &mut self,
+                slice: $crate::file_traits::lib::VolatileSlice,
+                offset: u64,
+            ) -> std::io::Result<usize> {
                 // Safe because only bytes inside the slice are accessed and the kernel is expected
                 // to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    pread64(
+                    $crate::file_traits::lib::pread64(
                         self.as_raw_fd(),
-                        slice.as_ptr() as *mut c_void,
+                        slice.as_ptr() as *mut std::ffi::c_void,
                         slice.size() as usize,
-                        offset as off64_t,
+                        offset as $crate::file_traits::lib::off64_t,
                     )
                 };
 
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
             fn read_vectored_at_volatile(
                 &mut self,
-                bufs: &[VolatileSlice],
+                bufs: &[$crate::file_traits::lib::VolatileSlice],
                 offset: u64,
-            ) -> Result<usize> {
-                let iovecs: Vec<libc::iovec> = bufs
+            ) -> std::io::Result<usize> {
+                let iovecs: Vec<$crate::file_traits::lib::iovec> = bufs
                     .iter()
-                    .map(|s| libc::iovec {
-                        iov_base: s.as_ptr() as *mut c_void,
-                        iov_len: s.size() as size_t,
+                    .map(|s| $crate::file_traits::lib::iovec {
+                        iov_base: s.as_ptr() as *mut std::ffi::c_void,
+                        iov_len: s.size() as $crate::file_traits::lib::size_t,
                     })
                     .collect();
 
@@ -358,49 +398,53 @@ macro_rules! volatile_impl {
                 // Safe because only bytes inside the buffers are accessed and the kernel is
                 // expected to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    preadv64(
+                    $crate::file_traits::lib::preadv64(
                         self.as_raw_fd(),
                         &iovecs[0],
-                        iovecs.len() as c_int,
-                        offset as off64_t,
+                        iovecs.len() as std::os::raw::c_int,
+                        offset as $crate::file_traits::lib::off64_t,
                     )
                 };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
-            fn write_at_volatile(&mut self, slice: VolatileSlice, offset: u64) -> Result<usize> {
+            fn write_at_volatile(
+                &mut self,
+                slice: $crate::file_traits::lib::VolatileSlice,
+                offset: u64,
+            ) -> std::io::Result<usize> {
                 // Safe because only bytes inside the slice are accessed and the kernel is expected
                 // to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    pwrite64(
+                    $crate::file_traits::lib::pwrite64(
                         self.as_raw_fd(),
-                        slice.as_ptr() as *const c_void,
+                        slice.as_ptr() as *const std::ffi::c_void,
                         slice.size() as usize,
-                        offset as off64_t,
+                        offset as $crate::file_traits::lib::off64_t,
                     )
                 };
 
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
 
             fn write_vectored_at_volatile(
                 &mut self,
-                bufs: &[VolatileSlice],
+                bufs: &[$crate::file_traits::lib::VolatileSlice],
                 offset: u64,
-            ) -> Result<usize> {
-                let iovecs: Vec<libc::iovec> = bufs
+            ) -> std::io::Result<usize> {
+                let iovecs: Vec<$crate::file_traits::lib::iovec> = bufs
                     .iter()
-                    .map(|s| libc::iovec {
-                        iov_base: s.as_ptr() as *mut c_void,
-                        iov_len: s.size() as size_t,
+                    .map(|s| $crate::file_traits::lib::iovec {
+                        iov_base: s.as_ptr() as *mut std::ffi::c_void,
+                        iov_len: s.size() as $crate::file_traits::lib::size_t,
                     })
                     .collect();
 
@@ -411,17 +455,17 @@ macro_rules! volatile_impl {
                 // Safe because only bytes inside the buffers are accessed and the kernel is
                 // expected to handle arbitrary memory for I/O.
                 let ret = unsafe {
-                    pwritev64(
+                    $crate::file_traits::lib::pwritev64(
                         self.as_raw_fd(),
                         &iovecs[0],
-                        iovecs.len() as c_int,
-                        offset as off64_t,
+                        iovecs.len() as std::os::raw::c_int,
+                        offset as $crate::file_traits::lib::off64_t,
                     )
                 };
                 if ret >= 0 {
                     Ok(ret as usize)
                 } else {
-                    Err(Error::last_os_error())
+                    Err(std::io::Error::last_os_error())
                 }
             }
         }
@@ -429,7 +473,9 @@ macro_rules! volatile_impl {
 }
 
 volatile_impl!(File);
+volatile_at_impl!(File);
 volatile_impl!(SharedMemory);
+volatile_at_impl!(SharedMemory);
 
 /// A trait similar to `AsRawFd` but supports an arbitrary number of file descriptors.
 pub trait AsRawFds {
diff --git a/sys_util/src/lib.rs b/sys_util/src/lib.rs
index 8428429..594c79a 100644
--- a/sys_util/src/lib.rs
+++ b/sys_util/src/lib.rs
@@ -17,7 +17,7 @@ mod clock;
 mod errno;
 mod eventfd;
 mod file_flags;
-mod file_traits;
+pub mod file_traits;
 mod fork;
 mod guest_address;
 pub mod guest_memory;