• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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