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