mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-10 13:54:12 +00:00
agent: refine device.rs for better maintenance
1) pass reference instead of value when possible. 2) simplify code. 3) rename get_device_pci_address() as get_pci_device_address() to keep consistency get_pci_device_name(). 4) refine get_device_name() for maintenance. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
This commit is contained in:
parent
94311e4997
commit
000bb8592d
@ -3,21 +3,19 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
use rustjail::errors::*;
|
|
||||||
use std::fs;
|
|
||||||
// use std::io::Write;
|
|
||||||
use libc::{c_uint, major, minor};
|
use libc::{c_uint, major, minor};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::mpsc;
|
use std::sync::{mpsc, Arc, Mutex};
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use crate::mount::{DRIVERBLKTYPE, DRIVERMMIOBLKTYPE, DRIVERNVDIMMTYPE, DRIVERSCSITYPE};
|
use crate::mount::{DRIVERBLKTYPE, DRIVERMMIOBLKTYPE, DRIVERNVDIMMTYPE, DRIVERSCSITYPE};
|
||||||
use crate::sandbox::Sandbox;
|
use crate::sandbox::Sandbox;
|
||||||
use crate::{AGENT_CONFIG, GLOBAL_DEVICE_WATCHER};
|
use crate::{AGENT_CONFIG, GLOBAL_DEVICE_WATCHER};
|
||||||
use protocols::agent::Device;
|
use protocols::agent::Device;
|
||||||
use protocols::oci::Spec;
|
use protocols::oci::Spec;
|
||||||
|
use rustjail::errors::*;
|
||||||
|
|
||||||
// Convenience macro to obtain the scope logger
|
// Convenience macro to obtain the scope logger
|
||||||
macro_rules! sl {
|
macro_rules! sl {
|
||||||
@ -54,23 +52,18 @@ pub const SCSI_BLOCK_SUFFIX: &str = "block";
|
|||||||
const SCSI_DISK_SUFFIX: &str = "/device/block";
|
const SCSI_DISK_SUFFIX: &str = "/device/block";
|
||||||
const SCSI_HOST_PATH: &str = "/sys/class/scsi_host";
|
const SCSI_HOST_PATH: &str = "/sys/class/scsi_host";
|
||||||
|
|
||||||
// DeviceHandler is the type of callback to be defined to handle every
|
// DeviceHandler is the type of callback to be defined to handle every type of device driver.
|
||||||
// type of device driver.
|
type DeviceHandler = fn(&Device, &mut Spec, &Arc<Mutex<Sandbox>>) -> Result<()>;
|
||||||
type DeviceHandler = fn(&Device, &mut Spec, Arc<Mutex<Sandbox>>) -> Result<()>;
|
|
||||||
|
|
||||||
// DeviceHandlerList lists the supported drivers.
|
// DeviceHandlerList lists the supported drivers.
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref DEVICEHANDLERLIST: HashMap<&'static str, DeviceHandler> = {
|
static ref DEVICEHANDLERLIST: HashMap<&'static str, DeviceHandler> = {
|
||||||
let mut m = HashMap::new();
|
let mut m: HashMap<&'static str, DeviceHandler> = HashMap::new();
|
||||||
let blk: DeviceHandler = virtio_blk_device_handler;
|
m.insert(DRIVERBLKTYPE, virtio_blk_device_handler);
|
||||||
m.insert(DRIVERBLKTYPE, blk);
|
m.insert(DRIVERMMIOBLKTYPE, virtiommio_blk_device_handler);
|
||||||
let virtiommio: DeviceHandler = virtiommio_blk_device_handler;
|
m.insert(DRIVERNVDIMMTYPE, virtio_nvdimm_device_handler);
|
||||||
m.insert(DRIVERMMIOBLKTYPE, virtiommio);
|
m.insert(DRIVERSCSITYPE, virtio_scsi_device_handler);
|
||||||
let local: DeviceHandler = virtio_nvdimm_device_handler;
|
|
||||||
m.insert(DRIVERNVDIMMTYPE, local);
|
|
||||||
let scsi: DeviceHandler = virtio_scsi_device_handler;
|
|
||||||
m.insert(DRIVERSCSITYPE, scsi);
|
|
||||||
m
|
m
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -84,11 +77,11 @@ pub fn online_device(path: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_device_pci_address fetches the complete PCI address in sysfs, based on the PCI
|
// get_pci_device_address fetches the complete PCI address in sysfs, based on the PCI
|
||||||
// identifier provided. This should be in the format: "bridgeAddr/deviceAddr".
|
// identifier provided. This should be in the format: "bridgeAddr/deviceAddr".
|
||||||
// Here, bridgeAddr is the address at which the brige is attached on the root bus,
|
// Here, bridgeAddr is the address at which the bridge is attached on the root bus,
|
||||||
// while deviceAddr is the address at which the device is attached on the bridge.
|
// while deviceAddr is the address at which the device is attached on the bridge.
|
||||||
pub fn get_device_pci_address(pci_id: &str) -> Result<String> {
|
fn get_pci_device_address(pci_id: &str) -> Result<String> {
|
||||||
let tokens: Vec<&str> = pci_id.split("/").collect();
|
let tokens: Vec<&str> = pci_id.split("/").collect();
|
||||||
|
|
||||||
if tokens.len() != 2 {
|
if tokens.len() != 2 {
|
||||||
@ -139,78 +132,60 @@ pub fn get_device_pci_address(pci_id: &str) -> Result<String> {
|
|||||||
Ok(bridge_device_pci_addr)
|
Ok(bridge_device_pci_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device_name(sandbox: Arc<Mutex<Sandbox>>, dev_addr: &str) -> Result<String> {
|
fn get_device_name(sandbox: &Arc<Mutex<Sandbox>>, dev_addr: &str) -> Result<String> {
|
||||||
let mut dev_name: String = String::default();
|
// Keep the same lock order as uevent::handle_block_add_event(), otherwise it may cause deadlock.
|
||||||
|
let mut w = GLOBAL_DEVICE_WATCHER.lock().unwrap();
|
||||||
|
let sb = sandbox.lock().unwrap();
|
||||||
|
for (key, value) in sb.pci_device_map.iter() {
|
||||||
|
if key.contains(dev_addr) {
|
||||||
|
info!(sl!(), "Device {} found in pci device map", dev_addr);
|
||||||
|
return Ok(format!("{}/{}", SYSTEM_DEV_PATH, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drop(sb);
|
||||||
|
|
||||||
|
// If device is not found in the device map, hotplug event has not
|
||||||
|
// been received yet, create and add channel to the watchers map.
|
||||||
|
// The key of the watchers map is the device we are interested in.
|
||||||
|
// Note this is done inside the lock, not to miss any events from the
|
||||||
|
// global udev listener.
|
||||||
let (tx, rx) = mpsc::channel::<String>();
|
let (tx, rx) = mpsc::channel::<String>();
|
||||||
|
w.insert(dev_addr.to_string(), tx);
|
||||||
|
drop(w);
|
||||||
|
|
||||||
{
|
info!(sl!(), "Waiting on channel for device notification\n");
|
||||||
let watcher = GLOBAL_DEVICE_WATCHER.clone();
|
let hotplug_timeout = AGENT_CONFIG.read().unwrap().hotplug_timeout;
|
||||||
let mut w = watcher.lock().unwrap();
|
let dev_name = match rx.recv_timeout(hotplug_timeout) {
|
||||||
|
Ok(name) => name,
|
||||||
let s = sandbox.clone();
|
Err(_) => {
|
||||||
let sb = s.lock().unwrap();
|
GLOBAL_DEVICE_WATCHER.lock().unwrap().remove_entry(dev_addr);
|
||||||
|
return Err(ErrorKind::ErrorCode(format!(
|
||||||
for (key, value) in &(sb.pci_device_map) {
|
"Timeout reached after {:?} waiting for device {}",
|
||||||
if key.contains(dev_addr) {
|
hotplug_timeout, dev_addr
|
||||||
dev_name = value.to_string();
|
))
|
||||||
info!(sl!(), "Device {} found in pci device map", dev_addr);
|
.into());
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
// If device is not found in the device map, hotplug event has not
|
|
||||||
// been received yet, create and add channel to the watchers map.
|
|
||||||
// The key of the watchers map is the device we are interested in.
|
|
||||||
// Note this is done inside the lock, not to miss any events from the
|
|
||||||
// global udev listener.
|
|
||||||
if dev_name == "" {
|
|
||||||
w.insert(dev_addr.to_string(), tx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if dev_name == "" {
|
|
||||||
info!(sl!(), "Waiting on channel for device notification\n");
|
|
||||||
|
|
||||||
let agent_config = AGENT_CONFIG.clone();
|
|
||||||
let config = agent_config.read().unwrap();
|
|
||||||
|
|
||||||
match rx.recv_timeout(config.hotplug_timeout) {
|
|
||||||
Ok(name) => dev_name = name,
|
|
||||||
Err(_) => {
|
|
||||||
let watcher = GLOBAL_DEVICE_WATCHER.clone();
|
|
||||||
let mut w = watcher.lock().unwrap();
|
|
||||||
w.remove_entry(dev_addr);
|
|
||||||
|
|
||||||
return Err(ErrorKind::ErrorCode(format!(
|
|
||||||
"Timeout reached after {:?} waiting for device {}",
|
|
||||||
config.hotplug_timeout, dev_addr
|
|
||||||
))
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(format!("{}/{}", SYSTEM_DEV_PATH, &dev_name))
|
Ok(format!("{}/{}", SYSTEM_DEV_PATH, &dev_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scsi_device_name(sandbox: Arc<Mutex<Sandbox>>, scsi_addr: &str) -> Result<String> {
|
pub fn get_scsi_device_name(sandbox: &Arc<Mutex<Sandbox>>, scsi_addr: &str) -> Result<String> {
|
||||||
scan_scsi_bus(scsi_addr)?;
|
|
||||||
|
|
||||||
let dev_sub_path = format!("{}{}/{}", SCSI_HOST_CHANNEL, scsi_addr, SCSI_BLOCK_SUFFIX);
|
let dev_sub_path = format!("{}{}/{}", SCSI_HOST_CHANNEL, scsi_addr, SCSI_BLOCK_SUFFIX);
|
||||||
|
|
||||||
get_device_name(sandbox, dev_sub_path.as_str())
|
scan_scsi_bus(scsi_addr)?;
|
||||||
|
get_device_name(sandbox, &dev_sub_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pci_device_name(sandbox: Arc<Mutex<Sandbox>>, pci_id: &str) -> Result<String> {
|
pub fn get_pci_device_name(sandbox: &Arc<Mutex<Sandbox>>, pci_id: &str) -> Result<String> {
|
||||||
let pci_addr = get_device_pci_address(pci_id)?;
|
let pci_addr = get_pci_device_address(pci_id)?;
|
||||||
|
|
||||||
rescan_pci_bus()?;
|
rescan_pci_bus()?;
|
||||||
|
get_device_name(sandbox, &pci_addr)
|
||||||
get_device_name(sandbox, pci_addr.as_str())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scan_scsi_bus scans SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
/// Scan SCSI bus for the given SCSI address(SCSI-Id and LUN)
|
||||||
pub fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
||||||
let tokens: Vec<&str> = scsi_addr.split(":").collect();
|
let tokens: Vec<&str> = scsi_addr.split(":").collect();
|
||||||
if tokens.len() != 2 {
|
if tokens.len() != 2 {
|
||||||
return Err(ErrorKind::Msg(format!(
|
return Err(ErrorKind::Msg(format!(
|
||||||
@ -220,14 +195,12 @@ pub fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
|||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan scsi host passing in the channel, SCSI id and LUN. Channel
|
// Scan scsi host passing in the channel, SCSI id and LUN.
|
||||||
// is always 0 because we have only one SCSI controller.
|
// Channel is always 0 because we have only one SCSI controller.
|
||||||
let scan_data = format!("0 {} {}", tokens[0], tokens[1]);
|
let scan_data = format!("0 {} {}", tokens[0], tokens[1]);
|
||||||
|
|
||||||
for entry in fs::read_dir(SCSI_HOST_PATH)? {
|
for entry in fs::read_dir(SCSI_HOST_PATH)? {
|
||||||
let entry = entry?;
|
let host = entry?.file_name();
|
||||||
|
|
||||||
let host = entry.file_name();
|
|
||||||
let scan_path = format!("{}/{}/{}", SCSI_HOST_PATH, host.to_str().unwrap(), "scan");
|
let scan_path = format!("{}/{}/{}", SCSI_HOST_PATH, host.to_str().unwrap(), "scan");
|
||||||
|
|
||||||
fs::write(scan_path, &scan_data)?;
|
fs::write(scan_path, &scan_data)?;
|
||||||
@ -243,9 +216,6 @@ pub fn scan_scsi_bus(scsi_addr: &str) -> Result<()> {
|
|||||||
// This is needed to update information about minor/major numbers that cannot
|
// This is needed to update information about minor/major numbers that cannot
|
||||||
// be predicted from the caller.
|
// be predicted from the caller.
|
||||||
fn update_spec_device_list(device: &Device, spec: &mut Spec) -> Result<()> {
|
fn update_spec_device_list(device: &Device, spec: &mut Spec) -> Result<()> {
|
||||||
// If no container_path is provided, we won't be able to match and
|
|
||||||
// update the device in the OCI spec device list. This is an error.
|
|
||||||
|
|
||||||
let major_id: c_uint;
|
let major_id: c_uint;
|
||||||
let minor_id: c_uint;
|
let minor_id: c_uint;
|
||||||
|
|
||||||
@ -253,7 +223,7 @@ fn update_spec_device_list(device: &Device, spec: &mut Spec) -> Result<()> {
|
|||||||
// update the device in the OCI spec device list. This is an error.
|
// update the device in the OCI spec device list. This is an error.
|
||||||
if device.container_path == "" {
|
if device.container_path == "" {
|
||||||
return Err(ErrorKind::Msg(format!(
|
return Err(ErrorKind::Msg(format!(
|
||||||
"container_path cannot empty for device {:?}",
|
"container_path cannot empty for device {:?}",
|
||||||
device
|
device
|
||||||
))
|
))
|
||||||
.into());
|
.into());
|
||||||
@ -304,9 +274,7 @@ fn update_spec_device_list(device: &Device, spec: &mut Spec) -> Result<()> {
|
|||||||
|
|
||||||
// Resources must be updated since they are used to identify the
|
// Resources must be updated since they are used to identify the
|
||||||
// device in the devices cgroup.
|
// device in the devices cgroup.
|
||||||
let resource = linux.Resources.as_mut();
|
if let Some(res) = linux.Resources.as_mut() {
|
||||||
if resource.is_some() {
|
|
||||||
let res = resource.unwrap();
|
|
||||||
let ds = res.Devices.as_mut_slice();
|
let ds = res.Devices.as_mut_slice();
|
||||||
for d in ds.iter_mut() {
|
for d in ds.iter_mut() {
|
||||||
if d.Major == host_major && d.Minor == host_minor {
|
if d.Major == host_major && d.Minor == host_minor {
|
||||||
@ -331,10 +299,10 @@ fn update_spec_device_list(device: &Device, spec: &mut Spec) -> Result<()> {
|
|||||||
fn virtiommio_blk_device_handler(
|
fn virtiommio_blk_device_handler(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
spec: &mut Spec,
|
spec: &mut Spec,
|
||||||
_sandbox: Arc<Mutex<Sandbox>>,
|
_sandbox: &Arc<Mutex<Sandbox>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if device.vm_path == "" {
|
if device.vm_path == "" {
|
||||||
return Err(ErrorKind::Msg("Invalid path for virtiommioblkdevice".to_string()).into());
|
return Err(ErrorKind::Msg("Invalid path for virtio mmio blk device".to_string()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
update_spec_device_list(device, spec)
|
update_spec_device_list(device, spec)
|
||||||
@ -346,13 +314,10 @@ fn virtiommio_blk_device_handler(
|
|||||||
fn virtio_blk_device_handler(
|
fn virtio_blk_device_handler(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
spec: &mut Spec,
|
spec: &mut Spec,
|
||||||
sandbox: Arc<Mutex<Sandbox>>,
|
sandbox: &Arc<Mutex<Sandbox>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let dev_path = get_pci_device_name(sandbox, device.id.as_str())?;
|
|
||||||
|
|
||||||
let mut dev = device.clone();
|
let mut dev = device.clone();
|
||||||
dev.vm_path = dev_path;
|
dev.vm_path = get_pci_device_name(sandbox, &device.id)?;
|
||||||
|
|
||||||
update_spec_device_list(&dev, spec)
|
update_spec_device_list(&dev, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,39 +325,39 @@ fn virtio_blk_device_handler(
|
|||||||
fn virtio_scsi_device_handler(
|
fn virtio_scsi_device_handler(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
spec: &mut Spec,
|
spec: &mut Spec,
|
||||||
sandbox: Arc<Mutex<Sandbox>>,
|
sandbox: &Arc<Mutex<Sandbox>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let dev_path = get_scsi_device_name(sandbox, device.id.as_str())?;
|
|
||||||
|
|
||||||
let mut dev = device.clone();
|
let mut dev = device.clone();
|
||||||
dev.vm_path = dev_path;
|
dev.vm_path = get_scsi_device_name(sandbox, &device.id)?;
|
||||||
|
|
||||||
update_spec_device_list(&dev, spec)
|
update_spec_device_list(&dev, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn virtio_nvdimm_device_handler(
|
fn virtio_nvdimm_device_handler(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
spec: &mut Spec,
|
spec: &mut Spec,
|
||||||
_sandbox: Arc<Mutex<Sandbox>>,
|
_sandbox: &Arc<Mutex<Sandbox>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if device.vm_path == "" {
|
||||||
|
return Err(ErrorKind::Msg("Invalid path for nvdimm device".to_string()).into());
|
||||||
|
}
|
||||||
|
|
||||||
update_spec_device_list(device, spec)
|
update_spec_device_list(device, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_devices(
|
pub fn add_devices(
|
||||||
devices: Vec<Device>,
|
devices: &[Device],
|
||||||
spec: &mut Spec,
|
spec: &mut Spec,
|
||||||
sandbox: Arc<Mutex<Sandbox>>,
|
sandbox: &Arc<Mutex<Sandbox>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for device in devices.iter() {
|
for device in devices.iter() {
|
||||||
add_device(device, spec, sandbox.clone())?;
|
add_device(device, spec, sandbox)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_device(device: &Device, spec: &mut Spec, sandbox: Arc<Mutex<Sandbox>>) -> Result<()> {
|
fn add_device(device: &Device, spec: &mut Spec, sandbox: &Arc<Mutex<Sandbox>>) -> Result<()> {
|
||||||
// log before validation to help with debugging gRPC protocol
|
// log before validation to help with debugging gRPC protocol version differences.
|
||||||
// version differences.
|
|
||||||
info!(sl!(), "device-id: {}, device-type: {}, device-vm-path: {}, device-container-path: {}, device-options: {:?}",
|
info!(sl!(), "device-id: {}, device-type: {}, device-vm-path: {}, device-container-path: {}, device-options: {:?}",
|
||||||
device.id, device.field_type, device.vm_path, device.container_path, device.options);
|
device.id, device.field_type, device.vm_path, device.container_path, device.options);
|
||||||
|
|
||||||
@ -412,12 +377,8 @@ fn add_device(device: &Device, spec: &mut Spec, sandbox: Arc<Mutex<Sandbox>>) ->
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dev_handler = match DEVICEHANDLERLIST.get(device.field_type.as_str()) {
|
match DEVICEHANDLERLIST.get(device.field_type.as_str()) {
|
||||||
None => {
|
None => Err(ErrorKind::Msg(format!("Unknown device type {}", device.field_type)).into()),
|
||||||
return Err(ErrorKind::Msg(format!("Unknown device type {}", device.field_type)).into())
|
Some(dev_handler) => dev_handler(device, spec, sandbox),
|
||||||
}
|
}
|
||||||
Some(t) => t,
|
|
||||||
};
|
|
||||||
|
|
||||||
dev_handler(device, spec, sandbox)
|
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl agentService {
|
|||||||
// updates the devices listed in the OCI spec, so that they actually
|
// updates the devices listed in the OCI spec, so that they actually
|
||||||
// match real devices inside the VM. This step is necessary since we
|
// match real devices inside the VM. This step is necessary since we
|
||||||
// cannot predict everything from the caller.
|
// cannot predict everything from the caller.
|
||||||
add_devices(req.devices.to_vec(), oci, self.sandbox.clone())?;
|
add_devices(&req.devices.to_vec(), oci, &self.sandbox)?;
|
||||||
|
|
||||||
// Both rootfs and volumes (invoked with --volume for instance) will
|
// Both rootfs and volumes (invoked with --volume for instance) will
|
||||||
// be processed the same way. The idea is to always mount any provided
|
// be processed the same way. The idea is to always mount any provided
|
||||||
|
@ -341,7 +341,7 @@ fn virtio_blk_storage_handler(
|
|||||||
return Err(ErrorKind::ErrorCode(format!("Invalid device {}", &storage.source)).into());
|
return Err(ErrorKind::ErrorCode(format!("Invalid device {}", &storage.source)).into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let dev_path = get_pci_device_name(sandbox, &storage.source)?;
|
let dev_path = get_pci_device_name(&sandbox, &storage.source)?;
|
||||||
storage.source = dev_path;
|
storage.source = dev_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ fn virtio_scsi_storage_handler(
|
|||||||
let mut storage = storage.clone();
|
let mut storage = storage.clone();
|
||||||
|
|
||||||
// Retrieve the device path from SCSI address.
|
// Retrieve the device path from SCSI address.
|
||||||
let dev_path = get_scsi_device_name(sandbox, &storage.source)?;
|
let dev_path = get_scsi_device_name(&sandbox, &storage.source)?;
|
||||||
storage.source = dev_path;
|
storage.source = dev_path;
|
||||||
|
|
||||||
common_storage_handler(logger, &storage)
|
common_storage_handler(logger, &storage)
|
||||||
|
Loading…
Reference in New Issue
Block a user