xref: /aosp_15_r20/external/crosvm/e2e_tests/tests/block.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Testing virtio-block.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(any(target_os = "android", target_os = "linux"))]
8*bb4ee6a4SAndroid Build Coastguard Worker 
9*bb4ee6a4SAndroid Build Coastguard Worker use std::time;
10*bb4ee6a4SAndroid Build Coastguard Worker 
11*bb4ee6a4SAndroid Build Coastguard Worker use fixture::utils::create_vu_block_config;
12*bb4ee6a4SAndroid Build Coastguard Worker use fixture::utils::prepare_disk_img;
13*bb4ee6a4SAndroid Build Coastguard Worker use fixture::utils::DEFAULT_BLOCK_SIZE;
14*bb4ee6a4SAndroid Build Coastguard Worker use fixture::vhost_user::CmdType;
15*bb4ee6a4SAndroid Build Coastguard Worker use fixture::vhost_user::VhostUserBackend;
16*bb4ee6a4SAndroid Build Coastguard Worker use fixture::vm::Config as VmConfig;
17*bb4ee6a4SAndroid Build Coastguard Worker use fixture::vm::TestVm;
18*bb4ee6a4SAndroid Build Coastguard Worker use tempfile::NamedTempFile;
19*bb4ee6a4SAndroid Build Coastguard Worker 
20*bb4ee6a4SAndroid Build Coastguard Worker /// Tests virtio-blk device is mountable.
21*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/243127498): Add tests for write and sync operations.
22*bb4ee6a4SAndroid Build Coastguard Worker #[test]
test_mount_block()23*bb4ee6a4SAndroid Build Coastguard Worker fn test_mount_block() {
24*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new();
25*bb4ee6a4SAndroid Build Coastguard Worker     mount_block(config);
26*bb4ee6a4SAndroid Build Coastguard Worker }
27*bb4ee6a4SAndroid Build Coastguard Worker 
28*bb4ee6a4SAndroid Build Coastguard Worker #[test]
test_mount_block_disable_sandbox()29*bb4ee6a4SAndroid Build Coastguard Worker fn test_mount_block_disable_sandbox() {
30*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new().disable_sandbox();
31*bb4ee6a4SAndroid Build Coastguard Worker     mount_block(config);
32*bb4ee6a4SAndroid Build Coastguard Worker }
33*bb4ee6a4SAndroid Build Coastguard Worker 
mount_block(config: VmConfig)34*bb4ee6a4SAndroid Build Coastguard Worker fn mount_block(config: VmConfig) {
35*bb4ee6a4SAndroid Build Coastguard Worker     let disk = prepare_disk_img();
36*bb4ee6a4SAndroid Build Coastguard Worker     let disk_path = disk.path().to_str().unwrap();
37*bb4ee6a4SAndroid Build Coastguard Worker     println!("disk={disk_path}");
38*bb4ee6a4SAndroid Build Coastguard Worker 
39*bb4ee6a4SAndroid Build Coastguard Worker     let config = config.extra_args(vec!["--block".to_string(), format!("{},ro", disk_path)]);
40*bb4ee6a4SAndroid Build Coastguard Worker     let mut vm = TestVm::new(config).unwrap();
41*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
42*bb4ee6a4SAndroid Build Coastguard Worker         vm.exec_in_guest("mount -t ext4 /dev/vdb /mnt && echo 42")
43*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
44*bb4ee6a4SAndroid Build Coastguard Worker             .stdout
45*bb4ee6a4SAndroid Build Coastguard Worker             .trim(),
46*bb4ee6a4SAndroid Build Coastguard Worker         "42"
47*bb4ee6a4SAndroid Build Coastguard Worker     );
48*bb4ee6a4SAndroid Build Coastguard Worker }
49*bb4ee6a4SAndroid Build Coastguard Worker 
50*bb4ee6a4SAndroid Build Coastguard Worker /// Tests `crosvm disk resize` works.
51*bb4ee6a4SAndroid Build Coastguard Worker #[test]
test_resize()52*bb4ee6a4SAndroid Build Coastguard Worker fn test_resize() {
53*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new();
54*bb4ee6a4SAndroid Build Coastguard Worker     resize(config);
55*bb4ee6a4SAndroid Build Coastguard Worker }
56*bb4ee6a4SAndroid Build Coastguard Worker 
57*bb4ee6a4SAndroid Build Coastguard Worker #[test]
test_resize_disable_sandbox()58*bb4ee6a4SAndroid Build Coastguard Worker fn test_resize_disable_sandbox() {
59*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new().disable_sandbox();
60*bb4ee6a4SAndroid Build Coastguard Worker     resize(config);
61*bb4ee6a4SAndroid Build Coastguard Worker }
62*bb4ee6a4SAndroid Build Coastguard Worker 
resize(config: VmConfig)63*bb4ee6a4SAndroid Build Coastguard Worker fn resize(config: VmConfig) {
64*bb4ee6a4SAndroid Build Coastguard Worker     let disk = prepare_disk_img();
65*bb4ee6a4SAndroid Build Coastguard Worker     let disk_path = disk.path().to_str().unwrap().to_string();
66*bb4ee6a4SAndroid Build Coastguard Worker     println!("disk={disk_path}");
67*bb4ee6a4SAndroid Build Coastguard Worker 
68*bb4ee6a4SAndroid Build Coastguard Worker     let config = config.extra_args(vec!["--block".to_string(), disk_path]);
69*bb4ee6a4SAndroid Build Coastguard Worker     let mut vm = TestVm::new(config).unwrap();
70*bb4ee6a4SAndroid Build Coastguard Worker 
71*bb4ee6a4SAndroid Build Coastguard Worker     // Check the initial block device size.
72*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
73*bb4ee6a4SAndroid Build Coastguard Worker         vm.exec_in_guest("blockdev --getsize64 /dev/vdb")
74*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
75*bb4ee6a4SAndroid Build Coastguard Worker             .stdout
76*bb4ee6a4SAndroid Build Coastguard Worker             .trim()
77*bb4ee6a4SAndroid Build Coastguard Worker             .parse::<u64>()
78*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap(),
79*bb4ee6a4SAndroid Build Coastguard Worker         DEFAULT_BLOCK_SIZE
80*bb4ee6a4SAndroid Build Coastguard Worker     );
81*bb4ee6a4SAndroid Build Coastguard Worker 
82*bb4ee6a4SAndroid Build Coastguard Worker     let new_size = DEFAULT_BLOCK_SIZE * 2;
83*bb4ee6a4SAndroid Build Coastguard Worker 
84*bb4ee6a4SAndroid Build Coastguard Worker     // The index of the disk to resize.
85*bb4ee6a4SAndroid Build Coastguard Worker     let disk_index = 1;
86*bb4ee6a4SAndroid Build Coastguard Worker 
87*bb4ee6a4SAndroid Build Coastguard Worker     vm.disk(vec![
88*bb4ee6a4SAndroid Build Coastguard Worker         "resize".to_string(),
89*bb4ee6a4SAndroid Build Coastguard Worker         disk_index.to_string(),
90*bb4ee6a4SAndroid Build Coastguard Worker         new_size.to_string(),
91*bb4ee6a4SAndroid Build Coastguard Worker     ])
92*bb4ee6a4SAndroid Build Coastguard Worker     .expect("Disk resizing command failed");
93*bb4ee6a4SAndroid Build Coastguard Worker 
94*bb4ee6a4SAndroid Build Coastguard Worker     // Allow block device size to be updated within 500ms
95*bb4ee6a4SAndroid Build Coastguard Worker     let now = time::Instant::now();
96*bb4ee6a4SAndroid Build Coastguard Worker 
97*bb4ee6a4SAndroid Build Coastguard Worker     while now.elapsed() <= time::Duration::from_millis(500) {
98*bb4ee6a4SAndroid Build Coastguard Worker         if vm
99*bb4ee6a4SAndroid Build Coastguard Worker             .exec_in_guest("blockdev --getsize64 /dev/vdb")
100*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
101*bb4ee6a4SAndroid Build Coastguard Worker             .stdout
102*bb4ee6a4SAndroid Build Coastguard Worker             .trim()
103*bb4ee6a4SAndroid Build Coastguard Worker             .parse::<u64>()
104*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
105*bb4ee6a4SAndroid Build Coastguard Worker             == new_size
106*bb4ee6a4SAndroid Build Coastguard Worker         {
107*bb4ee6a4SAndroid Build Coastguard Worker             return;
108*bb4ee6a4SAndroid Build Coastguard Worker         }
109*bb4ee6a4SAndroid Build Coastguard Worker     }
110*bb4ee6a4SAndroid Build Coastguard Worker     // Check the new block device size.
111*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
112*bb4ee6a4SAndroid Build Coastguard Worker         vm.exec_in_guest("blockdev --getsize64 /dev/vdb")
113*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
114*bb4ee6a4SAndroid Build Coastguard Worker             .stdout
115*bb4ee6a4SAndroid Build Coastguard Worker             .trim()
116*bb4ee6a4SAndroid Build Coastguard Worker             .parse::<u64>()
117*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap(),
118*bb4ee6a4SAndroid Build Coastguard Worker         new_size
119*bb4ee6a4SAndroid Build Coastguard Worker     );
120*bb4ee6a4SAndroid Build Coastguard Worker }
121*bb4ee6a4SAndroid Build Coastguard Worker 
run_vhost_user_test(cmd_type: CmdType, config: VmConfig)122*bb4ee6a4SAndroid Build Coastguard Worker fn run_vhost_user_test(cmd_type: CmdType, config: VmConfig) {
123*bb4ee6a4SAndroid Build Coastguard Worker     let socket = NamedTempFile::new().unwrap();
124*bb4ee6a4SAndroid Build Coastguard Worker     let disk = prepare_disk_img();
125*bb4ee6a4SAndroid Build Coastguard Worker 
126*bb4ee6a4SAndroid Build Coastguard Worker     let vu_config = create_vu_block_config(cmd_type, socket.path(), disk.path());
127*bb4ee6a4SAndroid Build Coastguard Worker     let _vu_device = VhostUserBackend::new(vu_config).unwrap();
128*bb4ee6a4SAndroid Build Coastguard Worker 
129*bb4ee6a4SAndroid Build Coastguard Worker     let config = config.with_vhost_user("block", socket.path());
130*bb4ee6a4SAndroid Build Coastguard Worker     let mut vm = TestVm::new(config).unwrap();
131*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(
132*bb4ee6a4SAndroid Build Coastguard Worker         vm.exec_in_guest("mount -t ext4 /dev/vdb /mnt && echo 42")
133*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
134*bb4ee6a4SAndroid Build Coastguard Worker             .stdout
135*bb4ee6a4SAndroid Build Coastguard Worker             .trim(),
136*bb4ee6a4SAndroid Build Coastguard Worker         "42"
137*bb4ee6a4SAndroid Build Coastguard Worker     );
138*bb4ee6a4SAndroid Build Coastguard Worker }
139*bb4ee6a4SAndroid Build Coastguard Worker 
140*bb4ee6a4SAndroid Build Coastguard Worker /// Tests vhost-user block device with `crosvm device`.
141*bb4ee6a4SAndroid Build Coastguard Worker #[test]
vhost_user_mount()142*bb4ee6a4SAndroid Build Coastguard Worker fn vhost_user_mount() {
143*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new();
144*bb4ee6a4SAndroid Build Coastguard Worker     run_vhost_user_test(CmdType::Device, config);
145*bb4ee6a4SAndroid Build Coastguard Worker }
146*bb4ee6a4SAndroid Build Coastguard Worker 
147*bb4ee6a4SAndroid Build Coastguard Worker /// Tests vhost-user block device with `crosvm devices` (not `device`).
148*bb4ee6a4SAndroid Build Coastguard Worker #[test]
vhost_user_mount_with_devices()149*bb4ee6a4SAndroid Build Coastguard Worker fn vhost_user_mount_with_devices() {
150*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new();
151*bb4ee6a4SAndroid Build Coastguard Worker     run_vhost_user_test(CmdType::Devices, config);
152*bb4ee6a4SAndroid Build Coastguard Worker }
153*bb4ee6a4SAndroid Build Coastguard Worker 
154*bb4ee6a4SAndroid Build Coastguard Worker /// Tests vhost-user block device with `crosvm device`.
155*bb4ee6a4SAndroid Build Coastguard Worker #[test]
vhost_user_mount_disable_sandbox()156*bb4ee6a4SAndroid Build Coastguard Worker fn vhost_user_mount_disable_sandbox() {
157*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new().disable_sandbox();
158*bb4ee6a4SAndroid Build Coastguard Worker     run_vhost_user_test(CmdType::Device, config);
159*bb4ee6a4SAndroid Build Coastguard Worker }
160*bb4ee6a4SAndroid Build Coastguard Worker 
161*bb4ee6a4SAndroid Build Coastguard Worker /// Tests vhost-user block device with `crosvm devices` (not `device`).
162*bb4ee6a4SAndroid Build Coastguard Worker #[test]
vhost_user_mount_with_devices_disable_sandbox()163*bb4ee6a4SAndroid Build Coastguard Worker fn vhost_user_mount_with_devices_disable_sandbox() {
164*bb4ee6a4SAndroid Build Coastguard Worker     let config = VmConfig::new().disable_sandbox();
165*bb4ee6a4SAndroid Build Coastguard Worker     run_vhost_user_test(CmdType::Devices, config);
166*bb4ee6a4SAndroid Build Coastguard Worker }
167