@@ -13,14 +13,22 @@ pub struct BlockDeviceConfig {
1313 pub drive_id : String ,
1414 pub path_on_host : PathBuf ,
1515 pub is_root_device : bool ,
16+ pub partuuid : Option < String > ,
1617 pub is_read_only : bool ,
1718 pub rate_limiter : Option < RateLimiterDescription > ,
1819}
1920
21+ impl BlockDeviceConfig {
22+ pub fn get_partuuid ( & self ) -> Option < & String > {
23+ self . partuuid . as_ref ( )
24+ }
25+ }
26+
2027// Wrapper for the collection that holds all the Block Devices Configs
2128pub struct BlockDeviceConfigs {
2229 pub config_list : LinkedList < BlockDeviceConfig > ,
2330 has_root_block : bool ,
31+ has_partuuid_root : bool ,
2432 read_only_root : bool ,
2533}
2634
@@ -31,6 +39,7 @@ impl From<DriveDescription> for BlockDeviceConfig {
3139 drive_id : item. drive_id ,
3240 path_on_host : PathBuf :: from ( item. path_on_host ) ,
3341 is_root_device : item. is_root_device ,
42+ partuuid : item. partuuid ,
3443 is_read_only,
3544 rate_limiter : item. rate_limiter ,
3645 }
@@ -42,6 +51,7 @@ impl BlockDeviceConfigs {
4251 BlockDeviceConfigs {
4352 config_list : LinkedList :: < BlockDeviceConfig > :: new ( ) ,
4453 has_root_block : false ,
54+ has_partuuid_root : false ,
4555 read_only_root : false ,
4656 }
4757 }
@@ -54,6 +64,10 @@ impl BlockDeviceConfigs {
5464 self . read_only_root
5565 }
5666
67+ pub fn has_partuuid_root ( & self ) -> bool {
68+ self . has_partuuid_root
69+ }
70+
5771 pub fn contains_drive_path ( & self , drive_path : PathBuf ) -> bool {
5872 for drive_config in self . config_list . iter ( ) {
5973 if drive_config. path_on_host == drive_path {
@@ -92,7 +106,10 @@ impl BlockDeviceConfigs {
92106 } else {
93107 self . has_root_block = true ;
94108 self . read_only_root = block_device_config. is_read_only ;
95- // Root Device should be the first in the list
109+ self . has_partuuid_root = block_device_config. partuuid . is_some ( ) ;
110+ // Root Device should be the first in the list whether or not PARTUUID is specified
111+ // in order to avoid bugs in case of switching from partuuid boot scenarios to
112+ // /dev/vda boot type.
96113 self . config_list . push_front ( block_device_config) ;
97114 }
98115 } else {
@@ -118,7 +135,7 @@ impl BlockDeviceConfigs {
118135 /// This function updates a Block Device Config prior to the guest boot. The update fails if it
119136 /// would result in two root block devices.
120137 pub fn update ( & mut self , block_device_config : & BlockDeviceConfig ) -> Result < ( ) > {
121- // Check if the path exists
138+ // Check if the path exists.
122139 if !block_device_config. path_on_host . exists ( ) {
123140 return Err ( DriveError :: InvalidBlockDevicePath ) ;
124141 }
@@ -127,23 +144,27 @@ impl BlockDeviceConfigs {
127144 for cfg in self . config_list . iter_mut ( ) {
128145 if cfg. drive_id == block_device_config. drive_id {
129146 if cfg. is_root_device {
130- // Check if the root block device is being updated
147+ // Check if the root block device is being updated.
131148 self . has_root_block = block_device_config. is_root_device ;
132149 self . read_only_root =
133150 block_device_config. is_root_device && block_device_config. is_read_only ;
151+ self . has_partuuid_root = block_device_config. partuuid . is_some ( ) ;
134152 } else if block_device_config. is_root_device {
135- // Check if a second root block device is being added
153+ // Check if a second root block device is being added.
136154 if root_id. is_some ( ) {
137155 return Err ( DriveError :: RootBlockDeviceAlreadyAdded ) ;
138156 } else {
139- // One of the non-root blocks is becoming root
157+ // One of the non-root blocks is becoming root.
140158 self . has_root_block = true ;
141159 self . read_only_root = block_device_config. is_read_only ;
160+ self . has_partuuid_root = block_device_config. partuuid . is_some ( ) ;
142161 }
143162 }
144163 cfg. is_root_device = block_device_config. is_root_device ;
145164 cfg. path_on_host = block_device_config. path_on_host . clone ( ) ;
146165 cfg. is_read_only = block_device_config. is_read_only ;
166+ cfg. rate_limiter = block_device_config. rate_limiter . clone ( ) ;
167+ cfg. partuuid = block_device_config. partuuid . clone ( ) ;
147168
148169 return Ok ( ( ) ) ;
149170 }
@@ -177,6 +198,7 @@ mod tests {
177198 let dummy_block_device = BlockDeviceConfig {
178199 path_on_host : dummy_path. clone ( ) ,
179200 is_root_device : false ,
201+ partuuid : None ,
180202 is_read_only : false ,
181203 drive_id : dummy_id. clone ( ) ,
182204 rate_limiter : None ,
@@ -206,6 +228,7 @@ mod tests {
206228 let dummy_block_device = BlockDeviceConfig {
207229 path_on_host : dummy_path,
208230 is_root_device : true ,
231+ partuuid : None ,
209232 is_read_only : true ,
210233 drive_id : String :: from ( "1" ) ,
211234 rate_limiter : None ,
@@ -232,6 +255,7 @@ mod tests {
232255 let root_block_device_1 = BlockDeviceConfig {
233256 path_on_host : dummy_path_1,
234257 is_root_device : true ,
258+ partuuid : None ,
235259 is_read_only : false ,
236260 drive_id : String :: from ( "1" ) ,
237261 rate_limiter : None ,
@@ -242,6 +266,7 @@ mod tests {
242266 let root_block_device_2 = BlockDeviceConfig {
243267 path_on_host : dummy_path_2,
244268 is_root_device : true ,
269+ partuuid : None ,
245270 is_read_only : false ,
246271 drive_id : String :: from ( "2" ) ,
247272 rate_limiter : None ,
@@ -263,6 +288,7 @@ mod tests {
263288 let root_block_device = BlockDeviceConfig {
264289 path_on_host : dummy_path_1,
265290 is_root_device : true ,
291+ partuuid : None ,
266292 is_read_only : false ,
267293 drive_id : String :: from ( "1" ) ,
268294 rate_limiter : None ,
@@ -273,6 +299,7 @@ mod tests {
273299 let dummy_block_device_2 = BlockDeviceConfig {
274300 path_on_host : dummy_path_2,
275301 is_root_device : false ,
302+ partuuid : None ,
276303 is_read_only : false ,
277304 drive_id : String :: from ( "2" ) ,
278305 rate_limiter : None ,
@@ -283,6 +310,7 @@ mod tests {
283310 let dummy_block_device_3 = BlockDeviceConfig {
284311 path_on_host : dummy_path_3,
285312 is_root_device : false ,
313+ partuuid : None ,
286314 is_read_only : false ,
287315 drive_id : String :: from ( "3" ) ,
288316 rate_limiter : None ,
@@ -319,6 +347,7 @@ mod tests {
319347 let root_block_device = BlockDeviceConfig {
320348 path_on_host : dummy_path_1,
321349 is_root_device : true ,
350+ partuuid : None ,
322351 is_read_only : false ,
323352 drive_id : String :: from ( "1" ) ,
324353 rate_limiter : None ,
@@ -329,6 +358,7 @@ mod tests {
329358 let dummy_block_device_2 = BlockDeviceConfig {
330359 path_on_host : dummy_path_2,
331360 is_root_device : false ,
361+ partuuid : None ,
332362 is_read_only : false ,
333363 drive_id : String :: from ( "2" ) ,
334364 rate_limiter : None ,
@@ -339,6 +369,7 @@ mod tests {
339369 let dummy_block_device_3 = BlockDeviceConfig {
340370 path_on_host : dummy_path_3,
341371 is_root_device : false ,
372+ partuuid : None ,
342373 is_read_only : false ,
343374 drive_id : String :: from ( "3" ) ,
344375 rate_limiter : None ,
@@ -361,7 +392,8 @@ mod tests {
361392 assert_eq ! ( block_devices_configs. config_list. len( ) , 3 ) ;
362393
363394 let mut block_dev_iter = block_devices_configs. config_list . iter ( ) ;
364- // The root device should be first in the list no matter of the order in which the devices were added
395+ // The root device should be first in the list no matter of the order in
396+ // which the devices were added.
365397 assert_eq ! ( block_dev_iter. next( ) . unwrap( ) , & root_block_device) ;
366398 assert_eq ! ( block_dev_iter. next( ) . unwrap( ) , & dummy_block_device_2) ;
367399 assert_eq ! ( block_dev_iter. next( ) . unwrap( ) , & dummy_block_device_3) ;
@@ -371,6 +403,7 @@ mod tests {
371403 fn test_from_drive_description ( ) {
372404 let dd = DriveDescription {
373405 is_root_device : true ,
406+ partuuid : None ,
374407 path_on_host : String :: from ( "/foo/bar" ) ,
375408 drive_id : String :: from ( "foo" ) ,
376409 state : DeviceState :: Attached ,
@@ -392,6 +425,7 @@ mod tests {
392425 let root_block_device = BlockDeviceConfig {
393426 path_on_host : dummy_path_1,
394427 is_root_device : true ,
428+ partuuid : None ,
395429 is_read_only : false ,
396430 drive_id : String :: from ( "1" ) ,
397431 rate_limiter : None ,
@@ -402,6 +436,7 @@ mod tests {
402436 let mut dummy_block_device_2 = BlockDeviceConfig {
403437 path_on_host : dummy_path_2. clone ( ) ,
404438 is_root_device : false ,
439+ partuuid : None ,
405440 is_read_only : false ,
406441 drive_id : String :: from ( "2" ) ,
407442 rate_limiter : None ,
0 commit comments