Switch over to a reverse connection scheme (bridge to a guest bus)
This commit is contained in:
parent
ea34b7b08c
commit
52c3ea7cd3
5 changed files with 53 additions and 82 deletions
|
|
@ -5,7 +5,7 @@ mod vsock;
|
|||
use bus::SharedHostedBus;
|
||||
use clap::Parser;
|
||||
use futures::{TryFutureExt, stream::FuturesUnordered};
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::{path::PathBuf, sync::Arc, time::Duration};
|
||||
use tokio::{net::UnixListener, process::Command, sync::Mutex};
|
||||
use tokio_stream::StreamExt as _;
|
||||
use tracing::{Instrument, debug, error, info_span};
|
||||
|
|
@ -71,7 +71,6 @@ async fn main() -> eyre::Result<()> {
|
|||
|
||||
let cli = BrokerCli::parse();
|
||||
|
||||
let (vm_bus, vm_bus_guid, _) = new_hosted_bus().await?;
|
||||
let (priv_bus, _, mut priv_lst) = new_hosted_bus().await?;
|
||||
|
||||
let mut server_tasks = tokio::task::JoinSet::new();
|
||||
|
|
@ -88,12 +87,6 @@ async fn main() -> eyre::Result<()> {
|
|||
.clone()
|
||||
.run_unix_listener(priv_dbg_listener, zbus::AuthMechanism::External),
|
||||
);
|
||||
let vm_dbg_listener = UnixListener::bind(dir_path.join("vm.sock"))?;
|
||||
server_tasks.spawn(
|
||||
vm_bus
|
||||
.clone()
|
||||
.run_unix_listener(vm_dbg_listener, zbus::AuthMechanism::External),
|
||||
);
|
||||
// TODO: unlink sockets on exit
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +141,6 @@ async fn main() -> eyre::Result<()> {
|
|||
.spawn()?,
|
||||
);
|
||||
|
||||
let vm_bus_conn = vm_bus.lock().await.connect_channel(false).await?;
|
||||
let priv_bus_conn = priv_bus.lock().await.connect_channel(false).await?;
|
||||
let host_session_conn = zbus::connection::Builder::session()?.build().await?;
|
||||
let file_chooser_imp = portal::file_chooser::FileChooser::new(
|
||||
|
|
@ -157,47 +149,49 @@ async fn main() -> eyre::Result<()> {
|
|||
cli.guest_mountpoint,
|
||||
)
|
||||
.await?;
|
||||
vm_bus_conn
|
||||
.request_name("org.freedesktop.portal.Desktop")
|
||||
.await?;
|
||||
let true = vm_bus_conn
|
||||
.object_server()
|
||||
.at("/org/freedesktop/portal/desktop", file_chooser_imp)
|
||||
.await?
|
||||
else {
|
||||
unreachable!("our own fresh bus can't have interfaces already provided");
|
||||
};
|
||||
|
||||
// NOTE: Every individual D-Bus client inside of the VM is a new client on the VM bus listeners!
|
||||
async fn on_vm_bus_connected(
|
||||
vm_bus_conn: zbus::Connection,
|
||||
file_chooser: portal::file_chooser::FileChooser,
|
||||
) -> Result<(), eyre::Report> {
|
||||
vm_bus_conn
|
||||
.request_name("org.freedesktop.portal.Desktop")
|
||||
.await?;
|
||||
if !vm_bus_conn
|
||||
.object_server()
|
||||
.at("/org/freedesktop/portal/desktop", file_chooser)
|
||||
.await?
|
||||
{
|
||||
error!("org.freedesktop.portal.Desktop already provided");
|
||||
};
|
||||
// XXX: no method for "wait until the conn dies"?
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_millis(5000)).await;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(path) = cli.unix_path {
|
||||
// XXX: going through the channel just to strip fds
|
||||
let vm_unix_listener = UnixListener::bind(path)?;
|
||||
server_tasks.spawn(enclose! { (vm_bus, vm_bus_guid) async move {
|
||||
server_tasks.spawn(enclose!((file_chooser_imp) async move {
|
||||
while let Ok((socket, remote_addr)) = vm_unix_listener.accept().await {
|
||||
let f = enclose! { (vm_bus, vm_bus_guid) async move {
|
||||
let f = enclose!((file_chooser_imp) async move {
|
||||
let client_conn = zbus::connection::Builder::unix_stream(socket)
|
||||
.server(&vm_bus_guid)
|
||||
.unwrap()
|
||||
.p2p()
|
||||
.auth_mechanism(zbus::AuthMechanism::Anonymous)
|
||||
.build()
|
||||
.await?;
|
||||
let vmbus_conn = vm_bus.lock().await.connect_channel(true).await?;
|
||||
sidebus_common::raw::splice_conns(client_conn, vmbus_conn).await;
|
||||
Ok::<(), eyre::Report>(())
|
||||
} };
|
||||
on_vm_bus_connected(client_conn, file_chooser_imp).await
|
||||
});
|
||||
tokio::spawn(
|
||||
async {
|
||||
match f.await {
|
||||
Ok(()) => debug!("done with client"),
|
||||
Err(err) => error!(%err, "error dealing with client"),
|
||||
Ok(()) => debug!("done with server"),
|
||||
Err(err) => error!(%err, "error dealing with server"),
|
||||
}
|
||||
}
|
||||
.instrument(info_span!("serve", ?remote_addr)),
|
||||
);
|
||||
}
|
||||
} });
|
||||
}));
|
||||
}
|
||||
|
||||
if let Some(port) = cli.vsock_port {
|
||||
|
|
@ -206,13 +200,11 @@ async fn main() -> eyre::Result<()> {
|
|||
vsock::ListenerBuilder::new(vsock::VsockAddr::new(vsock::VMADDR_CID_HOST, port))
|
||||
.with_label("VM Bus")
|
||||
.listen(move |client| {
|
||||
enclose! { (vm_bus, vm_bus_guid) async move {
|
||||
enclose!((file_chooser_imp) 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(true).await?;
|
||||
sidebus_common::raw::splice_conns(client_conn, vmbus_conn).await;
|
||||
Ok(())
|
||||
} }
|
||||
let client_conn = client.build().await?;
|
||||
on_vm_bus_connected(client_conn, file_chooser_imp).await
|
||||
})
|
||||
})
|
||||
.map_ok_or_else(
|
||||
|e| {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use zbus::{Connection, ObjectServer, fdo::Result, zvariant};
|
|||
use super::documents::DocumentsProxy;
|
||||
use super::request::{RESPONSE_SUCCESS, ReqHandler, ResultTransformer};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FileChooser {
|
||||
host: FileChooserProxy<'static>,
|
||||
docs: DocumentsProxy<'static>,
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ impl ConnectionBuilder {
|
|||
&self.remote_addr
|
||||
}
|
||||
|
||||
pub async fn build<'a>(self, guid: zbus::Guid<'a>) -> eyre::Result<zbus::Connection> {
|
||||
pub async fn build<'a>(self) -> eyre::Result<zbus::Connection> {
|
||||
zbus::connection::Builder::vsock_stream(self.socket)
|
||||
.server(guid)
|
||||
.unwrap()
|
||||
.p2p()
|
||||
.auth_mechanism(zbus::AuthMechanism::Anonymous)
|
||||
.build()
|
||||
.await
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue