mirror of
https://github.com/rust-vmm/vhost-device.git
synced 2026-01-08 12:38:21 +00:00
gpio: re-arrange start_backend to handle config errors
The compiler warns with the move that:
error: variants `CouldNotOpenDevice`, `CouldNotCreateGpioController`, `CouldNotCreateBackend`, and `CouldNotCreateDaemon` are never constructed
--> crates/vhost-device-gpio/src/backend.rs:43:5
|
31 | pub(crate) enum Error {
| ----- variants in this enum
...
43 | CouldNotOpenDevice(crate::gpio::Error),
| ^^^^^^^^^^^^^^^^^^
44 | #[error("Could not create gpio controller: {0}")]
45 | CouldNotCreateGpioController(crate::gpio::Error),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46 | #[error("Could not create gpio backend: {0}")]
47 | CouldNotCreateBackend(crate::vhu_gpio::Error),
| ^^^^^^^^^^^^^^^^^^^^^
48 | #[error("Could not create daemon: {0}")]
49 | CouldNotCreateDaemon(vhost_user_backend::Error),
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `Error` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
= note: `-D dead-code` implied by `-D warnings`
error: could not compile `vhost-device-gpio` (bin "vhost-device-gpio") due to previous error
Because we never really care about failure within the spawn loop.
Handle this by ensuring errors propagate back to the caller.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
parent
e4aefda817
commit
026cf0e532
@ -174,9 +174,11 @@ impl TryFrom<GpioArgs> for GpioConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
fn start_device_backend<D: GpioDevice>(device: D, socket: String) {
|
||||
let controller = GpioController::<D>::new(device).unwrap();
|
||||
let backend = Arc::new(RwLock::new(VhostUserGpioBackend::new(controller).unwrap()));
|
||||
fn start_device_backend<D: GpioDevice>(device: D, socket: String) -> Result<()> {
|
||||
let controller = GpioController::new(device).map_err(Error::CouldNotCreateGpioController)?;
|
||||
let backend = Arc::new(RwLock::new(
|
||||
VhostUserGpioBackend::new(controller).map_err(Error::CouldNotCreateBackend)?,
|
||||
));
|
||||
let listener = Listener::new(socket, true).unwrap();
|
||||
|
||||
let mut daemon = VhostUserDaemon::new(
|
||||
@ -184,7 +186,7 @@ fn start_device_backend<D: GpioDevice>(device: D, socket: String) {
|
||||
backend.clone(),
|
||||
GuestMemoryAtomic::new(GuestMemoryMmap::new()),
|
||||
)
|
||||
.unwrap();
|
||||
.map_err(Error::CouldNotCreateDaemon)?;
|
||||
|
||||
daemon.start(listener).unwrap();
|
||||
|
||||
@ -201,6 +203,7 @@ fn start_device_backend<D: GpioDevice>(device: D, socket: String) {
|
||||
}
|
||||
// No matter the result, we need to shut down the worker thread.
|
||||
backend.read().unwrap().exit_event.write(1).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_backend(args: GpioArgs) -> Result<()> {
|
||||
@ -212,23 +215,23 @@ fn start_backend(args: GpioArgs) -> Result<()> {
|
||||
let cfg = config.devices.inner[i];
|
||||
|
||||
let handle: JoinHandle<Result<()>> = spawn(move || loop {
|
||||
// A separate thread is spawned for each socket and can connect to a separate guest.
|
||||
// These are run in an infinite loop to not require the daemon to be restarted once a
|
||||
// guest exits.
|
||||
// A separate thread is spawned for each socket and can
|
||||
// connect to a separate guest. These are run in an
|
||||
// infinite loop to not require the daemon to be restarted
|
||||
// once a guest exits.
|
||||
//
|
||||
// There isn't much value in complicating code here to return an error from the
|
||||
// threads, and so the code uses unwrap() instead. The panic on a thread won't cause
|
||||
// trouble to other threads/guests or the main() function and should be safe for the
|
||||
// daemon.
|
||||
// However if we fail to spawn (due to bad config or
|
||||
// other reason) we will bail out of the spawning and
|
||||
// propagate the error back to gpio_init().
|
||||
match cfg {
|
||||
GpioDeviceType::PhysicalDevice { id } => {
|
||||
let controller = PhysDevice::open(id).unwrap();
|
||||
start_device_backend(controller, socket.clone());
|
||||
let controller = PhysDevice::open(id).map_err(Error::CouldNotOpenDevice)?;
|
||||
start_device_backend(controller, socket.clone())?;
|
||||
}
|
||||
#[cfg(any(test, feature = "mock_gpio"))]
|
||||
GpioDeviceType::SimulatedDevice { num_gpios } => {
|
||||
let controller = MockGpioDevice::open(num_gpios).unwrap();
|
||||
start_device_backend(controller, socket.clone());
|
||||
let controller = MockGpioDevice::open(num_gpios).unwrap(); // cannot fail
|
||||
start_device_backend(controller, socket.clone())?;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user