blob: 71ec1c9f43cc56d60cf871cfe4c2fd690094b504 [file] [log] [blame] [edit]
// Copyright 2016 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.
#ifndef SRC_SYS_APPMGR_NAMESPACE_H_
#define SRC_SYS_APPMGR_NAMESPACE_H_
#include <fuchsia/process/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <fs/managed_vfs.h>
#include "lib/fidl/cpp/binding_set.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/ref_counted.h"
#include "src/sys/appmgr/job_provider_impl.h"
#include "src/sys/appmgr/moniker.h"
#include "src/sys/appmgr/service_provider_dir_impl.h"
namespace component {
class Realm;
class Namespace : public fuchsia::sys::Environment,
public fuchsia::sys::Launcher,
public fuchsia::process::Resolver,
public fxl::RefCountedThreadSafe<Namespace> {
public:
const fbl::RefPtr<ServiceProviderDirImpl>& services() const { return services_; }
const fbl::RefPtr<JobProviderImpl>& job_provider() { return job_provider_; }
fxl::WeakPtr<Realm> realm() const { return realm_; }
void AddBinding(fidl::InterfaceRequest<fuchsia::sys::Environment> environment);
zx_status_t ServeServiceDirectory(zx::channel request);
zx::channel OpenServicesAsDirectory();
//
// fuchsia::process::Resolver implementation:
//
void Resolve(std::string name, fuchsia::process::Resolver::ResolveCallback callback) override;
//
// fuchsia::sys::Environment implementation:
//
void CreateNestedEnvironment(
fidl::InterfaceRequest<fuchsia::sys::Environment> environment,
fidl::InterfaceRequest<fuchsia::sys::EnvironmentController> controller, std::string label,
fuchsia::sys::ServiceListPtr additional_services,
fuchsia::sys::EnvironmentOptions options) override;
void GetLauncher(fidl::InterfaceRequest<fuchsia::sys::Launcher> launcher) override;
void GetServices(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> services) override;
void GetDirectory(zx::channel directory_request) override {
ServeServiceDirectory(std::move(directory_request));
}
void set_component_moniker(const Moniker& moniker) { services_->set_component_moniker(moniker); }
void set_component_id(const std::string& id) { services_->set_component_id(id); }
//
// fuchsia::sys::Launcher implementation:
//
void CreateComponent(
fuchsia::sys::LaunchInfo launch_info,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) override;
// Adds the service to the service directory if it's allowlisted.
void MaybeAddComponentEventProvider();
// Notifies a realms ComponentEventListener with the out/diagnostics directory for a component.
void NotifyComponentDiagnosticsDirReady(const std::string& component_url,
const std::string& component_name,
const std::string& component_id,
fidl::InterfaceHandle<fuchsia::io::Directory> directory);
// Notifies a realms ComponentEventListener that a component started.
void NotifyComponentStarted(const std::string& component_url, const std::string& component_name,
const std::string& component_id);
// Notifies a realms ComponentEventListener that a component stopped.
void NotifyComponentStopped(const std::string& component_url, const std::string& component_name,
const std::string& component_id);
// Proccesses all pending messages and shuts downs children and self.
// We handle shutdown here and not in realm and component as
// 1. It is lot of work to get realm and component to maintain state and close all dependencies.
// 2. Namespace doesn't need realm and component to be active so we can shut it down in
// background.
// 3. We anyways need to do this as a namespace might be dependent on a parent namespace, so
// parent should make sure all if its child namespace shutdown before it does.
void FlushAndShutdown(fxl::RefPtr<Namespace> self,
fs::ManagedVfs::CloseAllConnectionsForVnodeCallback callback = nullptr);
// Create child namespace. Returns |null| if the namespace is shutting down.
static fxl::RefPtr<Namespace> CreateChildNamespace(
fxl::RefPtr<Namespace>& parent, fxl::WeakPtr<Realm> realm,
fuchsia::sys::ServiceListPtr additional_services,
const std::vector<std::string>* service_allowlist);
private:
// So that constructor with parent namesapace cannot be used directly.
struct PrivateConstructor {};
enum Status {
RUNNING,
SHUTTING_DOWN,
STOPPED,
};
FRIEND_MAKE_REF_COUNTED(Namespace);
Namespace(fxl::WeakPtr<Realm> realm, fuchsia::sys::ServiceListPtr additional_services,
const std::vector<std::string>* service_allowlist);
// Use CreateChildNamespace.
Namespace(PrivateConstructor p, fxl::RefPtr<Namespace> parent, fxl::WeakPtr<Realm> realm,
fuchsia::sys::ServiceListPtr additional_services,
const std::vector<std::string>* service_allowlist);
FRIEND_REF_COUNTED_THREAD_SAFE(Namespace);
~Namespace() override;
void AddChild(fxl::RefPtr<Namespace> child);
static void ExtractChild(fxl::RefPtr<Namespace> ns, Namespace* child);
static void RunShutdownIfNoChildren(fxl::RefPtr<Namespace> ns);
fidl::BindingSet<fuchsia::sys::Environment> environment_bindings_;
fidl::BindingSet<fuchsia::sys::Launcher> launcher_bindings_;
fidl::BindingSet<fuchsia::process::Resolver> resolver_bindings_;
fs::ManagedVfs vfs_;
fbl::RefPtr<ServiceProviderDirImpl> services_;
fbl::RefPtr<JobProviderImpl> job_provider_;
// realm_ can be null when it is shutting down and we kill namespace in background.
fxl::WeakPtr<Realm> realm_;
// Set if |additional_services.provider| was set.
fuchsia::sys::ServiceProviderPtr service_provider_;
// Set if |additional_services.host_directory| was set.
zx::channel service_host_directory_;
fuchsia::sys::LoaderPtr loader_;
// Weak ptr to store in children namesapce.
fxl::WeakPtrFactory<Namespace> weak_ptr_factory_;
// List of children which have this namespace as its parent. Children should be shutdown before
// this namespace is killed.
std::map<Namespace*, fxl::RefPtr<Namespace>> children_;
// Running status of this namespace.
Status status_;
// Callbacks to call when shutdown completes.
std::vector<fs::ManagedVfs::CloseAllConnectionsForVnodeCallback> shutdown_callbacks_;
// store parent reference
fxl::WeakPtr<Namespace> parent_;
FXL_DISALLOW_COPY_AND_ASSIGN(Namespace);
};
} // namespace component
#endif // SRC_SYS_APPMGR_NAMESPACE_H_