From 2e7c00be45382d3c52a142e1cf1d77931eed4b83 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 16 Sep 2025 19:58:19 +0200 Subject: [PATCH] vhost-device-sound: add --socket-fd argument This allows a service manager to start vhost-device-sound with an already listening socket. With this, the service manager can create the socket in advance of starting any services, so there's no race in between vhost-device-sound being started and being ready to accept connections. Signed-off-by: Alyssa Ross --- vhost-device-sound/CHANGELOG.md | 3 +++ vhost-device-sound/README.md | 4 ++++ vhost-device-sound/src/args.rs | 15 ++++++++++++--- vhost-device-sound/src/main.rs | 13 ++++++++++++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/vhost-device-sound/CHANGELOG.md b/vhost-device-sound/CHANGELOG.md index 5476568..431b2c4 100644 --- a/vhost-device-sound/CHANGELOG.md +++ b/vhost-device-sound/CHANGELOG.md @@ -3,6 +3,9 @@ ### Added +- [[#909]](https://github.com/rust-vmm/vhost-device/pull/909) + `vhost-device-sound` now supports a `--socket-fd` argument. + ### Changed - [[#907]](https://github.com/rust-vmm/vhost-device/pull/907) diff --git a/vhost-device-sound/README.md b/vhost-device-sound/README.md index 92d7aca..3f6d884 100644 --- a/vhost-device-sound/README.md +++ b/vhost-device-sound/README.md @@ -15,6 +15,10 @@ generated with help2man target/debug/vhost-device-sound |mandoc --socket vhost-user Unix domain socket path + --socket-fd + listening vhost-user Unix domain socket file descriptor + (e.g. from a service manager) + --backend audio backend to be used [possible values: null, pipewire, alsa, gstreamer] diff --git a/vhost-device-sound/src/args.rs b/vhost-device-sound/src/args.rs index 5cda63c..7a57bb2 100644 --- a/vhost-device-sound/src/args.rs +++ b/vhost-device-sound/src/args.rs @@ -1,16 +1,25 @@ // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause //! An arguments type for the binary interface of this library. +use std::os::fd::RawFd; use std::path::PathBuf; -use clap::{Parser, ValueEnum}; +use clap::{ArgGroup, Parser, ValueEnum}; #[derive(Parser, Debug)] -#[clap(version, about, long_about = None)] +#[clap( + version, + about, + long_about = None, + group(ArgGroup::new("socket group").required(true).args(&["socket", "socket_fd"])), +)] pub struct SoundArgs { /// vhost-user Unix domain socket path. #[clap(long)] - pub socket: PathBuf, + pub socket: Option, + /// vhost-user Unix domain socket FD. + #[clap(long)] + pub socket_fd: Option, /// audio backend to be used #[clap(long)] #[clap(value_enum)] diff --git a/vhost-device-sound/src/main.rs b/vhost-device-sound/src/main.rs index f11d558..3dcfd29 100644 --- a/vhost-device-sound/src/main.rs +++ b/vhost-device-sound/src/main.rs @@ -2,6 +2,9 @@ // Stefano Garzarella // SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause +use std::os::unix::net::UnixListener; +use std::os::unix::prelude::*; + use clap::Parser; use vhost::vhost_user::Listener; use vhost_device_sound::{args::SoundArgs, start_backend_server, SoundConfig}; @@ -11,7 +14,15 @@ fn main() { let args = SoundArgs::parse(); let config = SoundConfig::new(false, args.backend); - let mut listener = Listener::new(args.socket, true).unwrap(); + + let mut listener = if let Some(fd) = args.socket_fd { + // SAFETY: user has assured us this is safe. + unsafe { UnixListener::from_raw_fd(fd) }.into() + } else if let Some(path) = args.socket { + Listener::new(path, true).unwrap() + } else { + unreachable!() + }; loop { start_backend_server(&mut listener, config.clone());