devices: vhost-user: properly return device failures

The `run_until` method of the executor returns a Result<Result<..>>,
where the outer result signals errors within the async executor, and the
inner result is the actual result of the passed future.

The current error handling completely ignores this inner error, making
"crosvm device" exit silently if we e.g. specify a socket that already
exists.

Fix this by explicitly returning outer errors if they exist, and
returning the inner anyhow::Result as-is so both levels of errors are
properly reported.

BUG=None
TEST=cargo build
TEST=console device properly reports and error if its socket file
already exists.

Change-Id: I7d091bd7b0d66a07c6f340ebf9e395d0dab2c212
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3439668
Reviewed-by: Keiichi Watanabe <keiichiw@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Anton Romanov <romanton@google.com>
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
This commit is contained in:
Alexandre Courbot 2022-02-04 17:50:24 +09:00 committed by Commit Bot
parent 73072d6d16
commit 1ee6783a57
7 changed files with 18 additions and 34 deletions

View file

@ -342,9 +342,6 @@ pub fn run_block_device(program_name: &str, args: &[&str]) -> anyhow::Result<()>
let block = BlockBackend::new(BLOCK_EXECUTOR.clone(), filename, fileopts)?;
let handler = DeviceRequestHandler::new(block);
if let Err(e) = ex.run_until(handler.run(opts.socket, &ex)) {
bail!("error occurred: {}", e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run(opts.socket, &ex))?
}

View file

@ -267,10 +267,8 @@ fn run_console(params: &SerialParameters, socket: &str) -> anyhow::Result<()> {
let _ = CONSOLE_EXECUTOR.set(ex.clone());
if let Err(e) = ex.run_until(handler.run(socket, &ex)) {
bail!(e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run(socket, &ex))?
}
#[derive(FromArgs)]

View file

@ -285,7 +285,6 @@ pub fn run_cras_snd_device(program_name: &str, args: &[&str]) -> anyhow::Result<
let _ = SND_EXECUTOR.set(ex.clone());
let _ = ex.run_until(handler.run_with_listener(listener, &ex))?;
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run_with_listener(listener, &ex))?
}

View file

@ -337,9 +337,6 @@ pub fn run_fs_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> {
let _ = FS_EXECUTOR.set(ex.clone());
if let Err(e) = ex.run_until(handler.run_with_listener(listener, &ex)) {
bail!(e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run_with_listener(listener, &ex))?
}

View file

@ -489,9 +489,6 @@ pub fn run_gpu_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> {
};
let handler = DeviceRequestHandler::new(backend);
if let Err(e) = ex.run_until(handler.run(socket, &ex)) {
error!("error occurred: {}", e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run(socket, &ex))?
}

View file

@ -413,20 +413,19 @@ pub fn run_net_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> {
let handler = DeviceRequestHandler::new(backend);
let ex = Executor::new().context("failed to create executor")?;
threads.push(thread::spawn(move || {
threads.push(thread::spawn(move || -> anyhow::Result<()> {
NET_EXECUTOR.with(|thread_ex| {
let _ = thread_ex.set(ex.clone());
});
if let Err(e) = ex.run_until(handler.run(&socket, &ex)) {
bail!("error occurred: {}", e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run(&socket, &ex))?
}));
}
for t in threads {
if let Err(e) = t.join() {
bail!("failed to join threads: {:?}", e);
match t.join() {
Ok(r) => r?,
Err(e) => bail!("thread panicked: {:?}", e),
}
}
Ok(())

View file

@ -361,9 +361,6 @@ pub fn run_wl_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> {
let handler =
DeviceRequestHandler::new(WlBackend::new(wayland_paths, vm_socket, resource_bridge));
if let Err(e) = ex.run_until(handler.run(socket, &ex)) {
bail!("error occurred: {}", e);
}
Ok(())
// run_until() returns an Result<Result<..>> which the ? operator lets us flatten.
ex.run_until(handler.run(socket, &ex))?
}