blob: 9b9158323a877d57991ef0ebdec465c8797b1b88 [file] [log] [blame]
// Copyright 2020 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.
#include "bind_devfs_to_namespace.h"
#include <fuchsia/sys2/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/types.h>
namespace isolated_devmgr {
zx::status<> OneTimeSetUp() {
static zx::status<> status = []() -> zx::status<> {
// Mark this process as critical so that if this process terminates, all other processes
// within this job get terminated (e.g. file system processes).
auto status = zx::make_status(zx::job::default_job()->set_critical(0, *zx::process::self()));
if (status.is_error()) {
FX_LOGS(ERROR) << "Unable to make process critical: " << status.status_string();
return status;
}
status = isolated_devmgr::BindDevfsToNamespace();
if (status.is_error()) {
FX_LOGS(ERROR) << "Unable to bind devfs to namespace: " << status.status_string();
return status;
}
return zx::ok();
}();
return status;
}
zx::status<> BindDevfsToNamespace() {
fdio_ns_t* name_space;
auto status = zx::make_status(fdio_ns_get_installed(&name_space));
if (status.is_error()) {
FX_LOGS(ERROR) << "Failed to get namespace: " << status.status_string();
return status;
}
fidl::SynchronousInterfacePtr<fuchsia::sys2::Realm> realm;
std::string service_name = std::string("/svc/") + fuchsia::sys2::Realm::Name_;
status = zx::make_status(
fdio_service_connect(service_name.c_str(), realm.NewRequest().TakeChannel().get()));
if (status.is_error()) {
FX_LOGS(ERROR) << "Unable to connect to realm service: " << status.status_string();
return status;
}
fidl::SynchronousInterfacePtr<fuchsia::io::Directory> exposed_dir;
fuchsia::sys2::Realm_BindChild_Result result;
status = zx::make_status(realm->BindChild(fuchsia::sys2::ChildRef{.name = "isolated-devmgr"},
exposed_dir.NewRequest(), &result));
if (status.is_error() || result.is_err()) {
FX_LOGS(ERROR) << "Unable to connect to child: " << status.status_string();
return status;
}
zx::channel handle, request;
status = zx::make_status(zx::channel::create(0, &handle, &request));
if (status.is_error()) {
FX_LOGS(ERROR) << "Unable to create channel: " << status.status_string();
return status;
}
status = zx::make_status(
exposed_dir->Open(fuchsia::io::OPEN_FLAG_DIRECTORY | fuchsia::io::OPEN_RIGHT_READABLE,
fuchsia::io::MODE_TYPE_DIRECTORY, "dev",
fidl::InterfaceRequest<fuchsia::io::Node>(std::move(request))));
if (status.is_error()) {
FX_LOGS(ERROR) << "Unable to open dev in child: " << status.status_string();
return status;
}
status = zx::make_status(fdio_ns_bind(name_space, "/dev", handle.release()));
if (status.is_error()) {
FX_LOGS(ERROR) << "Failed to bind /dev to namespace: " << status.status_string();
return status;
}
return zx::ok();
}
} // namespace isolated_devmgr