1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File; 6*bb4ee6a4SAndroid Build Coastguard Worker 7*bb4ee6a4SAndroid Build Coastguard Worker use base::ioctl_with_ref; 8*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor; 9*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor; 10*bb4ee6a4SAndroid Build Coastguard Worker use virtio_sys::VHOST_VSOCK_SET_GUEST_CID; 11*bb4ee6a4SAndroid Build Coastguard Worker use virtio_sys::VHOST_VSOCK_SET_RUNNING; 12*bb4ee6a4SAndroid Build Coastguard Worker 13*bb4ee6a4SAndroid Build Coastguard Worker use super::ioctl_result; 14*bb4ee6a4SAndroid Build Coastguard Worker use super::Result; 15*bb4ee6a4SAndroid Build Coastguard Worker use super::Vhost; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker /// Handle for running VHOST_VSOCK ioctls. 18*bb4ee6a4SAndroid Build Coastguard Worker pub struct Vsock { 19*bb4ee6a4SAndroid Build Coastguard Worker descriptor: File, 20*bb4ee6a4SAndroid Build Coastguard Worker } 21*bb4ee6a4SAndroid Build Coastguard Worker 22*bb4ee6a4SAndroid Build Coastguard Worker impl Vsock { 23*bb4ee6a4SAndroid Build Coastguard Worker /// Open a handle to a new VHOST_VSOCK instance. new(vhost_vsock_file: File) -> Vsock24*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(vhost_vsock_file: File) -> Vsock { 25*bb4ee6a4SAndroid Build Coastguard Worker Vsock { 26*bb4ee6a4SAndroid Build Coastguard Worker descriptor: vhost_vsock_file, 27*bb4ee6a4SAndroid Build Coastguard Worker } 28*bb4ee6a4SAndroid Build Coastguard Worker } 29*bb4ee6a4SAndroid Build Coastguard Worker 30*bb4ee6a4SAndroid Build Coastguard Worker /// Set the CID for the guest. This number is used for routing all data destined for 31*bb4ee6a4SAndroid Build Coastguard Worker /// programs 32*bb4ee6a4SAndroid Build Coastguard Worker /// running in the guest. 33*bb4ee6a4SAndroid Build Coastguard Worker /// 34*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments 35*bb4ee6a4SAndroid Build Coastguard Worker /// * `cid` - CID to assign to the guest set_cid(&self, cid: u64) -> Result<()>36*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_cid(&self, cid: u64) -> Result<()> { 37*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Safe because descriptor is valid and the return value is checked. 38*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { ioctl_with_ref(&self.descriptor, VHOST_VSOCK_SET_GUEST_CID, &cid) }; 39*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 40*bb4ee6a4SAndroid Build Coastguard Worker return ioctl_result(); 41*bb4ee6a4SAndroid Build Coastguard Worker } 42*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 43*bb4ee6a4SAndroid Build Coastguard Worker } 44*bb4ee6a4SAndroid Build Coastguard Worker 45*bb4ee6a4SAndroid Build Coastguard Worker /// Tell the VHOST driver to start performing data transfer. start(&self) -> Result<()>46*bb4ee6a4SAndroid Build Coastguard Worker pub fn start(&self) -> Result<()> { 47*bb4ee6a4SAndroid Build Coastguard Worker self.set_running(true) 48*bb4ee6a4SAndroid Build Coastguard Worker } 49*bb4ee6a4SAndroid Build Coastguard Worker 50*bb4ee6a4SAndroid Build Coastguard Worker /// Tell the VHOST driver to stop performing data transfer. stop(&self) -> Result<()>51*bb4ee6a4SAndroid Build Coastguard Worker pub fn stop(&self) -> Result<()> { 52*bb4ee6a4SAndroid Build Coastguard Worker self.set_running(false) 53*bb4ee6a4SAndroid Build Coastguard Worker } 54*bb4ee6a4SAndroid Build Coastguard Worker set_running(&self, running: bool) -> Result<()>55*bb4ee6a4SAndroid Build Coastguard Worker fn set_running(&self, running: bool) -> Result<()> { 56*bb4ee6a4SAndroid Build Coastguard Worker let on = ::std::os::raw::c_int::from(running); 57*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Safe because descriptor is valid and the return value is checked. 58*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { ioctl_with_ref(&self.descriptor, VHOST_VSOCK_SET_RUNNING, &on) }; 59*bb4ee6a4SAndroid Build Coastguard Worker 60*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 61*bb4ee6a4SAndroid Build Coastguard Worker return ioctl_result(); 62*bb4ee6a4SAndroid Build Coastguard Worker } 63*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 64*bb4ee6a4SAndroid Build Coastguard Worker } 65*bb4ee6a4SAndroid Build Coastguard Worker } 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker impl Vhost for Vsock {} 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawDescriptor for Vsock { as_raw_descriptor(&self) -> RawDescriptor70*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_descriptor(&self) -> RawDescriptor { 71*bb4ee6a4SAndroid Build Coastguard Worker self.descriptor.as_raw_descriptor() 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker } 74