1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use libc; 6 use std::fs::{File, OpenOptions}; 7 use std::os::unix::fs::OpenOptionsExt; 8 use std::os::unix::io::{AsRawFd, RawFd}; 9 10 use sys_util::{ioctl_with_ref, GuestMemory}; 11 use virtio_sys::{VHOST_VSOCK_SET_GUEST_CID, VHOST_VSOCK_SET_RUNNING}; 12 13 use super::{ioctl_result, Error, Result, Vhost}; 14 15 static DEVICE: &'static str = "/dev/vhost-vsock"; 16 17 /// Handle for running VHOST_VSOCK ioctls. 18 pub struct Vsock { 19 fd: File, 20 mem: GuestMemory, 21 } 22 23 impl Vsock { 24 /// Open a handle to a new VHOST_VSOCK instance. new(mem: &GuestMemory) -> Result<Vsock>25 pub fn new(mem: &GuestMemory) -> Result<Vsock> { 26 Ok(Vsock { 27 fd: OpenOptions::new() 28 .read(true) 29 .write(true) 30 .custom_flags(libc::O_CLOEXEC | libc::O_NONBLOCK) 31 .open(DEVICE) 32 .map_err(Error::VhostOpen)?, 33 mem: mem.clone(), 34 }) 35 } 36 37 /// Set the CID for the guest. This number is used for routing all data destined for 38 /// programs 39 /// running in the guest. 40 /// 41 /// # Arguments 42 /// * `cid` - CID to assign to the guest set_cid(&self, cid: u64) -> Result<()>43 pub fn set_cid(&self, cid: u64) -> Result<()> { 44 let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_GUEST_CID(), &cid) }; 45 if ret < 0 { 46 return ioctl_result(); 47 } 48 Ok(()) 49 } 50 51 /// Tell the VHOST driver to start performing data transfer. start(&self) -> Result<()>52 pub fn start(&self) -> Result<()> { 53 self.set_running(true) 54 } 55 56 /// Tell the VHOST driver to stop performing data transfer. stop(&self) -> Result<()>57 pub fn stop(&self) -> Result<()> { 58 self.set_running(false) 59 } 60 set_running(&self, running: bool) -> Result<()>61 fn set_running(&self, running: bool) -> Result<()> { 62 let on: ::std::os::raw::c_int = if running { 1 } else { 0 }; 63 let ret = unsafe { ioctl_with_ref(&self.fd, VHOST_VSOCK_SET_RUNNING(), &on) }; 64 65 if ret < 0 { 66 return ioctl_result(); 67 } 68 Ok(()) 69 } 70 } 71 72 impl Vhost for Vsock { mem(&self) -> &GuestMemory73 fn mem(&self) -> &GuestMemory { 74 &self.mem 75 } 76 } 77 78 impl AsRawFd for Vsock { as_raw_fd(&self) -> RawFd79 fn as_raw_fd(&self) -> RawFd { 80 self.fd.as_raw_fd() 81 } 82 } 83