Compare commits

...

8 Commits
v49.0 ... v23.1

Author SHA1 Message Date
Rob Bradford
479fef1b8e build: Release v23.1 (bug fix release)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Bo Chen
fc8f867879 vmm: Add 'shutdown()' to vCPU seccomp filter
This is required when hot-removing a vfio-user device. Details code path
below:

Thread 6 "vcpu0" received signal SIGSYS, Bad system call.
[Switching to Thread 0x7f8196889700 (LWP 2358305)]
0x00007f8196dae7ab in shutdown () at ../sysdeps/unix/syscall-template.S:78
78	T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) bt
  0x00007f8196dae7ab in shutdown () at ../sysdeps/unix/syscall-template.S:78
  0x000056189240737d in std::sys::unix::net::Socket::shutdown ()
    at library/std/src/sys/unix/net.rs:383
  std::os::unix::net::stream::UnixStream::shutdown () at library/std/src/os/unix/net/stream.rs:479
  0x000056189210e23d in vfio_user::Client::shutdown (self=0x7f8190014300)
    at vfio_user/src/lib.rs:787
  0x00005618920b9d02 in <pci::vfio_user::VfioUserPciDevice as core::ops::drop::Drop>::drop (
    self=0x7f819002d7c0) at pci/src/vfio_user.rs:551
  0x00005618920b8787 in core::ptr::drop_in_place<pci::vfio_user::VfioUserPciDevice> ()
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920b92e3 in core::ptr::drop_in_place<core::cell::UnsafeCell<dyn pci::device::PciDevice>>
    () at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920b9362 in core::ptr::drop_in_place<std::sync::mutex::Mutex<dyn pci::device::PciDevice>> () at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
  0x00005618920d8a3e in alloc::sync::Arc<T>::drop_slow (self=0x7f81968852b8)
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/sync.rs:1092
  0x00005618920ba273 in <alloc::sync::Arc<T> as core::ops::drop::Drop>::drop (self=0x7f81968852b8)
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/sync.rs:1688
 0x00005618920b76fb in core::ptr::drop_in_place<alloc::sync::Arc<std::sync::mutex::Mutex<dyn pci::device::PciDevice>>> ()
    at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ptr/mod.rs:188
 0x0000561891b5e47d in vmm::device_manager::DeviceManager::eject_device (self=0x7f8190009600,
    pci_segment_id=0, device_id=3) at vmm/src/device_manager.rs:4000
 0x0000561891b674bc in <vmm::device_manager::DeviceManager as vm_device::bus::BusDevice>::write (
    self=0x7f8190009600, base=70368744108032, offset=8, data=&[u8](size=4) = {...})
    at vmm/src/device_manager.rs:4625
 0x00005618921927d5 in vm_device::bus::Bus::write (self=0x7f8190006e00, addr=70368744108040,
    data=&[u8](size=4) = {...}) at vm-device/src/bus.rs:235
 0x0000561891b72e10 in <vmm::vm::VmOps as hypervisor::vm::VmmOps>::mmio_write (
    self=0x7f81900097b0, gpa=70368744108040, data=&[u8](size=4) = {...}) at vmm/src/vm.rs:378
 0x0000561892133ae2 in <hypervisor::kvm::KvmVcpu as hypervisor::cpu::Vcpu>::run (
    self=0x7f8190013c90) at hypervisor/src/kvm/mod.rs:1114
 0x0000561891914e85 in vmm::cpu::Vcpu::run (self=0x7f819001b230) at vmm/src/cpu.rs:348
 0x000056189189f2cb in vmm::cpu::CpuManager::start_vcpu::{{closure}}::{{closure}} ()
    at vmm/src/cpu.rs:953

Signed-off-by: Bo Chen <chen.bo@intel.com>
(cherry picked from commit 42c19e14c5)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Sebastien Boeuf
e2eb59bcc8 vmm: Remove FsConfig from VmConfig when unplugging fs device
All hotpluggable devices were properly removed from the VmConfig when a
remove-device command was issued, except for the "fs" type. Fix this
lack of support as it is causing the integration tests to fail with the
recent addition of verifying that identifiers are unique.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
(cherry picked from commit a5a2e591c9)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
LiHui
1e557fdb3c vmm: api: Do not delete the API socket on API server creation
The socket will safely deleted on shutdown and so it is not necessary to
delete the API socket when starting the HTTP server.

Fixes: #4026

Signed-off-by: LiHui <andrewli@kubesphere.io>
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit ec0c1b01c4)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
10ce348aa6 tests: Use different API sockets when restoring
This prevents a conflict since the old API socket will not have been
cleaned up (due to the use of SIGKILL.)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 4fed2d4ed7)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
63130d0f92 vmm: seccomp: Allow SYS_rseq as required by newer glibc
glibc 2.35 as shipped by Fedora 36 now uses the rseq syscall.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 4a04d1f8f2)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Rob Bradford
e6cc364703 virtio-devices: mem: Reject resize if device not activated by guest
If the guest has not activated the virtio-mem device then reject an
attempt to resize using it.

Fixes: #4001

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit c274ce4d49)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
Fabiano Fidêncio
a861918f06 docs: Fix the name of the I/O operations knobs
The I/O operations knobs are prefixed `ops_` rather than `bw_`, as `bw_`
refers to the "bandwidth" knobs.

Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
(cherry picked from commit a87d1bbaa1)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
2022-05-09 14:54:18 +01:00
10 changed files with 77 additions and 30 deletions

2
Cargo.lock generated
View File

@@ -148,7 +148,7 @@ dependencies = [
[[package]]
name = "cloud-hypervisor"
version = "23.0.0"
version = "23.1.0"
dependencies = [
"anyhow",
"api_client",

View File

@@ -1,6 +1,6 @@
[package]
name = "cloud-hypervisor"
version = "23.0.0"
version = "23.1.0"
authors = ["The Cloud Hypervisor Authors"]
edition = "2021"
default-run = "cloud-hypervisor"

View File

@@ -24,8 +24,8 @@ bucket is unbounded in speed which allows for bursts bound in size by
the amount of tokens available. Once the token bucket is empty,
consumption speed is bound by the "refill-rate". Similarly, Cloud
Hypervisor provides another three options for limiting I/O operations,
i.e., `ops_size` (I/O operations), `bw_one_time_burst` (I/O operations),
and `bw_refill_time` (ms).
i.e., `ops_size` (I/O operations), `ops_one_time_burst` (I/O operations),
and `ops_refill_time` (ms).
One caveat in the I/O throttling is that every-time the bucket gets
empty, it will stop I/O operations for a fixed amount of time

View File

@@ -1,3 +1,4 @@
- [v23.1](#v231)
- [v23.0](#v230)
- [vDPA Support](#vdpa-support)
- [Updated OS Support list](#updated-os-support-list)
@@ -202,6 +203,15 @@
- [Console over virtio](#console-over-virtio)
- [Unit testing](#unit-testing)
- [Integration tests parallelization](#integration-tests-parallelization)
# v23.1
This is a bug fix release. The following issues have been addressed:
* Add some missing seccomp rules
* Remove `virtio-fs` filesystem entries from config on removal
* Do not delete API socket on API server start (#4026)
* Reject `virtio-mem` resize if the guest doesn't activate the device
* Fix OpenAPI naming of I/O throttling knobs
# v23.0

View File

@@ -9,7 +9,7 @@
Name: cloud-hypervisor
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of KVM.
Version: 23.0
Version: 23.1
Release: 0%{?dist}
License: ASL 2.0 or BSD-3-clause
Group: Applications/System
@@ -112,6 +112,9 @@ rm -rf %{buildroot}
%changelog
* Mon May 09 2022 Rob Bradford <robert.bradford@intel.com> 23.1-0
- Update to 23.1
* Thu Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
- Update to 23.0

View File

@@ -5058,7 +5058,7 @@ mod parallel {
let guest = Guest::new(Box::new(focal));
let kernel_path = direct_kernel_boot_path();
let api_socket = temp_api_path(&guest.tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&guest.tmp_dir));
let net_id = "net123";
let net_params = format!(
@@ -5074,7 +5074,7 @@ mod parallel {
let socket = temp_vsock_path(&guest.tmp_dir);
let mut child = GuestCommand::new(&guest)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_source])
.args(&["--cpus", "boot=4"])
.args(&[
"--memory",
@@ -5110,11 +5110,11 @@ mod parallel {
// Check the guest RAM
assert!(guest.get_total_memory().unwrap_or_default() > 3_840_000);
// Increase guest RAM with virtio-mem
resize_command(&api_socket, None, Some(6 << 30), None);
resize_command(&api_socket_source, None, Some(6 << 30), None);
thread::sleep(std::time::Duration::new(5, 0));
assert!(guest.get_total_memory().unwrap_or_default() > 5_760_000);
// Use balloon to remove RAM from the VM
resize_command(&api_socket, None, None, Some(1 << 30));
resize_command(&api_socket_source, None, None, Some(1 << 30));
thread::sleep(std::time::Duration::new(5, 0));
let total_memory = guest.get_total_memory().unwrap_or_default();
assert!(total_memory > 4_800_000);
@@ -5131,12 +5131,16 @@ mod parallel {
// AArch64: Device hotplug is currently not supported, skipping here.
#[cfg(target_arch = "x86_64")]
{
assert!(remote_command(&api_socket, "remove-device", Some(net_id),));
assert!(remote_command(
&api_socket_source,
"remove-device",
Some(net_id),
));
thread::sleep(std::time::Duration::new(10, 0));
// Plug the virtio-net device again
assert!(remote_command(
&api_socket,
&api_socket_source,
"add-net",
Some(net_params.as_str()),
));
@@ -5144,11 +5148,11 @@ mod parallel {
}
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -5175,9 +5179,11 @@ mod parallel {
.output()
.unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&guest.tmp_dir));
// Restore the VM from the snapshot
let mut child = GuestCommand::new(&guest)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -5191,7 +5197,7 @@ mod parallel {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
// Perform same checks to validate VM has been properly restored
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 4);
@@ -5199,11 +5205,11 @@ mod parallel {
assert!(total_memory > 4_800_000);
assert!(total_memory < 5_760_000);
// Deflate balloon to restore entire RAM to the VM
resize_command(&api_socket, None, None, Some(0));
resize_command(&api_socket_restored, None, None, Some(0));
thread::sleep(std::time::Duration::new(5, 0));
assert!(guest.get_total_memory().unwrap_or_default() > 5_760_000);
// Decrease guest RAM with virtio-mem
resize_command(&api_socket, None, Some(5 << 30), None);
resize_command(&api_socket_restored, None, Some(5 << 30), None);
thread::sleep(std::time::Duration::new(5, 0));
let total_memory = guest.get_total_memory().unwrap_or_default();
assert!(total_memory > 4_800_000);
@@ -5598,9 +5604,9 @@ mod parallel {
let focal2 = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest2 = Guest::new(Box::new(focal2));
let api_socket = temp_api_path(&guest2.tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&guest2.tmp_dir));
let (mut child1, mut child2) = setup_ovs_dpdk_guests(&guest1, &guest2, &api_socket);
let (mut child1, mut child2) = setup_ovs_dpdk_guests(&guest1, &guest2, &api_socket_source);
// Create the snapshot directory
let snapshot_dir = temp_snapshot_dir_path(&guest2.tmp_dir);
@@ -5634,11 +5640,11 @@ mod parallel {
guest2.ssh_command("nc -vz 172.100.0.1 12345").unwrap();
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -5659,9 +5665,10 @@ mod parallel {
.output()
.unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&guest2.tmp_dir));
// Restore the VM from the snapshot
let mut child2 = GuestCommand::new(&guest2)
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -5675,7 +5682,7 @@ mod parallel {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
// Spawn a new netcat listener in the first VM
let guest_ip = guest1.network.guest_ip.clone();
@@ -6477,10 +6484,10 @@ mod windows {
ovmf_path.push(OVMF_NAME);
let tmp_dir = TempDir::new_with_prefix("/tmp/ch").unwrap();
let api_socket = temp_api_path(&tmp_dir);
let api_socket_source = format!("{}.1", temp_api_path(&tmp_dir));
let mut child = GuestCommand::new(windows_guest.guest())
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_source])
.args(&["--cpus", "boot=2,kvm_hyperv=on"])
.args(&["--memory", "size=4G"])
.args(&["--kernel", ovmf_path.to_str().unwrap()])
@@ -6507,11 +6514,11 @@ mod windows {
let snapshot_dir = temp_snapshot_dir_path(&tmp_dir);
// Pause the VM
assert!(remote_command(&api_socket, "pause", None));
assert!(remote_command(&api_socket_source, "pause", None));
// Take a snapshot from the VM
assert!(remote_command(
&api_socket,
&api_socket_source,
"snapshot",
Some(format!("file://{}", snapshot_dir).as_str()),
));
@@ -6522,9 +6529,11 @@ mod windows {
let _ = child.kill();
child.wait().unwrap();
let api_socket_restored = format!("{}.2", temp_api_path(&tmp_dir));
// Restore the VM from the snapshot
let mut child = GuestCommand::new(windows_guest.guest())
.args(&["--api-socket", &api_socket])
.args(&["--api-socket", &api_socket_restored])
.args(&[
"--restore",
format!("source_url=file://{}", snapshot_dir).as_str(),
@@ -6538,7 +6547,7 @@ mod windows {
let r = std::panic::catch_unwind(|| {
// Resume the VM
assert!(remote_command(&api_socket, "resume", None));
assert!(remote_command(&api_socket_restored, "resume", None));
windows_guest.shutdown();
});

View File

@@ -137,6 +137,8 @@ pub enum Error {
DmaUnmap(std::io::Error),
// Invalid DMA mapping handler
InvalidDmaMappingHandler,
// Not activated by the guest
NotActivatedByGuest,
}
#[repr(C)]
@@ -327,6 +329,7 @@ impl Request {
pub struct ResizeSender {
hotplugged_size: Arc<AtomicU64>,
activated: Arc<AtomicBool>,
tx: mpsc::Sender<Result<(), Error>>,
evt: EventFd,
}
@@ -345,6 +348,7 @@ impl Clone for ResizeSender {
fn clone(&self) -> Self {
ResizeSender {
hotplugged_size: self.hotplugged_size.clone(),
activated: self.activated.clone(),
tx: self.tx.clone(),
evt: self
.evt
@@ -356,6 +360,7 @@ impl Clone for ResizeSender {
pub struct Resize {
hotplugged_size: Arc<AtomicU64>,
activated: Arc<AtomicBool>,
tx: mpsc::Sender<Result<(), Error>>,
rx: mpsc::Receiver<Result<(), Error>>,
evt: EventFd,
@@ -367,6 +372,7 @@ impl Resize {
Ok(Resize {
hotplugged_size: Arc::new(AtomicU64::new(hotplugged_size)),
activated: Arc::new(AtomicBool::default()),
tx,
rx,
evt: EventFd::new(EFD_NONBLOCK)?,
@@ -376,12 +382,17 @@ impl Resize {
pub fn new_resize_sender(&self) -> Result<ResizeSender, Error> {
Ok(ResizeSender {
hotplugged_size: self.hotplugged_size.clone(),
activated: self.activated.clone(),
tx: self.tx.clone(),
evt: self.evt.try_clone().map_err(Error::EventFdTryCloneFail)?,
})
}
pub fn work(&self, desired_size: u64) -> Result<(), Error> {
if !self.activated.load(Ordering::Acquire) {
return Err(Error::NotActivatedByGuest);
}
self.hotplugged_size.store(desired_size, Ordering::Release);
self.evt.write(1).map_err(Error::EventFdWriteFail)?;
self.rx.recv().map_err(Error::MpscRecvFail)?
@@ -1046,11 +1057,14 @@ impl VirtioDevice for Mem {
)?;
self.common.epoll_threads = Some(epoll_threads);
self.resize.activated.store(true, Ordering::Release);
event!("virtio-device", "activated", "id", &self.id);
Ok(())
}
fn reset(&mut self) -> Option<Arc<dyn VirtioInterrupt>> {
self.resize.activated.store(false, Ordering::Release);
let result = self.common.reset();
event!("virtio-device", "reset", "id", &self.id);
result

View File

@@ -336,7 +336,6 @@ pub fn start_http_path_thread(
seccomp_action: &SeccompAction,
exit_evt: EventFd,
) -> Result<thread::JoinHandle<Result<()>>> {
std::fs::remove_file(path).unwrap_or_default();
let socket_path = PathBuf::from(path);
let socket_fd = UnixListener::bind(socket_path).map_err(Error::CreateApiServerSocket)?;
let server =

View File

@@ -546,6 +546,12 @@ fn vmm_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
(libc::SYS_recvfrom, vec![]),
(libc::SYS_recvmsg, vec![]),
(libc::SYS_restart_syscall, vec![]),
// musl is missing this constant
// (libc::SYS_rseq, vec![]),
#[cfg(target_arch = "x86_64")]
(334, vec![]),
#[cfg(target_arch = "aarch64")]
(293, vec![]),
(libc::SYS_rt_sigaction, vec![]),
(libc::SYS_rt_sigprocmask, vec![]),
(libc::SYS_rt_sigreturn, vec![]),
@@ -680,6 +686,7 @@ fn vcpu_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
(libc::SYS_rt_sigprocmask, vec![]),
(libc::SYS_rt_sigreturn, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_shutdown, vec![]),
(libc::SYS_sigaltstack, vec![]),
(libc::SYS_tgkill, vec![]),
(libc::SYS_tkill, vec![]),

View File

@@ -1477,6 +1477,11 @@ impl Vm {
disks.retain(|dev| dev.id.as_ref() != Some(&id));
}
// Remove if fs device
if let Some(fs) = config.fs.as_mut() {
fs.retain(|dev| dev.id.as_ref() != Some(&id));
}
// Remove if net device
if let Some(net) = config.net.as_mut() {
net.retain(|dev| dev.id.as_ref() != Some(&id));