Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/e2e_tests/tests/scsi.rs
5394 views
1
// Copyright 2023 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
//! Integration test for scsi devices as virtio-scsi.
6
7
use std::path::Path;
8
9
use fixture::utils::prepare_disk_img;
10
use fixture::vm::Config;
11
use fixture::vm::TestVm;
12
13
// Mount the scsi device, and then check if simple read, write, and sync operations work.
14
fn mount_scsi_devices(mut config: Config, count: usize) -> anyhow::Result<()> {
15
let disks = (0..count).map(|_| prepare_disk_img()).collect::<Vec<_>>();
16
for disk in &disks {
17
let scsi_disk = disk.path().to_str().unwrap();
18
println!("scsi-disk={scsi_disk}");
19
config = config.extra_args(vec!["--scsi-block".to_string(), scsi_disk.to_string()]);
20
}
21
22
let mut vm = TestVm::new(config).unwrap();
23
for (i, disk) in disks.iter().enumerate() {
24
let dev = format!("/dev/sd{}", char::from(b'a' + i as u8));
25
let dest = Path::new("/mnt").join(disk.path().file_name().unwrap());
26
vm.exec_in_guest("mount -t tmpfs none /mnt")?;
27
vm.exec_in_guest(&format!("mkdir -p {}", dest.display()))?;
28
vm.exec_in_guest(&format!("mount -t ext4 {dev} {}", dest.display()))?;
29
30
let output = dest.join("tmp");
31
vm.exec_in_guest(&format!("echo 42 > {}", output.display()))?;
32
vm.exec_in_guest(&format!("sync -d {}", output.display()))?;
33
assert_eq!(
34
vm.exec_in_guest(&format!("cat {}", output.display()))?
35
.stdout
36
.trim(),
37
"42"
38
);
39
}
40
Ok(())
41
}
42
43
#[test]
44
fn test_scsi_mount() {
45
let config = Config::new();
46
mount_scsi_devices(config, 1).unwrap();
47
}
48
49
#[test]
50
fn test_scsi_mount_disable_sandbox() {
51
let config = Config::new().disable_sandbox();
52
mount_scsi_devices(config, 1).unwrap();
53
}
54
55
#[test]
56
fn test_scsi_mount_multi_devices() {
57
let config = Config::new();
58
mount_scsi_devices(config, 3).unwrap();
59
}
60
61
#[test]
62
fn test_scsi_mount_multi_devices_disable_sandbox() {
63
let config = Config::new().disable_sandbox();
64
mount_scsi_devices(config, 3).unwrap();
65
}
66
67
// This test is for commands in controlq.
68
// First check if the resetting behavior is supported by `sg_opcodes` commands, and then issue the
69
// `sg_reset` command.
70
fn reset_scsi(config: Config) -> anyhow::Result<()> {
71
let disk = prepare_disk_img();
72
let scsi_disk = disk.path().to_str().unwrap();
73
let config = config.extra_args(vec!["--scsi-block".to_string(), scsi_disk.to_string()]);
74
println!("scsi-disk={scsi_disk}");
75
76
let mut vm = TestVm::new(config).unwrap();
77
let cmd = vm.exec_in_guest("sg_opcodes --tmf /dev/sda")?;
78
let stdout = cmd.stdout.trim();
79
assert!(stdout.contains("Logical unit reset"));
80
assert!(stdout.contains("Target reset"));
81
82
assert!(vm.exec_in_guest("sg_reset -d /dev/sda").is_ok());
83
Ok(())
84
}
85
86
#[test]
87
fn test_scsi_reset() {
88
let config = Config::new();
89
reset_scsi(config).unwrap();
90
}
91
92
#[test]
93
fn test_scsi_reset_disable_sandbox() {
94
let config = Config::new().disable_sandbox();
95
reset_scsi(config).unwrap();
96
}
97
98
fn write_same_scsi(config: Config) -> anyhow::Result<()> {
99
let disk = prepare_disk_img();
100
let scsi_disk = disk.path().to_str().unwrap();
101
let config = config.extra_args(vec!["--scsi-block".to_string(), scsi_disk.to_string()]);
102
println!("scsi-disk={scsi_disk}");
103
104
let mut vm = TestVm::new(config)?;
105
assert!(vm
106
.exec_in_guest("sg_write_same --16 --lba=0 --num=1 --unmap /dev/sda")
107
.is_ok());
108
assert!(vm
109
.exec_in_guest("sg_write_same --16 --lba=0 --num=1 /dev/sda")
110
.is_ok());
111
Ok(())
112
}
113
114
#[test]
115
fn test_scsi_write_same() {
116
let config = Config::new();
117
write_same_scsi(config).unwrap();
118
}
119
120
#[test]
121
fn test_scsi_write_same_disable_sandbox() {
122
let config = Config::new().disable_sandbox();
123
write_same_scsi(config).unwrap();
124
}
125
126
fn unmap_scsi(config: Config) -> anyhow::Result<()> {
127
let disk = prepare_disk_img();
128
let scsi_disk = disk.path().to_str().unwrap();
129
let config = config.extra_args(vec!["--scsi-block".to_string(), scsi_disk.to_string()]);
130
println!("scsi-disk={scsi_disk}");
131
132
let mut vm = TestVm::new(config)?;
133
assert!(vm
134
.exec_in_guest("sg_unmap --lba=0 --num=1 -f /dev/sda")
135
.is_ok());
136
Ok(())
137
}
138
139
#[test]
140
fn test_scsi_unmap() {
141
let config = Config::new();
142
unmap_scsi(config).unwrap();
143
}
144
145
#[test]
146
fn test_scsi_unmap_disable_sandbox() {
147
let config = Config::new().disable_sandbox();
148
unmap_scsi(config).unwrap();
149
}
150
151