blob: abe94b48659a5f02ba1569a1deadcfee1f456022 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![recursion_limit = "256"]
use {
anyhow::{Context as _, Error},
fidl_fuchsia_hardware_vsock::DeviceMarker,
fuchsia_async as fasync,
fuchsia_component::client::connect_to_named_protocol_at_dir_root,
fuchsia_component::server::ServiceFs,
fuchsia_fs::OpenFlags,
futures::TryStreamExt,
futures::{StreamExt, TryFutureExt},
};
use vsock_service_lib as service;
#[fuchsia::main]
async fn main() -> Result<(), Error> {
tracing::info!("Starting vsock service");
const DEV_CLASS_VSOCK: &str = "/dev/class/vsock";
let vsock_dir =
fuchsia_fs::directory::open_in_namespace(DEV_CLASS_VSOCK, OpenFlags::RIGHT_READABLE)
.context("Open vsock dir")?;
let path = device_watcher::watch_for_files(&vsock_dir)
.await
.with_context(|| format!("Watching for files in {}", DEV_CLASS_VSOCK))?
.try_next()
.await
.with_context(|| format!("Getting a file from {}", DEV_CLASS_VSOCK))?;
let path = path.ok_or(anyhow::anyhow!("Could not find device in {}", DEV_CLASS_VSOCK))?;
let path = path.to_str().ok_or(anyhow::anyhow!("Expected valid utf-8 device name"))?;
let path = format!("{path}/device_protocol");
let dev = connect_to_named_protocol_at_dir_root::<DeviceMarker>(&vsock_dir, &path)
.context("Failed to connect vsock device")?;
let (service, event_loop) =
service::Vsock::new(dev).await.context("Failed to initialize vsock service")?;
let service_clone = service.clone();
let mut fs = ServiceFs::new();
fs.dir("svc").add_fidl_service(move |stream| {
fasync::Task::spawn(
service_clone
.clone()
.run_client_connection(stream)
.unwrap_or_else(|err| tracing::info!("Error {} during client connection", err)),
)
.detach();
});
fs.take_and_serve_directory_handle()?;
// Spawn the services server with a wrapper to discard the return value.
fasync::Task::spawn(fs.collect()).detach();
// Run the event loop until completion. The event loop only terminates
// with an error.
event_loop.await?;
Ok(())
}