@@ -72,6 +72,13 @@ pub struct BlockDeviceUpdateConfig {
72
72
pub rate_limiter : Option < RateLimiterConfig > ,
73
73
}
74
74
75
+ /// Enum with all possible block device types.
76
+ #[ derive( Debug ) ]
77
+ pub enum BlockDeviceType {
78
+ /// VirtioBlock type
79
+ VirtioBlock ( Arc < Mutex < VirtioBlock > > ) ,
80
+ }
81
+
75
82
/// Wrapper for the collection that holds all the Block Devices
76
83
#[ derive( Debug , Default ) ]
77
84
pub struct BlockBuilder {
@@ -80,40 +87,46 @@ pub struct BlockBuilder {
80
87
// Root Device should be the first in the list whether or not PARTUUID is
81
88
// specified in order to avoid bugs in case of switching from partuuid boot
82
89
// scenarios to /dev/vda boot type.
83
- pub list : VecDeque < Arc < Mutex < VirtioBlock > > > ,
90
+ pub devices : VecDeque < BlockDeviceType > ,
84
91
}
85
92
86
93
impl BlockBuilder {
87
94
/// Constructor for BlockDevices. It initializes an empty LinkedList.
88
95
pub fn new ( ) -> Self {
89
96
Self {
90
- list : VecDeque :: < Arc < Mutex < VirtioBlock > > > :: new ( ) ,
97
+ devices : Default :: default ( ) ,
91
98
}
92
99
}
93
100
94
101
/// Specifies whether there is a root block device already present in the list.
95
102
fn has_root_device ( & self ) -> bool {
96
103
// If there is a root device, it would be at the top of the list.
97
- if let Some ( block) = self . list . get ( 0 ) {
98
- block. lock ( ) . expect ( "Poisoned lock" ) . is_root_device ( )
104
+ if let Some ( block) = self . devices . get ( 0 ) {
105
+ match block {
106
+ BlockDeviceType :: VirtioBlock ( b) => {
107
+ b. lock ( ) . expect ( "Poisoned lock" ) . is_root_device ( )
108
+ }
109
+ }
99
110
} else {
100
111
false
101
112
}
102
113
}
103
114
104
115
/// Gets the index of the device with the specified `drive_id` if it exists in the list.
105
116
fn get_index_of_drive_id ( & self , drive_id : & str ) -> Option < usize > {
106
- self . list
107
- . iter ( )
108
- . position ( |b| b . lock ( ) . expect ( "Poisoned lock" ) . id ( ) . eq ( drive_id ) )
117
+ self . devices . iter ( ) . position ( |b| match b {
118
+ BlockDeviceType :: VirtioBlock ( b ) => b . lock ( ) . expect ( "Poisoned lock" ) . id ( ) . eq ( drive_id ) ,
119
+ } )
109
120
}
110
121
111
122
/// Inserts an existing block device.
112
123
pub fn add_device ( & mut self , block_device : Arc < Mutex < VirtioBlock > > ) {
113
124
if block_device. lock ( ) . expect ( "Poisoned lock" ) . is_root_device ( ) {
114
- self . list . push_front ( block_device) ;
125
+ self . devices
126
+ . push_front ( BlockDeviceType :: VirtioBlock ( block_device) ) ;
115
127
} else {
116
- self . list . push_back ( block_device) ;
128
+ self . devices
129
+ . push_back ( BlockDeviceType :: VirtioBlock ( block_device) ) ;
117
130
}
118
131
}
119
132
@@ -139,19 +152,21 @@ impl BlockBuilder {
139
152
// New block device.
140
153
None => {
141
154
if is_root_device {
142
- self . list . push_front ( block_dev) ;
155
+ self . devices
156
+ . push_front ( BlockDeviceType :: VirtioBlock ( block_dev) ) ;
143
157
} else {
144
- self . list . push_back ( block_dev) ;
158
+ self . devices
159
+ . push_back ( BlockDeviceType :: VirtioBlock ( block_dev) ) ;
145
160
}
146
161
}
147
162
// Update existing block device.
148
163
Some ( index) => {
149
164
// Update the slot with the new block.
150
- self . list [ index] = block_dev;
165
+ self . devices [ index] = BlockDeviceType :: VirtioBlock ( block_dev) ;
151
166
// Check if the root block device is being updated.
152
167
if index != 0 && is_root_device {
153
168
// Make sure the root device is on the first position.
154
- self . list . swap ( 0 , index) ;
169
+ self . devices . swap ( 0 , index) ;
155
170
}
156
171
}
157
172
}
@@ -160,9 +175,11 @@ impl BlockBuilder {
160
175
161
176
/// Returns a vec with the structures used to configure the devices.
162
177
pub fn configs ( & self ) -> Vec < BlockDeviceConfig > {
163
- self . list
178
+ self . devices
164
179
. iter ( )
165
- . map ( |block| block. lock ( ) . unwrap ( ) . config ( ) . into ( ) )
180
+ . map ( |b| match b {
181
+ BlockDeviceType :: VirtioBlock ( b) => b. lock ( ) . unwrap ( ) . config ( ) . into ( ) ,
182
+ } )
166
183
. collect ( )
167
184
}
168
185
}
@@ -200,7 +217,7 @@ mod tests {
200
217
#[ test]
201
218
fn test_create_block_devs ( ) {
202
219
let block_devs = BlockBuilder :: new ( ) ;
203
- assert_eq ! ( block_devs. list . len( ) , 0 ) ;
220
+ assert_eq ! ( block_devs. devices . len( ) , 0 ) ;
204
221
}
205
222
206
223
#[ test]
@@ -223,13 +240,17 @@ mod tests {
223
240
assert ! ( block_devs. insert( dummy_block_device. clone( ) ) . is_ok( ) ) ;
224
241
225
242
assert ! ( !block_devs. has_root_device( ) ) ;
226
- assert_eq ! ( block_devs. list . len( ) , 1 ) ;
243
+ assert_eq ! ( block_devs. devices . len( ) , 1 ) ;
227
244
228
245
{
229
- let block = block_devs. list [ 0 ] . lock ( ) . unwrap ( ) ;
230
- assert_eq ! ( block. id( ) , & dummy_block_device. drive_id) ;
231
- assert_eq ! ( block. partuuid( ) , dummy_block_device. partuuid. as_ref( ) ) ;
232
- assert_eq ! ( block. is_read_only( ) , dummy_block_device. is_read_only) ;
246
+ match block_devs. devices [ 0 ] {
247
+ BlockDeviceType :: VirtioBlock ( ref b) => {
248
+ let block = b. lock ( ) . unwrap ( ) ;
249
+ assert_eq ! ( block. id( ) , & dummy_block_device. drive_id) ;
250
+ assert_eq ! ( block. partuuid( ) , dummy_block_device. partuuid. as_ref( ) ) ;
251
+ assert_eq ! ( block. is_read_only( ) , dummy_block_device. is_read_only) ;
252
+ }
253
+ }
233
254
}
234
255
assert_eq ! ( block_devs. get_index_of_drive_id( & dummy_id) , Some ( 0 ) ) ;
235
256
}
@@ -254,12 +275,16 @@ mod tests {
254
275
assert ! ( block_devs. insert( dummy_block_device. clone( ) ) . is_ok( ) ) ;
255
276
256
277
assert ! ( block_devs. has_root_device( ) ) ;
257
- assert_eq ! ( block_devs. list . len( ) , 1 ) ;
278
+ assert_eq ! ( block_devs. devices . len( ) , 1 ) ;
258
279
{
259
- let block = block_devs. list [ 0 ] . lock ( ) . unwrap ( ) ;
260
- assert_eq ! ( block. id( ) , & dummy_block_device. drive_id) ;
261
- assert_eq ! ( block. partuuid( ) , dummy_block_device. partuuid. as_ref( ) ) ;
262
- assert_eq ! ( block. is_read_only( ) , dummy_block_device. is_read_only) ;
280
+ match block_devs. devices [ 0 ] {
281
+ BlockDeviceType :: VirtioBlock ( ref b) => {
282
+ let block = b. lock ( ) . unwrap ( ) ;
283
+ assert_eq ! ( block. id( ) , & dummy_block_device. drive_id) ;
284
+ assert_eq ! ( block. partuuid( ) , dummy_block_device. partuuid. as_ref( ) ) ;
285
+ assert_eq ! ( block. is_read_only( ) , dummy_block_device. is_read_only) ;
286
+ }
287
+ }
263
288
}
264
289
}
265
290
@@ -346,21 +371,24 @@ mod tests {
346
371
assert ! ( block_devs. insert( dummy_block_dev_3. clone( ) ) . is_ok( ) ) ;
347
372
assert ! ( block_devs. insert( root_block_device. clone( ) ) . is_ok( ) ) ;
348
373
349
- assert_eq ! ( block_devs. list . len( ) , 3 ) ;
374
+ assert_eq ! ( block_devs. devices . len( ) , 3 ) ;
350
375
351
- let mut block_iter = block_devs. list . iter ( ) ;
352
- assert_eq ! (
353
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
354
- & root_block_device. drive_id
355
- ) ;
356
- assert_eq ! (
357
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
358
- & dummy_block_dev_2. drive_id
359
- ) ;
360
- assert_eq ! (
361
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
362
- & dummy_block_dev_3. drive_id
363
- ) ;
376
+ let mut block_iter = block_devs. devices . iter ( ) ;
377
+ match block_iter. next ( ) . unwrap ( ) {
378
+ BlockDeviceType :: VirtioBlock ( ref b) => {
379
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & root_block_device. drive_id)
380
+ }
381
+ }
382
+ match block_iter. next ( ) . unwrap ( ) {
383
+ BlockDeviceType :: VirtioBlock ( ref b) => {
384
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & dummy_block_dev_2. drive_id)
385
+ }
386
+ }
387
+ match block_iter. next ( ) . unwrap ( ) {
388
+ BlockDeviceType :: VirtioBlock ( ref b) => {
389
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & dummy_block_dev_3. drive_id)
390
+ }
391
+ }
364
392
}
365
393
366
394
#[ test]
@@ -410,23 +438,26 @@ mod tests {
410
438
assert ! ( block_devs. insert( dummy_block_dev_3. clone( ) ) . is_ok( ) ) ;
411
439
assert ! ( block_devs. insert( root_block_device. clone( ) ) . is_ok( ) ) ;
412
440
413
- assert_eq ! ( block_devs. list . len( ) , 3 ) ;
441
+ assert_eq ! ( block_devs. devices . len( ) , 3 ) ;
414
442
415
- let mut block_iter = block_devs. list . iter ( ) ;
443
+ let mut block_iter = block_devs. devices . iter ( ) ;
416
444
// The root device should be first in the list no matter of the order in
417
445
// which the devices were added.
418
- assert_eq ! (
419
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
420
- & root_block_device. drive_id
421
- ) ;
422
- assert_eq ! (
423
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
424
- & dummy_block_dev_2. drive_id
425
- ) ;
426
- assert_eq ! (
427
- block_iter. next( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
428
- & dummy_block_dev_3. drive_id
429
- ) ;
446
+ match block_iter. next ( ) . unwrap ( ) {
447
+ BlockDeviceType :: VirtioBlock ( ref b) => {
448
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & root_block_device. drive_id)
449
+ }
450
+ }
451
+ match block_iter. next ( ) . unwrap ( ) {
452
+ BlockDeviceType :: VirtioBlock ( ref b) => {
453
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & dummy_block_dev_2. drive_id)
454
+ }
455
+ }
456
+ match block_iter. next ( ) . unwrap ( ) {
457
+ BlockDeviceType :: VirtioBlock ( ref b) => {
458
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & dummy_block_dev_3. drive_id)
459
+ }
460
+ }
430
461
}
431
462
432
463
#[ test]
@@ -487,7 +518,9 @@ mod tests {
487
518
. get_index_of_drive_id ( & dummy_block_device_2. drive_id )
488
519
. unwrap ( ) ;
489
520
// Validate update was successful.
490
- assert ! ( block_devs. list[ index] . lock( ) . unwrap( ) . is_read_only( ) ) ;
521
+ match block_devs. devices [ index] {
522
+ BlockDeviceType :: VirtioBlock ( ref b) => assert ! ( b. lock( ) . unwrap( ) . is_read_only( ) ) ,
523
+ }
491
524
492
525
// Update with invalid path.
493
526
let dummy_path_3 = String :: from ( "test_update_3" ) ;
@@ -535,7 +568,11 @@ mod tests {
535
568
assert ! ( block_devs. insert( root_block_device_new) . is_ok( ) ) ;
536
569
assert ! ( block_devs. has_root_device( ) ) ;
537
570
// Verify it's been moved to the first position.
538
- assert_eq ! ( block_devs. list[ 0 ] . lock( ) . unwrap( ) . id( ) , & root_block_id) ;
571
+ match block_devs. devices [ 0 ] {
572
+ BlockDeviceType :: VirtioBlock ( ref b) => {
573
+ assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , & root_block_id)
574
+ }
575
+ }
539
576
}
540
577
541
578
#[ test]
@@ -581,10 +618,9 @@ mod tests {
581
618
let block = VirtioBlock :: new ( config) . unwrap ( ) ;
582
619
583
620
block_devs. add_device ( Arc :: new ( Mutex :: new ( block) ) ) ;
584
- assert_eq ! ( block_devs. list. len( ) , 1 ) ;
585
- assert_eq ! (
586
- block_devs. list. pop_back( ) . unwrap( ) . lock( ) . unwrap( ) . id( ) ,
587
- block_id
588
- )
621
+ assert_eq ! ( block_devs. devices. len( ) , 1 ) ;
622
+ match block_devs. devices . pop_back ( ) . unwrap ( ) {
623
+ BlockDeviceType :: VirtioBlock ( ref b) => assert_eq ! ( b. lock( ) . unwrap( ) . id( ) , block_id) ,
624
+ }
589
625
}
590
626
}
0 commit comments