blob: 807560652352899222a2f40d935d8224fb6de5ce [file] [log] [blame]
// Copyright 2019 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.
use {
crate::model::{
component::WeakComponentInstance,
routing::{self, RouteRequest},
},
bedrock_error::Explain,
fidl_fuchsia_io as fio, fuchsia_zircon as zx,
std::sync::Arc,
tracing::error,
vfs::directory::entry::{DirectoryEntry, DirectoryEntryAsync, EntryInfo, OpenRequest},
};
pub struct RouteEntry {
component: WeakComponentInstance,
request: RouteRequest,
entry_type: fio::DirentType,
}
impl RouteEntry {
pub fn new(
component: WeakComponentInstance,
request: RouteRequest,
entry_type: fio::DirentType,
) -> Arc<Self> {
Arc::new(Self { component, request, entry_type })
}
}
impl DirectoryEntry for RouteEntry {
fn entry_info(&self) -> EntryInfo {
EntryInfo::new(fio::INO_UNKNOWN, self.entry_type)
}
fn open_entry(self: Arc<Self>, request: OpenRequest<'_>) -> Result<(), zx::Status> {
request.spawn(self);
Ok(())
}
}
impl DirectoryEntryAsync for RouteEntry {
async fn open_entry_async(self: Arc<Self>, request: OpenRequest<'_>) -> Result<(), zx::Status> {
let component = match self.component.upgrade() {
Ok(component) => component,
Err(e) => {
// This can happen if the component instance tree topology changes such
// that the captured `component` no longer exists.
error!(
"failed to upgrade WeakComponentInstance while routing {}: {:?}",
self.request, e
);
return Err(e.as_zx_status());
}
};
if let Err(e) = routing::route_and_open_capability(&self.request, &component, request).await
{
routing::report_routing_failure(&self.request, &component, &e).await;
Err(e.as_zx_status())
} else {
Ok(())
}
}
}