Skip to content

Commit

Permalink
tests: Add test_snapshot_restore_with_fd to integration tests
Browse files Browse the repository at this point in the history
VM is created with FDs explicitly passed to CH via --net parameter
and snapshotted. New net FDs are passed in turn during restore.

Signed-off-by: Purna Pavan Chandra <[email protected]>
  • Loading branch information
pupacha committed Apr 22, 2024
1 parent 0f9a9b5 commit c5053d0
Showing 1 changed file with 123 additions and 11 deletions.
134 changes: 123 additions & 11 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5992,26 +5992,62 @@ mod common_parallel {
#[test]
#[cfg(not(feature = "mshv"))]
fn test_snapshot_restore_hotplug_virtiomem() {
_test_snapshot_restore(true);
_test_snapshot_restore(true, false);
}

#[test]
fn test_snapshot_restore_basic() {
_test_snapshot_restore(false);
_test_snapshot_restore(false, false);
}

fn _test_snapshot_restore(use_hotplug: bool) {
#[test]
fn test_snapshot_restore_with_fd() {
_test_snapshot_restore(false, true);
}

fn _test_snapshot_restore(use_hotplug: bool, use_fd: bool) {
let focal = UbuntuDiskConfig::new(FOCAL_IMAGE_NAME.to_string());
let guest = Guest::new(Box::new(focal));
let kernel_path = direct_kernel_boot_path();

let api_socket_source = format!("{}.1", temp_api_path(&guest.tmp_dir));

let net_id = "net123";
let net_params = format!(
"id={},tap=,mac={},ip={},mask=255.255.255.0",
net_id, guest.network.guest_mac, guest.network.host_ip
);
// num_queue_pairs & tap_name are used only if use_fd is set to true
let num_queue_pairs: usize = 2;
let tap_name = "chtap0";
use std::str::FromStr;
let taps = if use_fd {
net_util::open_tap(
Some(tap_name),
Some(std::net::Ipv4Addr::from_str(&guest.network.host_ip).unwrap()),
None,
&mut None,
None,
num_queue_pairs,
Some(libc::O_RDWR | libc::O_NONBLOCK),
)
.unwrap()
} else {
vec![]
};
let net_params = if use_fd {
format!(
"id={},fd=[{},{}],mac={},ip={},mask=255.255.255.0,num_queues={}",
net_id,
taps[0].as_raw_fd(),
taps[1].as_raw_fd(),
guest.network.guest_mac,
guest.network.host_ip,
num_queue_pairs * 2
)
} else {
format!(
"id={},tap=,mac={},ip={},mask=255.255.255.0",
net_id, guest.network.guest_mac, guest.network.host_ip
)
};

let mut mem_params = "size=4G";

if use_hotplug {
Expand Down Expand Up @@ -6056,6 +6092,13 @@ mod common_parallel {
let r = std::panic::catch_unwind(|| {
guest.wait_vm_boot(None).unwrap();

if use_fd {
// close the fds after VM boots, as CH duplicates them before using
for tap in taps.iter() {
unsafe { libc::close(tap.as_raw_fd()) };
}
}

// Check the number of vCPUs
assert_eq!(guest.get_cpu_count().unwrap_or_default(), 4);
// Check the guest RAM
Expand Down Expand Up @@ -6111,12 +6154,45 @@ mod common_parallel {
assert!(check_latest_events_exact(&latest_events, &event_path));

// Plug the virtio-net device again
let taps = if use_fd {
net_util::open_tap(
Some(tap_name),
Some(std::net::Ipv4Addr::from_str(&guest.network.host_ip).unwrap()),
None,
&mut None,
None,
num_queue_pairs,
Some(libc::O_RDWR | libc::O_NONBLOCK),
)
.unwrap()
} else {
vec![]
};
let net_params = if use_fd {
format!(
"id={},fd=[{},{}],mac={},ip={},mask=255.255.255.0,num_queues={}",
net_id,
taps[0].as_raw_fd(),
taps[1].as_raw_fd(),
guest.network.guest_mac,
guest.network.host_ip,
num_queue_pairs * 2
)
} else {
net_params
};
assert!(remote_command(
&api_socket_source,
"add-net",
Some(net_params.as_str()),
));
thread::sleep(std::time::Duration::new(10, 0));
if use_fd {
// close the fds once guest boots up, as CH duplicates them before using
for tap in taps.iter() {
unsafe { libc::close(tap.as_raw_fd()) };
}
}
}

// Pause the VM
Expand Down Expand Up @@ -6188,16 +6264,52 @@ mod common_parallel {
"--event-monitor",
format!("path={event_path_restored}").as_str(),
])
.args([
"--restore",
format!("source_url=file://{snapshot_dir}").as_str(),
])
.capture_output()
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(2, 0));

let taps = if use_fd {
net_util::open_tap(
Some(tap_name),
Some(std::net::Ipv4Addr::from_str(&guest.network.host_ip).unwrap()),
None,
&mut None,
None,
num_queue_pairs,
Some(libc::O_RDWR | libc::O_NONBLOCK),
)
.unwrap()
} else {
vec![]
};
let restore_params = if use_fd {
format!(
"source_url=file://{},net_ids=[{}],net_fds=[{},{}]",
snapshot_dir,
net_id,
taps[0].as_raw_fd(),
taps[1].as_raw_fd()
)
} else {
format!("source_url=file://{}", snapshot_dir)
};
assert!(remote_command(
&api_socket_restored,
"restore",
Some(restore_params.as_str())
));

// Wait for the VM to be restored
thread::sleep(std::time::Duration::new(20, 0));

if use_fd {
// close the fds as CH duplicates them before using
for tap in taps.iter() {
unsafe { libc::close(tap.as_raw_fd()) };
}
}

let expected_events = [
&MetaEvent {
event: "starting".to_string(),
Expand Down

0 comments on commit c5053d0

Please sign in to comment.