dragonball: Convert BlockDeviceMgr function to method

Convert BlockDeviceMgr::insert_device, BlockDeviceMgr::remove_device
and BlockDeviceMgr::update_device_ratelimiters to method.

Fixes: #6880

Signed-off-by: Shuaiyi Zhang <zhang_syi@qq.com>
This commit is contained in:
Shuaiyi Zhang 2023-05-16 20:56:56 +08:00
parent 8d10d157b3
commit 4659facb74
2 changed files with 102 additions and 65 deletions

View File

@ -486,7 +486,9 @@ impl VmmService {
VmmActionError::Block(BlockDeviceError::UpdateNotAllowedPostBoot) VmmActionError::Block(BlockDeviceError::UpdateNotAllowedPostBoot)
})?; })?;
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, config) vm.device_manager_mut()
.block_manager
.insert_device(ctx, config)
.map(|_| VmmData::Empty) .map(|_| VmmData::Empty)
.map_err(VmmActionError::Block) .map_err(VmmActionError::Block)
} }
@ -500,7 +502,9 @@ impl VmmService {
) -> VmmRequestResult { ) -> VmmRequestResult {
let vm = vmm.get_vm_mut().ok_or(VmmActionError::InvalidVMID)?; let vm = vmm.get_vm_mut().ok_or(VmmActionError::InvalidVMID)?;
BlockDeviceMgr::update_device_ratelimiters(vm.device_manager_mut(), config) vm.device_manager_mut()
.block_manager
.update_device_ratelimiters(config)
.map(|_| VmmData::Empty) .map(|_| VmmData::Empty)
.map_err(VmmActionError::Block) .map_err(VmmActionError::Block)
} }
@ -518,7 +522,9 @@ impl VmmService {
.create_device_op_context(Some(event_mgr.epoll_manager())) .create_device_op_context(Some(event_mgr.epoll_manager()))
.map_err(|_| VmmActionError::Block(BlockDeviceError::UpdateNotAllowedPostBoot))?; .map_err(|_| VmmActionError::Block(BlockDeviceError::UpdateNotAllowedPostBoot))?;
BlockDeviceMgr::remove_device(vm.device_manager_mut(), ctx, drive_id) vm.device_manager_mut()
.block_manager
.remove_device(ctx, drive_id)
.map(|_| VmmData::Empty) .map(|_| VmmData::Empty)
.map_err(VmmActionError::Block) .map_err(VmmActionError::Block)
} }

View File

@ -340,7 +340,7 @@ impl BlockDeviceMgr {
/// the existing entry. /// the existing entry.
/// Inserting a secondary root block device will fail. /// Inserting a secondary root block device will fail.
pub fn insert_device( pub fn insert_device(
device_mgr: &mut DeviceManager, &mut self,
mut ctx: DeviceOpContext, mut ctx: DeviceOpContext,
config: BlockDeviceConfigInfo, config: BlockDeviceConfigInfo,
) -> std::result::Result<(), BlockDeviceError> { ) -> std::result::Result<(), BlockDeviceError> {
@ -348,10 +348,8 @@ impl BlockDeviceMgr {
return Err(BlockDeviceError::UpdateNotAllowedPostBoot); return Err(BlockDeviceError::UpdateNotAllowedPostBoot);
} }
let mgr = &mut device_mgr.block_manager;
// If the id of the drive already exists in the list, the operation is update. // If the id of the drive already exists in the list, the operation is update.
match mgr.get_index_of_drive_id(config.id()) { match self.get_index_of_drive_id(config.id()) {
Some(index) => { Some(index) => {
// No support for runtime update yet. // No support for runtime update yet.
if ctx.is_hotplug { if ctx.is_hotplug {
@ -359,19 +357,19 @@ impl BlockDeviceMgr {
config.path_on_host.clone(), config.path_on_host.clone(),
)) ))
} else { } else {
for (idx, info) in mgr.info_list.iter().enumerate() { for (idx, info) in self.info_list.iter().enumerate() {
if idx != index { if idx != index {
info.config.check_conflicts(&config)?; info.config.check_conflicts(&config)?;
} }
} }
mgr.update(index, config) self.update(index, config)
} }
} }
None => { None => {
for info in mgr.info_list.iter() { for info in self.info_list.iter() {
info.config.check_conflicts(&config)?; info.config.check_conflicts(&config)?;
} }
let index = mgr.create(config.clone())?; let index = self.create(config.clone())?;
if !ctx.is_hotplug { if !ctx.is_hotplug {
return Ok(()); return Ok(());
} }
@ -383,17 +381,16 @@ impl BlockDeviceMgr {
let dev = DeviceManager::create_mmio_virtio_device( let dev = DeviceManager::create_mmio_virtio_device(
device, device,
&mut ctx, &mut ctx,
config.use_shared_irq.unwrap_or(mgr.use_shared_irq), config.use_shared_irq.unwrap_or(self.use_shared_irq),
config.use_generic_irq.unwrap_or(USE_GENERIC_IRQ), config.use_generic_irq.unwrap_or(USE_GENERIC_IRQ),
) )
.map_err(BlockDeviceError::DeviceManager)?; .map_err(BlockDeviceError::DeviceManager)?;
mgr.update_device_by_index(index, Arc::clone(&dev))?; self.update_device_by_index(index, Arc::clone(&dev))?;
// live-upgrade need save/restore device from info.device. // live-upgrade need save/restore device from info.device.
mgr.info_list[index].set_device(dev.clone()); self.info_list[index].set_device(dev.clone());
ctx.insert_hotplug_mmio_device(&dev, None).map_err(|e| { ctx.insert_hotplug_mmio_device(&dev, None).map_err(|e| {
let logger = ctx.logger().new(slog::o!()); let logger = ctx.logger().new(slog::o!());
BlockDeviceMgr::remove_device(device_mgr, ctx, &config.drive_id) self.remove_device(ctx, &config.drive_id).unwrap();
.unwrap();
error!( error!(
logger, logger,
"failed to hot-add virtio block device {}, {:?}", "failed to hot-add virtio block device {}, {:?}",
@ -466,7 +463,7 @@ impl BlockDeviceMgr {
/// remove a block device, it basically is the inverse operation of `insert_device`` /// remove a block device, it basically is the inverse operation of `insert_device``
pub fn remove_device( pub fn remove_device(
dev_mgr: &mut DeviceManager, &mut self,
mut ctx: DeviceOpContext, mut ctx: DeviceOpContext,
drive_id: &str, drive_id: &str,
) -> std::result::Result<(), BlockDeviceError> { ) -> std::result::Result<(), BlockDeviceError> {
@ -474,8 +471,7 @@ impl BlockDeviceMgr {
return Err(BlockDeviceError::UpdateNotAllowedPostBoot); return Err(BlockDeviceError::UpdateNotAllowedPostBoot);
} }
let mgr = &mut dev_mgr.block_manager; match self.remove(drive_id) {
match mgr.remove(drive_id) {
Some(mut info) => { Some(mut info) => {
info!(ctx.logger(), "remove drive {}", info.config.drive_id); info!(ctx.logger(), "remove drive {}", info.config.drive_id);
if let Some(device) = info.device.take() { if let Some(device) = info.device.take() {
@ -731,15 +727,14 @@ impl BlockDeviceMgr {
/// Update the ratelimiter settings of a virtio blk device. /// Update the ratelimiter settings of a virtio blk device.
pub fn update_device_ratelimiters( pub fn update_device_ratelimiters(
device_mgr: &mut DeviceManager, &mut self,
new_cfg: BlockDeviceConfigUpdateInfo, new_cfg: BlockDeviceConfigUpdateInfo,
) -> std::result::Result<(), BlockDeviceError> { ) -> std::result::Result<(), BlockDeviceError> {
let mgr = &mut device_mgr.block_manager; match self.get_index_of_drive_id(&new_cfg.drive_id) {
match mgr.get_index_of_drive_id(&new_cfg.drive_id) {
Some(index) => { Some(index) => {
let config = &mut mgr.info_list[index].config; let config = &mut self.info_list[index].config;
config.rate_limiter = new_cfg.rate_limiter.clone(); config.rate_limiter = new_cfg.rate_limiter.clone();
let device = mgr.info_list[index] let device = self.info_list[index]
.device .device
.as_mut() .as_mut()
.ok_or_else(|| BlockDeviceError::InvalidDeviceId("".to_owned()))?; .ok_or_else(|| BlockDeviceError::InvalidDeviceId("".to_owned()))?;
@ -827,12 +822,11 @@ mod tests {
let mut vm = crate::vm::tests::create_vm_instance(); let mut vm = crate::vm::tests::create_vm_instance();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
assert!(BlockDeviceMgr::insert_device( assert!(vm
vm.device_manager_mut(), .device_manager_mut()
ctx, .block_manager
dummy_block_device.clone(), .insert_device(ctx, dummy_block_device.clone(),)
) .is_ok());
.is_ok());
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1); assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
assert!(!vm.device_manager().block_manager.has_root_block_device()); assert!(!vm.device_manager().block_manager.has_root_block_device());
@ -897,7 +891,9 @@ mod tests {
use_shared_irq: None, use_shared_irq: None,
use_generic_irq: None, use_generic_irq: None,
}; };
BlockDeviceMgr::insert_device(vm.device_manager_mut(), device_op_ctx, dummy_block_device) vm.device_manager_mut()
.block_manager
.insert_device(device_op_ctx, dummy_block_device)
.unwrap(); .unwrap();
let cfg = BlockDeviceConfigUpdateInfo { let cfg = BlockDeviceConfigUpdateInfo {
@ -923,7 +919,9 @@ mod tests {
let expected_error = "could not send patch message to the block epoll handler".to_string(); let expected_error = "could not send patch message to the block epoll handler".to_string();
assert_eq!( assert_eq!(
BlockDeviceMgr::update_device_ratelimiters(vm.device_manager_mut(), cfg) vm.device_manager_mut()
.block_manager
.update_device_ratelimiters(cfg)
.unwrap_err() .unwrap_err()
.to_string(), .to_string(),
expected_error expected_error
@ -938,7 +936,9 @@ mod tests {
let expected_error = format!("invalid block device id '{0}'", cfg2.drive_id); let expected_error = format!("invalid block device id '{0}'", cfg2.drive_id);
assert_eq!( assert_eq!(
BlockDeviceMgr::update_device_ratelimiters(vm.device_manager_mut(), cfg2) vm.device_manager_mut()
.block_manager
.update_device_ratelimiters(cfg2)
.unwrap_err() .unwrap_err()
.to_string(), .to_string(),
expected_error expected_error
@ -968,12 +968,11 @@ mod tests {
let mut vm = crate::vm::tests::create_vm_instance(); let mut vm = crate::vm::tests::create_vm_instance();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
assert!(BlockDeviceMgr::insert_device( assert!(vm
vm.device_manager_mut(), .device_manager_mut()
ctx, .block_manager
dummy_block_device.clone(), .insert_device(ctx, dummy_block_device.clone(),)
) .is_ok());
.is_ok());
assert_eq!(vm.device_manager().block_manager.info_list.len(), 1); assert_eq!(vm.device_manager().block_manager.info_list.len(), 1);
assert!(vm.device_manager().block_manager.has_root_block); assert!(vm.device_manager().block_manager.has_root_block);
@ -1027,12 +1026,16 @@ mod tests {
let mut vm = crate::vm::tests::create_vm_instance(); let mut vm = crate::vm::tests::create_vm_instance();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_1).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device_1)
.unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
assert!( assert!(vm
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_2) .device_manager_mut()
.is_err() .block_manager
); .insert_device(ctx, root_block_device_2)
.is_err());
} }
#[test] #[test]
@ -1112,13 +1115,22 @@ mod tests {
assert_eq!(vm.device_manager().block_manager.info_list.len(), 3); assert_eq!(vm.device_manager().block_manager.info_list.len(), 3);
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device)
.unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_2)
.unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_3).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_3)
.unwrap();
} }
#[test] #[test]
@ -1182,13 +1194,19 @@ mod tests {
let mut vm = crate::vm::tests::create_vm_instance(); let mut vm = crate::vm::tests::create_vm_instance();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone()) vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_2.clone())
.unwrap(); .unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_3.clone()) vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_3.clone())
.unwrap(); .unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device.clone()) vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device.clone())
.unwrap(); .unwrap();
assert!(vm.device_manager().block_manager.has_root_block_device(),); assert!(vm.device_manager().block_manager.has_root_block_device(),);
@ -1255,9 +1273,14 @@ mod tests {
// Add 2 block devices. // Add 2 block devices.
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device)
.unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone()) vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_2.clone())
.unwrap(); .unwrap();
// Get index zero. // Get index zero.
@ -1286,7 +1309,9 @@ mod tests {
// Update OK. // Update OK.
dummy_block_device_2.is_read_only = true; dummy_block_device_2.is_read_only = true;
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2.clone()) vm.device_manager_mut()
.block_manager
.insert_device(ctx, dummy_block_device_2.clone())
.unwrap(); .unwrap();
let index = vm let index = vm
@ -1306,21 +1331,21 @@ mod tests {
let dummy_path_3 = PathBuf::from(dummy_filename_3); let dummy_path_3 = PathBuf::from(dummy_filename_3);
dummy_block_device_2.path_on_host = dummy_path_3; dummy_block_device_2.path_on_host = dummy_path_3;
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
assert!(BlockDeviceMgr::insert_device( assert!(vm
vm.device_manager_mut(), .device_manager_mut()
ctx, .block_manager
dummy_block_device_2.clone(), .insert_device(ctx, dummy_block_device_2.clone(),)
) .is_err());
.is_err());
// Update with 2 root block devices. // Update with 2 root block devices.
dummy_block_device_2.path_on_host = dummy_path_2.clone(); dummy_block_device_2.path_on_host = dummy_path_2.clone();
dummy_block_device_2.is_root_device = true; dummy_block_device_2.is_root_device = true;
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
assert!( assert!(vm
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, dummy_block_device_2,) .device_manager_mut()
.is_err(), .block_manager
); .insert_device(ctx, dummy_block_device_2,)
.is_err(),);
// Switch roots and add a PARTUUID for the new one. // Switch roots and add a PARTUUID for the new one.
let root_block_device_old = BlockDeviceConfigInfo { let root_block_device_old = BlockDeviceConfigInfo {
@ -1354,9 +1379,15 @@ mod tests {
use_generic_irq: None, use_generic_irq: None,
}; };
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_old).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device_old)
.unwrap();
let ctx = DeviceOpContext::create_boot_ctx(&vm, None); let ctx = DeviceOpContext::create_boot_ctx(&vm, None);
BlockDeviceMgr::insert_device(vm.device_manager_mut(), ctx, root_block_device_new).unwrap(); vm.device_manager_mut()
.block_manager
.insert_device(ctx, root_block_device_new)
.unwrap();
assert!(vm.device_manager().block_manager.has_part_uuid_root); assert!(vm.device_manager().block_manager.has_part_uuid_root);
} }
} }