Add hosted bus module based on busd

Currently depends on WIP changes to busd to allow in-process clients
This commit is contained in:
Val Packett 2025-07-11 01:01:39 -03:00
parent 14ce212e81
commit 627237bdda
7 changed files with 152 additions and 167 deletions

190
Cargo.lock generated
View file

@ -17,15 +17,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.19"
@ -146,21 +137,20 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "busd"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2f217adcc5254e2eb9a4f3cecffb2670ca4ae8cc4abe33c10ae26d00316d4bc"
source = "git+https://github.com/valpackett/busd?branch=val%2Fmsksqvsqqrxm#7b57cb53731ee4610e407f8c560316f22b01be22"
dependencies = [
"anyhow",
"clap",
"enumflags2",
"event-listener",
"fastrand",
"futures-util",
"hex",
"nix 0.29.0",
"rand 0.8.5",
"nix 0.30.1",
"quick-xml",
"serde",
"serde_repr",
"tokio",
"tracing",
"tracing-subscriber",
"xdg-home",
"zbus",
]
@ -185,9 +175,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "clap"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [
"clap_builder",
"clap_derive",
@ -195,9 +185,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [
"anstream",
"anstyle",
@ -207,9 +197,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
"heck",
"proc-macro2",
@ -426,17 +416,6 @@ dependencies = [
"slab",
]
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.3"
@ -540,15 +519,6 @@ version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "memchr"
version = "2.7.5"
@ -725,6 +695,16 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "quote"
version = "1.0.40"
@ -740,35 +720,14 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
"rand_chacha",
"rand_core",
]
[[package]]
@ -778,16 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.16",
"rand_core",
]
[[package]]
@ -796,7 +746,7 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.3",
"getrandom",
]
[[package]]
@ -808,50 +758,6 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.9",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-demangle"
version = "0.1.25"
@ -988,12 +894,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.11.1"
@ -1018,7 +918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.3",
"getrandom",
"once_cell",
"rustix",
"windows-sys 0.59.0",
@ -1035,9 +935,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.46.0"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
"backtrace",
"bytes",
@ -1155,14 +1055,10 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
@ -1428,9 +1324,8 @@ dependencies = [
[[package]]
name = "zbus"
version = "5.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68"
version = "5.8.0"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"async-broadcast",
"async-recursion",
@ -1442,7 +1337,7 @@ dependencies = [
"hex",
"nix 0.30.1",
"ordered-stream",
"rand 0.9.1",
"rand",
"serde",
"serde_repr",
"tokio",
@ -1458,9 +1353,8 @@ dependencies = [
[[package]]
name = "zbus_macros"
version = "5.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a"
version = "5.8.0"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@ -1474,11 +1368,9 @@ dependencies = [
[[package]]
name = "zbus_names"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"serde",
"static_assertions",
"winnow",
"zvariant",
]
@ -1505,9 +1397,8 @@ dependencies = [
[[package]]
name = "zvariant"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1"
version = "5.6.0"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"endi",
"enumflags2",
@ -1519,9 +1410,8 @@ dependencies = [
[[package]]
name = "zvariant_derive"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580"
version = "5.6.0"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@ -1533,13 +1423,11 @@ dependencies = [
[[package]]
name = "zvariant_utils"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34"
source = "git+https://github.com/dbus2/zbus#b7c16006f3b79090c86f04b7934611e7796a6af1"
dependencies = [
"proc-macro2",
"quote",
"serde",
"static_assertions",
"syn",
"winnow",
]

View file

@ -8,3 +8,7 @@ members = [
[workspace.dependencies]
sidebus-common = { path = "sidebus-common" }
busd = { git = "https://github.com/valpackett/busd", branch = "val/msksqvsqqrxm", default-features = false }
zbus = { git = "https://github.com/dbus2/zbus", default-features = false, features = ["tokio", "tokio-vsock", "bus-impl", "p2p"] }
# zbus git to match busd git

View file

@ -12,4 +12,4 @@ tokio-stream = "0.1.17"
tokio-vsock = "0.7.1"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
zbus = { version = "5.7.1", default-features = false, features = ["tokio", "tokio-vsock", "bus-impl", "p2p"] }
zbus = { workspace = true }

View file

@ -5,11 +5,11 @@ edition = "2024"
[dependencies]
sidebus-common = { workspace = true }
busd = "0.4.0"
busd = { workspace = true }
clap = { version = "4.5.40", features = ["derive"] }
eyre = "0.6.12"
tokio = { version = "1.46.0", features = ["full"] }
tokio-vsock = "0.7.1"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
zbus = { version = "5.7.1", default-features = false, features = ["tokio", "tokio-vsock", "bus-impl", "p2p"] }
zbus = { workspace = true }

71
sidebus-broker/src/bus.rs Normal file
View file

@ -0,0 +1,71 @@
use std::sync::Arc;
use tracing::trace;
pub struct HostedBus {
peers: Arc<busd::peers::Peers>,
guid: zbus::OwnedGuid,
next_id: usize,
_self_conn: zbus::Connection,
}
impl HostedBus {
pub async fn new() -> eyre::Result<Self> {
let guid: zbus::OwnedGuid = zbus::Guid::generate().into();
let peers = busd::peers::Peers::new();
let dbus = busd::fdo::DBus::new(peers.clone(), guid.clone());
let monitoring = busd::fdo::Monitoring::new(peers.clone());
// Create a peer for ourselves.
trace!("Creating self-dial connection.");
let (client_socket, peer_socket) = zbus::connection::socket::Channel::pair();
let service_conn =
zbus::connection::Builder::authenticated_socket(client_socket, guid.clone())?
.p2p()
.unique_name(busd::fdo::BUS_NAME)?
.name(busd::fdo::BUS_NAME)?
.serve_at(busd::fdo::DBus::PATH, dbus)?
.serve_at(busd::fdo::Monitoring::PATH, monitoring)?
.build()
.await?;
let peer_conn = zbus::connection::Builder::authenticated_socket(peer_socket, guid.clone())?
.p2p()
.build()
.await?;
peers.add_us(peer_conn).await;
trace!("Self-dial connection created.");
Ok(HostedBus {
peers,
guid,
next_id: 0,
_self_conn: service_conn,
})
}
pub fn server_guid(&self) -> &zbus::Guid<'_> {
self.guid.inner()
}
pub async fn connect_channel(&mut self) -> eyre::Result<zbus::Connection> {
let id = self.next_id();
self.peers
.add_channel(&self.guid, id)
.await
.map_err(|err| eyre::eyre!(Box::new(err))) // https://github.com/eyre-rs/eyre/issues/31 XXX: busd should not use anyhow!
}
pub async fn connect_unix(&mut self, socket: tokio::net::UnixStream) -> eyre::Result<()> {
let id = self.next_id();
self.peers
.add(&self.guid, id, socket.into(), zbus::AuthMechanism::External)
.await
.map_err(|err| eyre::eyre!(Box::new(err)))
}
fn next_id(&mut self) -> usize {
self.next_id += 1;
self.next_id
}
}

View file

@ -1,7 +1,19 @@
mod bus;
mod vsock;
use clap::Parser;
use tracing::info;
use std::sync::Arc;
use tokio::sync::Mutex;
// https://github.com/rust-lang/rfcs/issues/2407#issuecomment-385291238
macro_rules! enclose {
( ($( $x:ident ),*) $y:expr ) => {
{
$(let $x = $x.clone();)*
$y
}
};
}
#[derive(Parser)]
#[command(version, about, long_about = None)]
@ -13,19 +25,29 @@ async fn main() -> eyre::Result<()> {
let _cli = BrokerCli::parse();
let vm_bus = bus::HostedBus::new().await?;
let vm_bus_guid: zbus::OwnedGuid = vm_bus.server_guid().to_owned().into();
let vm_bus = Arc::new(Mutex::new(vm_bus));
// Direct access for the host (just trying things out)
let unix_listener = tokio::net::UnixListener::bind("vmbus.sock")?;
tokio::spawn(enclose! { (vm_bus) async move {
while let Ok((socket, _remote_addr)) = unix_listener.accept().await {
vm_bus.lock().await.connect_unix(socket).await.unwrap()
}
} });
// NOTE: Every individual D-Bus client inside of the VM is a new client here!
vsock::ListenerBuilder::new(vsock::VsockAddr::new(vsock::VMADDR_CID_HOST, 4269))
.with_label("VM Bus")
.listen(async |client| {
let session_bus = zbus::connection::Builder::session()
.unwrap()
.p2p() /* i.e. "raw connection, don't send Hello" */
.build()
.await
.unwrap();
info!(guid = %session_bus.server_guid(), "connected to session bus");
let client_conn = client.build(session_bus.server_guid().into()).await?;
sidebus_common::raw::splice_conns(client_conn, session_bus).await;
Ok(())
.listen(move |client| {
enclose! { (vm_bus, vm_bus_guid) async move {
// TODO: Not necessary to go through the channel, add vsock support to the Peer too
let client_conn = client.build((&vm_bus_guid).into()).await?;
let vmbus_conn = vm_bus.lock().await.connect_channel().await?;
sidebus_common::raw::splice_conns(client_conn, vmbus_conn).await;
Ok(())
} }
})
.await?;

View file

@ -7,4 +7,4 @@ edition = "2024"
tracing = "0.1.41"
tokio = { version = "1.46.0", features = ["macros"] }
tokio-stream = "0.1.17"
zbus = { version = "5.7.1", default-features = false, features = ["tokio", "tokio-vsock", "bus-impl", "p2p"] }
zbus = { workspace = true }