mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Use a common method for spawning virtio threads
Introduce a common solution for spawning the virtio threads which will make it easier to add the panic handling. During this effort I discovered that there were no seccomp filters registered for the vhost-user-net thread nor the vhost-user-block thread. This change also incorporates basic seccomp filters for those as part of the refactoring. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
// Copyright 2019 Intel Corporation. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::super::{
|
||||
ActivateError, ActivateResult, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType,
|
||||
};
|
||||
use super::super::{ActivateResult, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType};
|
||||
use super::vu_common_ctrl::{VhostUserConfig, VhostUserHandle};
|
||||
use super::{Error, Result, DEFAULT_VIRTIO_FEATURES};
|
||||
use crate::seccomp_filters::Thread;
|
||||
use crate::thread_helper::spawn_virtio_thread;
|
||||
use crate::vhost_user::VhostUserCommon;
|
||||
use crate::VirtioInterrupt;
|
||||
use crate::{GuestMemoryMmap, GuestRegionMmap};
|
||||
use block_util::VirtioBlockConfig;
|
||||
use seccompiler::SeccompAction;
|
||||
use std::mem;
|
||||
use std::result;
|
||||
use std::sync::{Arc, Barrier, Mutex};
|
||||
@@ -57,11 +58,17 @@ pub struct Blk {
|
||||
config: VirtioBlockConfig,
|
||||
guest_memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
epoll_thread: Option<thread::JoinHandle<()>>,
|
||||
seccomp_action: SeccompAction,
|
||||
}
|
||||
|
||||
impl Blk {
|
||||
/// Create a new vhost-user-blk device
|
||||
pub fn new(id: String, vu_cfg: VhostUserConfig, restoring: bool) -> Result<Blk> {
|
||||
pub fn new(
|
||||
id: String,
|
||||
vu_cfg: VhostUserConfig,
|
||||
restoring: bool,
|
||||
seccomp_action: SeccompAction,
|
||||
) -> Result<Blk> {
|
||||
let num_queues = vu_cfg.num_queues;
|
||||
|
||||
if restoring {
|
||||
@@ -85,6 +92,7 @@ impl Blk {
|
||||
config: VirtioBlockConfig::default(),
|
||||
guest_memory: None,
|
||||
epoll_thread: None,
|
||||
seccomp_action,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -171,6 +179,7 @@ impl Blk {
|
||||
config,
|
||||
guest_memory: None,
|
||||
epoll_thread: None,
|
||||
seccomp_action,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -298,18 +307,20 @@ impl VirtioDevice for Blk {
|
||||
let paused = self.common.paused.clone();
|
||||
let paused_sync = self.common.paused_sync.clone();
|
||||
|
||||
thread::Builder::new()
|
||||
.name(self.id.to_string())
|
||||
.spawn(move || {
|
||||
let mut epoll_threads = Vec::new();
|
||||
|
||||
spawn_virtio_thread(
|
||||
&self.id,
|
||||
&self.seccomp_action,
|
||||
Thread::VirtioVhostBlock,
|
||||
&mut epoll_threads,
|
||||
move || {
|
||||
if let Err(e) = handler.run(paused, paused_sync.unwrap()) {
|
||||
error!("Error running vhost-user-blk worker: {:?}", e);
|
||||
error!("Error running worker: {:?}", e);
|
||||
}
|
||||
})
|
||||
.map(|thread| self.epoll_thread = Some(thread))
|
||||
.map_err(|e| {
|
||||
error!("failed to clone queue EventFd: {}", e);
|
||||
ActivateError::BadActivate
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
self.epoll_thread = Some(epoll_threads.remove(0));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
use super::vu_common_ctrl::VhostUserHandle;
|
||||
use super::{Error, Result, DEFAULT_VIRTIO_FEATURES};
|
||||
use crate::seccomp_filters::{get_seccomp_filter, Thread};
|
||||
use crate::seccomp_filters::Thread;
|
||||
use crate::thread_helper::spawn_virtio_thread;
|
||||
use crate::vhost_user::VhostUserCommon;
|
||||
use crate::{
|
||||
ActivateError, ActivateResult, Queue, UserspaceMapping, VirtioCommon, VirtioDevice,
|
||||
@@ -11,7 +12,7 @@ use crate::{
|
||||
};
|
||||
use crate::{GuestMemoryMmap, GuestRegionMmap, MmapRegion};
|
||||
use libc::{self, c_void, off64_t, pread64, pwrite64};
|
||||
use seccompiler::{apply_filter, SeccompAction};
|
||||
use seccompiler::SeccompAction;
|
||||
use std::io;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::result;
|
||||
@@ -549,28 +550,19 @@ impl VirtioDevice for Fs {
|
||||
let paused = self.common.paused.clone();
|
||||
let paused_sync = self.common.paused_sync.clone();
|
||||
|
||||
let virtio_vhost_fs_seccomp_filter =
|
||||
get_seccomp_filter(&self.seccomp_action, Thread::VirtioVhostFs)
|
||||
.map_err(ActivateError::CreateSeccompFilter)?;
|
||||
|
||||
thread::Builder::new()
|
||||
.name(self.id.to_string())
|
||||
.spawn(move || {
|
||||
if !virtio_vhost_fs_seccomp_filter.is_empty() {
|
||||
if let Err(e) = apply_filter(&virtio_vhost_fs_seccomp_filter) {
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let mut epoll_threads = Vec::new();
|
||||
spawn_virtio_thread(
|
||||
&self.id,
|
||||
&self.seccomp_action,
|
||||
Thread::VirtioVhostFs,
|
||||
&mut epoll_threads,
|
||||
move || {
|
||||
if let Err(e) = handler.run(paused, paused_sync.unwrap()) {
|
||||
error!("Error running vhost-user-fs worker: {:?}", e);
|
||||
error!("Error running worker: {:?}", e);
|
||||
}
|
||||
})
|
||||
.map(|thread| self.epoll_thread = Some(thread))
|
||||
.map_err(|e| {
|
||||
error!("failed to clone queue EventFd: {}", e);
|
||||
ActivateError::BadActivate
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
self.epoll_thread = Some(epoll_threads.remove(0));
|
||||
|
||||
event!("virtio-device", "activated", "id", &self.id);
|
||||
Ok(())
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
// Copyright 2019 Intel Corporation. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::seccomp_filters::{get_seccomp_filter, Thread};
|
||||
use crate::seccomp_filters::Thread;
|
||||
use crate::thread_helper::spawn_virtio_thread;
|
||||
use crate::vhost_user::vu_common_ctrl::{VhostUserConfig, VhostUserHandle};
|
||||
use crate::vhost_user::{Error, Result, VhostUserCommon};
|
||||
use crate::{
|
||||
ActivateError, ActivateResult, EpollHelper, EpollHelperError, EpollHelperHandler, Queue,
|
||||
VirtioCommon, VirtioDevice, VirtioDeviceType, VirtioInterrupt, EPOLL_HELPER_EVENT_LAST,
|
||||
ActivateResult, EpollHelper, EpollHelperError, EpollHelperHandler, Queue, VirtioCommon,
|
||||
VirtioDevice, VirtioDeviceType, VirtioInterrupt, EPOLL_HELPER_EVENT_LAST,
|
||||
VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_VERSION_1,
|
||||
};
|
||||
use crate::{GuestMemoryMmap, GuestRegionMmap};
|
||||
use net_util::{build_net_config_space, CtrlQueue, MacAddr, VirtioNetConfig};
|
||||
use seccompiler::{apply_filter, SeccompAction};
|
||||
use seccompiler::SeccompAction;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::result;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
@@ -332,28 +333,19 @@ impl VirtioDevice for Net {
|
||||
self.common.paused_sync = Some(Arc::new(Barrier::new(3)));
|
||||
let paused_sync = self.common.paused_sync.clone();
|
||||
|
||||
// Retrieve seccomp filter for virtio_net_ctl thread
|
||||
let virtio_vhost_net_ctl_seccomp_filter =
|
||||
get_seccomp_filter(&self.seccomp_action, Thread::VirtioVhostNetCtl)
|
||||
.map_err(ActivateError::CreateSeccompFilter)?;
|
||||
thread::Builder::new()
|
||||
.name(format!("{}_ctrl", self.id))
|
||||
.spawn(move || {
|
||||
if !virtio_vhost_net_ctl_seccomp_filter.is_empty() {
|
||||
if let Err(e) = apply_filter(&virtio_vhost_net_ctl_seccomp_filter) {
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let mut epoll_threads = Vec::new();
|
||||
spawn_virtio_thread(
|
||||
&format!("{}_ctrl", &self.id),
|
||||
&self.seccomp_action,
|
||||
Thread::VirtioVhostNetCtl,
|
||||
&mut epoll_threads,
|
||||
move || {
|
||||
if let Err(e) = ctrl_handler.run_ctrl(paused, paused_sync.unwrap()) {
|
||||
error!("Error running worker: {:?}", e);
|
||||
}
|
||||
})
|
||||
.map(|thread| self.ctrl_queue_epoll_thread = Some(thread))
|
||||
.map_err(|e| {
|
||||
error!("failed to clone queue EventFd: {}", e);
|
||||
ActivateError::BadActivate
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
self.ctrl_queue_epoll_thread = Some(epoll_threads.remove(0));
|
||||
}
|
||||
|
||||
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
|
||||
@@ -383,18 +375,19 @@ impl VirtioDevice for Net {
|
||||
let paused = self.common.paused.clone();
|
||||
let paused_sync = self.common.paused_sync.clone();
|
||||
|
||||
thread::Builder::new()
|
||||
.name(self.id.to_string())
|
||||
.spawn(move || {
|
||||
let mut epoll_threads = Vec::new();
|
||||
spawn_virtio_thread(
|
||||
&self.id,
|
||||
&self.seccomp_action,
|
||||
Thread::VirtioVhostNet,
|
||||
&mut epoll_threads,
|
||||
move || {
|
||||
if let Err(e) = handler.run(paused, paused_sync.unwrap()) {
|
||||
error!("Error running vhost-user-net worker: {:?}", e);
|
||||
error!("Error running worker: {:?}", e);
|
||||
}
|
||||
})
|
||||
.map(|thread| self.epoll_thread = Some(thread))
|
||||
.map_err(|e| {
|
||||
error!("failed to clone queue EventFd: {}", e);
|
||||
ActivateError::BadActivate
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
self.epoll_thread = Some(epoll_threads.remove(0));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user