@@ -62,80 +62,55 @@ impl VmmController {
62
62
VmmController { vm_resources, vmm }
63
63
}
64
64
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
-
107
65
fn update_drive_disk_image (
108
66
& mut self ,
109
67
drive_id : & str ,
110
- disk_image : File ,
68
+ mut disk_image : File ,
111
69
) -> result:: Result < ( ) , DriveError > {
112
70
if let Some ( busdev) = self
113
71
. vmm
114
72
. lock ( )
115
73
. unwrap ( )
116
74
. get_bus_device ( DeviceType :: Virtio ( TYPE_BLOCK ) , drive_id)
117
75
{
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
119
87
. lock ( )
120
88
. expect ( "Poisoned device lock" )
121
89
. as_any ( )
122
- . downcast_ref :: < MmioTransport > ( )
123
90
// Only MmioTransport implements BusDevice at this point.
91
+ . downcast_ref :: < MmioTransport > ( )
124
92
. 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" )
132
97
. as_mut_any ( )
98
+ // We know this is a block device from the HashMap.
133
99
. 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.
137
102
. 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 ( ( ) )
139
114
} else {
140
115
Err ( DriveError :: InvalidBlockDeviceID )
141
116
}
@@ -168,11 +143,9 @@ impl VmmController {
168
143
// Update the path of the block device with the specified path_on_host.
169
144
self . vm_resources . block . config_list [ block_device_index] . path_on_host = file_path;
170
145
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.
173
147
self . update_drive_disk_image ( & drive_id, disk_file)
174
148
. map_err ( VmmActionError :: DriveConfig ) ?;
175
- self . rescan_block_device ( & drive_id) ?;
176
149
Ok ( ( ) )
177
150
}
178
151
0 commit comments