Skip to content

Commit ee49525

Browse files
acatangiualxiord
authored andcommitted
vmm: simplify block device rescan
We were using two different functions each with its own way to get to the underlying block device and update its backing file, then update its virtio configuration space. This commit drops the 'rescan_block_device()' function and just updated the virtio configuration space in the 'update_drive_disk_image()' function. Signed-off-by: Adrian Catangiu <[email protected]>
1 parent d6fe3fb commit ee49525

File tree

4 files changed

+35
-62
lines changed

4 files changed

+35
-62
lines changed

src/devices/src/virtio/block/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod device;
55
pub mod event_handler;
66
pub mod request;
77

8-
pub use self::device::{build_config_space, Block};
8+
pub use self::device::Block;
99
pub use self::event_handler::*;
1010
pub use self::request::*;
1111

src/vmm/src/controller.rs

Lines changed: 32 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -62,80 +62,55 @@ impl VmmController {
6262
VmmController { vm_resources, vmm }
6363
}
6464

65-
/// Triggers a rescan of the host file backing the emulated block device with id `drive_id`.
66-
pub fn rescan_block_device(&mut self, drive_id: &str) -> ActionResult {
67-
for drive_config in self.vm_resources.block.config_list.iter() {
68-
if drive_config.drive_id != *drive_id {
69-
continue;
70-
}
71-
72-
// Use seek() instead of stat() (std::fs::Metadata) to support block devices.
73-
let new_size = File::open(&drive_config.path_on_host)
74-
.and_then(|mut f| f.seek(SeekFrom::End(0)))
75-
.map_err(|_| DriveError::BlockDeviceUpdateFailed)
76-
.map_err(VmmActionError::DriveConfig)?;
77-
78-
return match self
79-
.vmm
80-
.lock()
81-
.unwrap()
82-
.get_bus_device(DeviceType::Virtio(TYPE_BLOCK), drive_id)
83-
{
84-
Some(device) => {
85-
let data = devices::virtio::build_config_space(new_size);
86-
let mut busdev = device
87-
.lock()
88-
.map_err(|_| DriveError::BlockDeviceUpdateFailed)
89-
.map_err(VmmActionError::DriveConfig)?;
90-
91-
busdev.write(MMIO_CFG_SPACE_OFF, &data[..]);
92-
let _ = busdev.interrupt(devices::virtio::VIRTIO_MMIO_INT_CONFIG);
93-
94-
Ok(())
95-
}
96-
None => Err(VmmActionError::DriveConfig(
97-
DriveError::BlockDeviceUpdateFailed,
98-
)),
99-
};
100-
}
101-
102-
Err(VmmActionError::DriveConfig(
103-
DriveError::InvalidBlockDeviceID,
104-
))
105-
}
106-
10765
fn update_drive_disk_image(
10866
&mut self,
10967
drive_id: &str,
110-
disk_image: File,
68+
mut disk_image: File,
11169
) -> result::Result<(), DriveError> {
11270
if let Some(busdev) = self
11371
.vmm
11472
.lock()
11573
.unwrap()
11674
.get_bus_device(DeviceType::Virtio(TYPE_BLOCK), drive_id)
11775
{
118-
let virtio_device = busdev
76+
// Use seek() instead of stat() (std::fs::Metadata) to support block devices.
77+
let new_size = disk_image
78+
.seek(SeekFrom::End(0))
79+
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?;
80+
// Return cursor to the start of the file.
81+
disk_image
82+
.seek(SeekFrom::Start(0))
83+
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?;
84+
85+
// Call the update_disk_image() handler on Block.
86+
busdev
11987
.lock()
12088
.expect("Poisoned device lock")
12189
.as_any()
122-
.downcast_ref::<MmioTransport>()
12390
// Only MmioTransport implements BusDevice at this point.
91+
.downcast_ref::<MmioTransport>()
12492
.expect("Unexpected BusDevice type")
125-
.device();
126-
127-
// This call wraps the temporary `virtio_device` inside a `MutexGuard`.
128-
let mut lock = virtio_device.lock().expect("Poisoned device lock");
129-
130-
// Downcast the inner virtio_device to a Block.
131-
let block_device: &mut Block = lock
93+
.device()
94+
// Here we get a new clone of Arc<Mutex<dyn VirtioDevice>>.
95+
.lock()
96+
.expect("Poisoned device lock")
13297
.as_mut_any()
98+
// We know this is a block device from the HashMap.
13399
.downcast_mut::<Block>()
134-
.expect("Unexpected Block type");
135-
136-
block_device
100+
.expect("Unexpected VirtioDevice type")
101+
// Now we have a Block, so call its update handler.
137102
.update_disk_image(disk_image)
138-
.map_err(|_| DriveError::BlockDeviceUpdateFailed)
103+
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?;
104+
105+
// Update the virtio config space and kick the driver to pick up the changes.
106+
let new_cfg = devices::virtio::block::device::build_config_space(new_size);
107+
let mut locked_dev = busdev.lock().expect("Poisoned device lock");
108+
locked_dev.write(MMIO_CFG_SPACE_OFF, &new_cfg[..]);
109+
locked_dev
110+
.interrupt(devices::virtio::VIRTIO_MMIO_INT_CONFIG)
111+
.map_err(|_| DriveError::BlockDeviceUpdateFailed)?;
112+
113+
Ok(())
139114
} else {
140115
Err(DriveError::InvalidBlockDeviceID)
141116
}
@@ -168,11 +143,9 @@ impl VmmController {
168143
// Update the path of the block device with the specified path_on_host.
169144
self.vm_resources.block.config_list[block_device_index].path_on_host = file_path;
170145

171-
// When the microvm is running, we also need to update the disk image and send a
172-
// rescan command to the drive.
146+
// We need to update the disk image on the device and its virtio configuration.
173147
self.update_drive_disk_image(&drive_id, disk_file)
174148
.map_err(VmmActionError::DriveConfig)?;
175-
self.rescan_block_device(&drive_id)?;
176149
Ok(())
177150
}
178151

src/vmm/src/device_manager/mmio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ mod tests {
309309
fn update_drive(&self, device_id: &str, new_size: u64) -> Result<()> {
310310
match self.get_device(DeviceType::Virtio(TYPE_BLOCK), device_id) {
311311
Some(device) => {
312-
let data = devices::virtio::build_config_space(new_size);
312+
let data = devices::virtio::block::device::build_config_space(new_size);
313313
let mut busdev = device.lock().map_err(|_| Error::UpdateFailed)?;
314314

315315
busdev.write(MMIO_CFG_SPACE_OFF, &data[..]);

tests/integration_tests/build/test_coverage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import host_tools.cargo_build as host # pylint: disable=import-error
2121

22-
COVERAGE_TARGET_PCT = 82.46
22+
COVERAGE_TARGET_PCT = 82.56
2323
COVERAGE_MAX_DELTA = 0.05
2424

2525
CARGO_KCOV_REL_PATH = os.path.join(host.CARGO_BUILD_REL_PATH, 'kcov')

0 commit comments

Comments
 (0)