blob: 96c940bd15fd41c89ab925b12f2a05205172a186 [file] [log] [blame]
// Copyright 2021 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 {
anyhow::{format_err, Error},
fidl::prelude::*,
fidl_fuchsia_fshost as fshost, fidl_fuchsia_io as fio,
fuchsia_runtime::{take_startup_handle, HandleType},
futures::{channel::mpsc, StreamExt},
vfs::{directory::entry::DirectoryEntry, execution_scope::ExecutionScope, path::Path},
};
mod service;
#[fuchsia::main]
async fn main() -> Result<(), Error> {
log::info!("fshost started");
let directory_request =
take_startup_handle(HandleType::DirectoryRequest.into()).ok_or_else(|| {
format_err!("missing DirectoryRequest startup handle - not launched as a component?")
})?;
let (shutdown_tx, mut shutdown_rx) = mpsc::channel::<service::FshostShutdownResponder>(1);
let export = vfs::pseudo_directory! {
"svc" => vfs::pseudo_directory! {
fshost::AdminMarker::PROTOCOL_NAME => service::fshost_admin(shutdown_tx),
}
};
let scope = ExecutionScope::new();
export.open(
scope.clone(),
fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
fio::MODE_TYPE_DIRECTORY,
Path::dot(),
directory_request.into(),
);
// when we get a message on the shutdown channel, it's time to exit.
let shutdown_responder = shutdown_rx
.next()
.await
.ok_or_else(|| format_err!("shutdown signal stream ended unexpectedly"))?;
log::info!("shutdown signal received");
// Shutting down fshost involves sending asynchronous shutdown signals to several different
// systems in order. If at any point we hit an error, we log loudly, but continue with the
// shutdown procedure.
// 0. Before fshost is told to shut down, almost everything that is running out of the
// filesystems is shut down by component manager.
// 1. Shut down the scope for the export directory. This hosts the fshost services. This
// prevents additional connections to fshost services from being created.
scope.shutdown();
// 2. Shut down all the filesystems we started.
// 3. Notify whoever asked for a shutdown that it's complete. After this point, it's possible
// the fshost process will be terminated externally.
shutdown_responder.close()?;
log::info!("fshost terminated");
Ok(())
}