Revert "devices: refactor proxy to use msg_socket"

This reverts commit 142ce3efd9c6a20efb4685fa632ad522509441f2.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> devices: refactor proxy to use msg_socket
> 
> Use msg socket in proxy.
> 
> BUG=None
> TEST=None
> 
> Change-Id: Ia5ebc4410918a261fe525abc1051ebbbdc66a876
> Reviewed-on: https://chromium-review.googlesource.com/1260259
> Commit-Ready: Jingkui Wang <jkwang@google.com>
> Tested-by: Jingkui Wang <jkwang@google.com>
> Reviewed-by: Zach Reizner <zachr@chromium.org>

Bug: None
Change-Id: Ic7827969e9ad508cd1b65cb7b8747e81e0cd02d0
Reviewed-on: https://chromium-review.googlesource.com/c/1313014
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Jingkui Wang <jkwang@google.com>
diff --git a/Cargo.lock b/Cargo.lock
index b9705f9..15720da 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -135,7 +135,6 @@
  "io_jail 0.1.0",
  "kvm 0.1.0",
  "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "msg_socket 0.1.0",
  "net_sys 0.1.0",
  "net_util 0.1.0",
  "p9 0.1.0",
diff --git a/devices/Cargo.toml b/devices/Cargo.toml
index b6c94a2..ce0c0e5 100644
--- a/devices/Cargo.toml
+++ b/devices/Cargo.toml
@@ -15,7 +15,6 @@
 gpu_renderer = { path = "../gpu_renderer", optional = true }
 kvm = { path = "../kvm" }
 libc = "*"
-msg_socket = { path = "../msg_socket" }
 io_jail = { path = "../io_jail" }
 net_sys = { path = "../net_sys" }
 net_util = { path = "../net_util" }
diff --git a/devices/src/lib.rs b/devices/src/lib.rs
index a8e89a4..d76e743 100644
--- a/devices/src/lib.rs
+++ b/devices/src/lib.rs
@@ -18,8 +18,6 @@
 extern crate vhost;
 extern crate virtio_sys;
 extern crate vm_control;
-#[macro_use]
-extern crate msg_socket;
 
 mod bus;
 mod cmos;
diff --git a/devices/src/proxy.rs b/devices/src/proxy.rs
index 86fcd33..5b79d31 100644
--- a/devices/src/proxy.rs
+++ b/devices/src/proxy.rs
@@ -12,7 +12,7 @@
 use std::time::Duration;
 use std::{self, fmt, io};
 
-use msg_socket::{MsgError, MsgOnSocket, MsgReceiver, MsgResult, MsgSender, MsgSocket};
+use byteorder::{ByteOrder, LittleEndian, NativeEndian};
 
 use io_jail::{self, Minijail};
 use BusDevice;
@@ -35,80 +35,74 @@
 }
 
 const SOCKET_TIMEOUT_MS: u64 = 2000;
+const MSG_SIZE: usize = 24;
 
-#[derive(MsgOnSocket)]
 enum Command {
-    Read {
-        len: u32,
-        offset: u64,
-    },
-    Write {
-        len: u32,
-        offset: u64,
-        data: [u8; 8],
-    },
-    ReadConfig(u32),
-    WriteConfig {
-        reg_idx: u32,
-        offset: u32,
-        len: u32,
-        data: [u8; 4],
-    },
-    Shutdown,
-}
-
-#[derive(MsgOnSocket)]
-enum CommandResult {
-    Ok,
-    ReadResult([u8; 8]),
-    ReadConfigResult(u32),
+    Read = 0,
+    Write = 1,
+    ReadConfig = 2,
+    WriteConfig = 3,
+    Shutdown = 4,
 }
 
 fn child_proc(sock: UnixDatagram, device: &mut BusDevice) {
     let mut running = true;
-    let sock = MsgSocket::<CommandResult, Command>::new(sock);
 
     while running {
-        let cmd = match sock.recv() {
-            Ok(cmd) => cmd,
-            Err(err) => {
-                error!("child device process failed recv: {:?}", err);
+        let mut buf = [0; MSG_SIZE];
+        match handle_eintr!(sock.recv(&mut buf)) {
+            Ok(c) if c != buf.len() => {
+                error!(
+                    "child device process incorrect recv size: got {}, expected {}",
+                    c,
+                    buf.len()
+                );
                 break;
             }
+            Err(e) => {
+                error!("child device process failed recv: {}", e);
+                break;
+            }
+            _ => {}
+        }
+
+        let cmd = NativeEndian::read_u32(&buf[0..]);
+
+        let res = if cmd == Command::Read as u32 {
+            let len = NativeEndian::read_u32(&buf[4..]) as usize;
+            let offset = NativeEndian::read_u64(&buf[8..]);
+            device.read(offset, &mut buf[16..16 + len]);
+            handle_eintr!(sock.send(&buf))
+        } else if cmd == Command::Write as u32 {
+            let len = NativeEndian::read_u32(&buf[4..]) as usize;
+            let offset = NativeEndian::read_u64(&buf[8..]);
+            device.write(offset, &buf[16..16 + len]);
+            handle_eintr!(sock.send(&buf))
+        } else if cmd == Command::ReadConfig as u32 {
+            let reg_idx = NativeEndian::read_u32(&buf[4..]) as usize;
+            let val = device.config_register_read(reg_idx);
+            buf[16] = val as u8;
+            buf[17] = (val >> 8) as u8;
+            buf[18] = (val >> 16) as u8;
+            buf[19] = (val >> 24) as u8;
+            handle_eintr!(sock.send(&buf))
+        } else if cmd == Command::WriteConfig as u32 {
+            let reg_idx = NativeEndian::read_u32(&buf[4..]) as usize;
+            let offset = u64::from(NativeEndian::read_u32(&buf[8..]));
+            let len = u64::from(NativeEndian::read_u32(&buf[16..]));
+            device.config_register_write(reg_idx, offset, &buf[20..(20 + len as usize)]);
+            handle_eintr!(sock.send(&buf))
+        } else if cmd == Command::Shutdown as u32 {
+            running = false;
+            handle_eintr!(sock.send(&buf))
+        } else {
+            error!("child device process unknown command: {}", cmd);
+            break;
         };
 
-        let res = match cmd {
-            Command::Read { len, offset } => {
-                let mut buffer = [0u8; 8];
-                device.read(offset, &mut buffer[0..len as usize]);
-                sock.send(&CommandResult::ReadResult(buffer))
-            }
-            Command::Write { len, offset, data } => {
-                let len = len as usize;
-                device.write(offset, &data[0..len]);
-                sock.send(&CommandResult::Ok)
-            }
-            Command::ReadConfig(idx) => {
-                let val = device.config_register_read(idx as usize);
-                sock.send(&CommandResult::ReadConfigResult(val))
-            }
-            Command::WriteConfig {
-                reg_idx,
-                offset,
-                len,
-                data,
-            } => {
-                let len = len as usize;
-                device.config_register_write(reg_idx as usize, offset as u64, &data[0..len]);
-                sock.send(&CommandResult::Ok)
-            }
-            Command::Shutdown => {
-                running = false;
-                sock.send(&CommandResult::Ok)
-            }
-        };
         if let Err(e) = res {
-            error!("child device process failed send: {:?}", e);
+            error!("error: child device process failed send: {}", e);
+            break;
         }
     }
 }
@@ -118,7 +112,7 @@
 /// Because forks are very unfriendly to destructors and all memory mappings and file descriptors
 /// are inherited, this should be used as early as possible in the main process.
 pub struct ProxyDevice {
-    sock: MsgSocket<Command, CommandResult>,
+    sock: UnixDatagram,
     pid: pid_t,
 }
 
@@ -158,7 +152,7 @@
             .set_read_timeout(Some(Duration::from_millis(SOCKET_TIMEOUT_MS)))
             .map_err(Error::Io)?;
         Ok(ProxyDevice {
-            sock: MsgSocket::<Command, CommandResult>::new(parent_sock),
+            sock: parent_sock,
             pid,
         })
     }
@@ -167,69 +161,90 @@
         self.pid
     }
 
-    fn sync_send(&self, cmd: Command) -> Option<CommandResult> {
-        let res = self.sock.send(&cmd);
-        if let Err(e) = res {
-            error!("failed write to child device process: {:?}", e);
-        };
-        match self.sock.recv() {
-            Err(e) => {
-                error!("failed read from child device process: {:?}", e);
-                None
-            }
-            Ok(r) => Some(r),
-        }
+    fn send_cmd(&self, cmd: Command, offset: u64, len: u32, data: &[u8]) -> Result<()> {
+        let mut buf = [0; MSG_SIZE];
+        NativeEndian::write_u32(&mut buf[0..], cmd as u32);
+        NativeEndian::write_u32(&mut buf[4..], len);
+        NativeEndian::write_u64(&mut buf[8..], offset);
+        buf[16..16 + data.len()].clone_from_slice(data);
+        handle_eintr!(self.sock.send(&buf))
+            .map(|_| ())
+            .map_err(Error::Io)
+    }
+
+    fn send_config_cmd(&self, cmd: Command, reg_idx: u32, offset: u64, data: &[u8]) -> Result<()> {
+        let mut buf = [0; MSG_SIZE];
+        NativeEndian::write_u32(&mut buf[0..], cmd as u32);
+        NativeEndian::write_u32(&mut buf[4..], reg_idx);
+        NativeEndian::write_u64(&mut buf[8..], offset);
+        NativeEndian::write_u32(&mut buf[16..], data.len() as u32);
+        buf[20..20 + data.len()].clone_from_slice(data);
+        handle_eintr!(self.sock.send(&buf))
+            .map(|_| ())
+            .map_err(Error::Io)
+    }
+
+    fn recv_resp(&self, data: &mut [u8]) -> Result<()> {
+        let mut buf = [0; MSG_SIZE];
+        handle_eintr!(self.sock.recv(&mut buf)).map_err(Error::Io)?;
+        let len = data.len();
+        data.clone_from_slice(&buf[16..16 + len]);
+        Ok(())
+    }
+
+    fn wait(&self) -> Result<()> {
+        let mut buf = [0; MSG_SIZE];
+        handle_eintr!(self.sock.recv(&mut buf))
+            .map(|_| ())
+            .map_err(Error::Io)
     }
 }
 
 impl BusDevice for ProxyDevice {
     fn config_register_write(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
-        let len = data.len() as u32;
-        let mut buffer = [0u8; 4];
-        buffer[0..data.len()].clone_from_slice(data);
-        let reg_idx = reg_idx as u32;
-        let offset = offset as u32;
-        self.sync_send(Command::WriteConfig {
-            reg_idx,
-            offset,
-            len,
-            data: buffer,
-        });
-    }
-
-    fn config_register_read(&self, reg_idx: usize) -> u32 {
-        let res = self.sync_send(Command::ReadConfig(reg_idx as u32));
-        if let Some(CommandResult::ReadConfigResult(val)) = res {
-            val
-        } else {
-            0
+        let res = self
+            .send_config_cmd(Command::WriteConfig, reg_idx as u32, offset, data)
+            .and_then(|_| self.wait());
+        if let Err(e) = res {
+            error!("failed write to child device process: {}", e);
         }
     }
 
+    fn config_register_read(&self, reg_idx: usize) -> u32 {
+        let mut data = [0u8; 4];
+        let res = self
+            .send_config_cmd(Command::ReadConfig, reg_idx as u32, 0, &[])
+            .and_then(|_| self.recv_resp(&mut data));
+        if let Err(e) = res {
+            error!("failed write to child device process: {}", e);
+        }
+        LittleEndian::read_u32(&data)
+    }
+
     fn read(&mut self, offset: u64, data: &mut [u8]) {
-        let len = data.len() as u32;
-        if let Some(CommandResult::ReadResult(buffer)) =
-            self.sync_send(Command::Read { len, offset })
-        {
-            let len = data.len();
-            data.clone_from_slice(&buffer[0..len]);
+        let res = self
+            .send_cmd(Command::Read, offset, data.len() as u32, &[])
+            .and_then(|_| self.recv_resp(data));
+        if let Err(e) = res {
+            error!("failed read from child device process: {}", e);
         }
     }
 
     fn write(&mut self, offset: u64, data: &[u8]) {
-        let mut buffer = [0u8; 8];
-        let len = data.len() as u32;
-        buffer[0..data.len()].clone_from_slice(data);
-        self.sync_send(Command::Write {
-            len,
-            offset,
-            data: buffer,
-        });
+        let res = self
+            .send_cmd(Command::Write, offset, data.len() as u32, data)
+            .and_then(|_| self.wait());
+        if let Err(e) = res {
+            error!("failed write to child device process: {}", e);
+        }
     }
 }
 
 impl Drop for ProxyDevice {
     fn drop(&mut self) {
-        self.sync_send(Command::Shutdown);
+        let res = self.send_cmd(Command::Shutdown, 0, 0, &[]);
+        if let Err(e) = res {
+            error!("failed to shutdown child device process: {}", e);
+        }
     }
 }