summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2018-08-23 13:34:56 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-17 21:34:50 -0700
commita99954cb7c076c9585aba416afdcb86f67e3676f (patch)
tree359c901223f8bb11e1227f4b71e082c0d45f4b0a /src
parent4a55609f50ae6a66d0b3c255e18bd8e78a283242 (diff)
downloadcrosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar.gz
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar.bz2
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar.lz
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar.xz
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.tar.zst
crosvm-a99954cb7c076c9585aba416afdcb86f67e3676f.zip
sys_util: remove Scm struct and sock_ctrl_msg C library
The Scm object was made to reduce the number of heap allocations in
the hot paths of poll loops, at the cost of some code complexity. As it
turns out, the number of file descriptors being sent or received is
usually just one or limited to a fixed amount that can easily be covered
with a fixed size stack allocated buffer.

This change implements that solution, with heap allocation as a backup
in the rare case that many file descriptors must be sent or received.

This change also moves the msg and cmsg manipulation code out of C and
into pure Rust. The move was necessary to allocate the correct amount
of buffer space at compile time. It also improves safety by reducing the
scope of unsafe code. Deleting the code for building the C library is
also a nice bonus.

Finally, the removal of the commonly used Scm struct required
transitioning existing usage to the ScmSocket trait based methods. This
includes all those changes.

TEST=cargo test
BUG=None

Change-Id: If27ba297f5416dd9b8bc686ce740866912fa0aa0
Reviewed-on: https://chromium-review.googlesource.com/1186146
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src')
-rw-r--r--src/linux.rs8
-rw-r--r--src/main.rs8
-rw-r--r--src/plugin/process.rs21
3 files changed, 11 insertions, 26 deletions
diff --git a/src/linux.rs b/src/linux.rs
index a142d1d..a5c87de 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -729,8 +729,6 @@ fn run_control(mut linux: RunnableLinuxVm,
                control_sockets: Vec<UnlinkUnixDatagram>,
                balloon_host_socket: UnixDatagram,
                sigchld_fd: SignalFd) -> Result<()> {
-    const MAX_VM_FD_RECV: usize = 1;
-
     // Paths to get the currently available memory and the low memory threshold.
     const LOWMEM_MARGIN: &'static str = "/sys/kernel/mm/chromeos-low_mem/margin";
     const LOWMEM_AVAILABLE: &'static str = "/sys/kernel/mm/chromeos-low_mem/available";
@@ -817,8 +815,6 @@ fn run_control(mut linux: RunnableLinuxVm,
     }
     vcpu_thread_barrier.wait();
 
-    let mut scm = Scm::new(MAX_VM_FD_RECV);
-
     'poll: loop {
         let events = {
             match poll_ctx.wait() {
@@ -945,7 +941,7 @@ fn run_control(mut linux: RunnableLinuxVm,
                 }
                 Token::VmControl { index } => {
                     if let Some(socket) = control_sockets.get(index as usize) {
-                        match VmRequest::recv(&mut scm, socket.as_ref()) {
+                        match VmRequest::recv(socket.as_ref()) {
                             Ok(request) => {
                                 let mut running = true;
                                 let response =
@@ -953,7 +949,7 @@ fn run_control(mut linux: RunnableLinuxVm,
                                                     &mut linux.resources,
                                                     &mut running,
                                                     &balloon_host_socket);
-                                if let Err(e) = response.send(&mut scm, socket.as_ref()) {
+                                if let Err(e) = response.send(socket.as_ref()) {
                                     error!("failed to send VmResponse: {:?}", e);
                                 }
                                 if !running {
diff --git a/src/main.rs b/src/main.rs
index bd2b632..de93f1b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -47,7 +47,7 @@ use std::string::String;
 use std::thread::sleep;
 use std::time::Duration;
 
-use sys_util::{Scm, getpid, kill_process_group, reap_child, syslog};
+use sys_util::{getpid, kill_process_group, reap_child, syslog};
 use qcow::QcowFile;
 
 use argument::{Argument, set_arguments, print_help};
@@ -519,7 +519,6 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> {
 }
 
 fn stop_vms(args: std::env::Args) -> std::result::Result<(), ()> {
-    let mut scm = Scm::new(1);
     if args.len() == 0 {
         print_help("crosvm stop", "VM_SOCKET...", &[]);
         println!("Stops the crosvm instance listening on each `VM_SOCKET` given.");
@@ -532,7 +531,7 @@ fn stop_vms(args: std::env::Args) -> std::result::Result<(), ()> {
                                                    Ok(s)
                                                }) {
             Ok(s) => {
-                if let Err(e) = VmRequest::Exit.send(&mut scm, &s) {
+                if let Err(e) = VmRequest::Exit.send(&s) {
                     error!("failed to send stop request to socket at '{}': {:?}",
                            socket_path,
                            e);
@@ -549,7 +548,6 @@ fn stop_vms(args: std::env::Args) -> std::result::Result<(), ()> {
 }
 
 fn balloon_vms(mut args: std::env::Args) -> std::result::Result<(), ()> {
-    let mut scm = Scm::new(1);
     if args.len() < 2 {
         print_help("crosvm balloon", "PAGE_ADJUST VM_SOCKET...", &[]);
         println!("Adjust the ballon size of the crosvm instance by `PAGE_ADJUST` pages, `PAGE_ADJUST` can be negative to shrink the balloon.");
@@ -569,7 +567,7 @@ fn balloon_vms(mut args: std::env::Args) -> std::result::Result<(), ()> {
                                                    Ok(s)
                                                }) {
             Ok(s) => {
-                if let Err(e) = VmRequest::BalloonAdjust(num_pages).send(&mut scm, &s) {
+                if let Err(e) = VmRequest::BalloonAdjust(num_pages).send(&s) {
                     error!("failed to send balloon request to socket at '{}': {:?}",
                            socket_path,
                            e);
diff --git a/src/plugin/process.rs b/src/plugin/process.rs
index 0e8a74f..71c16c0 100644
--- a/src/plugin/process.rs
+++ b/src/plugin/process.rs
@@ -25,7 +25,7 @@ use protobuf::Message;
 use io_jail::Minijail;
 use kvm::{Vm, IoeventAddress, NoDatamatch, IrqSource, IrqRoute, PicId, dirty_log_bitmap_size};
 use kvm_sys::{kvm_pic_state, kvm_ioapic_state, kvm_pit_state2};
-use sys_util::{EventFd, MemoryMapping, Killable, Scm, SharedMemory, GuestAddress,
+use sys_util::{EventFd, MemoryMapping, Killable, ScmSocket, SharedMemory, GuestAddress,
                Result as SysResult, Error as SysError, SIGRTMIN};
 use plugin_proto::*;
 
@@ -119,9 +119,7 @@ pub struct Process {
     vcpu_sockets: Vec<(UnixDatagram, UnixDatagram)>,
 
     // Socket Transmission
-    scm: Scm,
     request_buffer: Vec<u8>,
-    datagram_files: Vec<File>,
     response_buffer: Vec<u8>,
 }
 
@@ -181,9 +179,7 @@ impl Process {
                per_vcpu_states,
                kill_evt: EventFd::new().map_err(Error::CreateEventFd)?,
                vcpu_sockets,
-               scm: Scm::new(1),
                request_buffer: vec![0; MAX_DATAGRAM_SIZE],
-               datagram_files: Vec::new(),
                response_buffer: Vec::new(),
            })
     }
@@ -444,10 +440,8 @@ impl Process {
                          vcpu_handles: &[JoinHandle<()>],
                          tap: Option<&Tap>)
                          -> Result<()> {
-        let msg_size = self.scm
-            .recv(&self.request_sockets[index],
-                  &mut [&mut self.request_buffer],
-                  &mut self.datagram_files)
+        let (msg_size, request_file) = self.request_sockets[index]
+            .recv_with_fd(&mut self.request_buffer)
             .map_err(Error::PluginSocketRecv)?;
 
         if msg_size == 0 {
@@ -475,7 +469,7 @@ impl Process {
                         }
                     } else if create.has_memory() {
                         let memory = create.get_memory();
-                        match self.datagram_files.pop() {
+                        match request_file {
                             Some(memfd) => {
                                 Self::handle_memory(entry,
                                                     vm,
@@ -653,16 +647,13 @@ impl Process {
             response.errno = e.errno();
         }
 
-        self.datagram_files.clear();
         self.response_buffer.clear();
         response
             .write_to_vec(&mut self.response_buffer)
             .map_err(Error::EncodeResponse)?;
         assert_ne!(self.response_buffer.len(), 0);
-        self.scm
-            .send(&self.request_sockets[index],
-                  &[&self.response_buffer[..]],
-                  &response_fds)
+        self.request_sockets[index]
+            .send_with_fds(&self.response_buffer[..], &response_fds)
             .map_err(Error::PluginSocketSend)?;
 
         Ok(())