mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Compare commits
8 Commits
v51.1
...
stable/v23
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
479fef1b8e | ||
|
|
fc8f867879 | ||
|
|
e2eb59bcc8 | ||
|
|
1e557fdb3c | ||
|
|
10ce348aa6 | ||
|
|
63130d0f92 | ||
|
|
e6cc364703 | ||
|
|
a861918f06 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -148,7 +148,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cloud-hypervisor"
|
||||
version = "23.0.0"
|
||||
version = "23.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"api_client",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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![]),
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user