Alioth Code Coverage

group.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::ffi::CString;
16use std::fs::File;
17use std::os::fd::{AsRawFd, FromRawFd};
18use std::path::Path;
19use std::sync::Arc;
20
21use snafu::ResultExt;
22
23use crate::sys::vfio::{
24 VfioIommu, vfio_group_get_device_fd, vfio_group_set_container, vfio_group_unset_container,
25};
26use crate::vfio::container::Container;
27use crate::vfio::device::Device;
28use crate::vfio::{Result, error};
29
30#[derive(Debug)]
31pub struct Group {
32 container: Option<Arc<Container>>,
33 fd: File,
34}
35
36impl Group {
37 pub fn new(path: &Path) -> Result<Self> {
38 let fd = File::open(path).context(error::AccessDevice { path })?;
39 Ok(Group {
40 fd,
41 container: None,
42 })
43 }
44
45 pub fn attach(&mut self, container: Arc<Container>, iommu: VfioIommu) -> Result<()> {
46 unsafe { vfio_group_set_container(&self.fd, &container.fd().as_raw_fd()) }?;
47 container.set_iommu(iommu)?;
48 self.container.replace(container);
49 Ok(())
50 }
51
52 pub fn detach(&mut self) -> Result<()> {
53 if self.container.is_none() {
54 return Ok(());
55 }
56 unsafe { vfio_group_unset_container(&self.fd) }?;
57 self.container = None;
58 Ok(())
59 }
60}
61
62impl Drop for Group {
63 fn drop(&mut self) {
64 if let Err(e) = self.detach() {
65 log::error!(
66 "Group-{}: detaching from container: {e:?}",
67 self.fd.as_raw_fd()
68 );
69 }
70 }
71}
72
73#[derive(Debug)]
74pub struct DevFd {
75 fd: File,
76 _group: Arc<Group>,
77}
78
79impl DevFd {
80 pub fn new(group: Arc<Group>, id: &str) -> Result<Self> {
81 let id_c = CString::new(id).unwrap();
82 let fd = unsafe { vfio_group_get_device_fd(&group.fd, id_c.as_ptr()) }?;
83 Ok(DevFd {
84 fd: unsafe { File::from_raw_fd(fd) },
85 _group: group,
86 })
87 }
88}
89
90impl Device for DevFd {
91 fn fd(&self) -> &File {
92 &self.fd
93 }
94}
95