{% set rfcid = “RFC-0168” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
{# Fuchsia RFCs use templates to display various fields from _rfcs.yaml. View the #} {# fully rendered RFCs at https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs #}
This RFC introduces the fuchsia.diagnostics.InspectSink
protocol that allows components to expose Inspect data. As a result, the current mechanism (the DirectoryReady
event) can now be removed.
Inspect today is exposed through a mechanism that is not aligned with regular component framework capability routing. Today a component exposes a diagnostics
directory in its outgoing namespace to framework.
The DirectoryReady
event was marked deprecated in RFC-121 as part of the goal of publishing event capabilities in the SDK. However, we don’t yet have a good solution to how components will be able to expose Inspect data if this directory doesn’t exist. Additionally, Flutter on Fuchsia wants to remove our reliance on these file system abstractions and simplify their implementation. Rethinking how components expose Inspect will allow them to remove significant runtime-complexity and provide advantages to developer ergonomics.
Facilitator: leannogasawara@google.com
Reviewers:
Consulted:
Socialization: this RFC was previously socialized in the form of a Google Docs document among Diagnostics, Component Framework, Flutter and others.
Time ago, the Archivist used to ingest Inspect data through the /hub
. Its codebase was structured as directory watchers on the hub that would begin tracking Inspect data of a component the moment the out/diagnostics
directory appeared (it used to be named different at the time). This was eventually removed and done through events (in both appmgr and component manager). Also, at the time, tests that read Inspect data, did so by reading directly from the /hub
.
The Archivist currently relies on the DirectoryReady
event for two things:
expose /diagnostics to framework
).The DirectoryReady
event tackles both of these points. However, we already have CapabilityRequested
for (2) and the author believes we could tackle (1) with a regular protocol (similar to fuchsia.logger.LogSink
) bringing additional advantages.
Solving attribution is a non-goal of this RFC. That’s left as future work for removing the CapabilityRequested
event which is currently used for LogSink
and DebugData
.
This RFC introduces the InspectSink
protocol that allows the Archivist to ingest Inspect data from a component. This protocol is defined as follows:
library fuchsia.diagnostics; using zx; @discoverable protocol InspectSink { /// Publishes a handle to the `fuchsia.inspect.Tree` protocol that the server can use to read /// Inspect data, including lazy nodes. Publish(struct { tree fuchsia.inspect.Tree; root zx.handle:<VMO, zx.rights.BASIC | zx.rights.READ | zx.rights.MAP, optional>; }); /// Publishes a read handle to the inspect VMO that the component asynchronously updates. /// The server can read Inspect using the Inspect reader algorithm [1]. A component using this /// method to publish Inspect won't be able to expose lazy nodes. /// /// [1]: /docs/reference/platform-spec/diagnostics/inspect-vmo-format.md#reader_algorithm PublishVmo(struct { name string; root zx.handle:<VMO, zx.rights.BASIC | zx.rights.READ | zx.rights.MAP>; }); }
The main method is Publish
, most components will be using it as fuchsia.inspect.Tree
is the standard way of exposing Inspect. However, we provide a mechanism that allows components to publish only an Inspect VMO. This is needed for a few reasons:
fuchsia.inspect.Tree
(issue), they will continue exposing VMOs.fuchsia.inspect.Tree
, it will need to continue exposing VMOs.Just like fuchsia.logger.LogSink
, this protocol will be served by the Archivist and routed to components.
This protocol has several advantages over serving an out/diagnostics
directory:
Alignment with standard component protocol routing:
fuchsia.inspect.InspectSink
instead of doing expose /diagnostics to framework
, similar to how components export logs and traces today.CapabilityRequested
, maintaining attribution.Inspect data can be made available before starting the component async loop.
A directory is backed by the fuchsia.io.Directory
and most components do not serve their out
directory until starting their async loop. By using this protocol, snapshots can contain the Inspect data of components that haven’t started their async loop yet but have already written Inspect data.
The same applies to the fuchsia.inspect.Tree
protocol. A component’s Inspect data won’t be available in snapshots until a component starts serving this protocol, which won’t happen in most cases until a component starts its async loop. By using the protocol proposed above we can immediately provide the Archivist with both the root VMO (so at least this one is included in snapshots) and a handle to fuchsia.inspect.Tree
for future requests.
No more issues with runners and file system implementations.
out/diagnostics
on time, which is the case for the Flutter runner. That runner serves the out/
directory first and then fills it. Ideally we would just use directory watchers, but not all VFS implementations have watchers implemented (notably our VFS implementation in the C++ SDK used by Flutter) and we cannot rely on future runners using complete fuchsia.io.Directory
implementations.This change can be done under the hood by changing the inspect/client.shard.cml
to use the new protocol instead of exposing the diagnostics directory to the framework. The file inspect/client.shard.cml
is offered through the SDK, and is used by all components that expose Inspect anywhere.
This proposal is intended for v2 components. We’ll still be handling out/diagnostics
for v1 components for compatibility purposes. With the ongoing migration to v2, the author doesn’t believe it’s worth spending time changing how v1 is working. The goal is to make this change under the hood, so components being migrated to v2 don't require code changes on how they expose inspect.
The standard LSC process will be followed.
Particular steps are:
InspectSink
in the Archivist.inspect/client.shard.cml
and route fuchsia.inspect.InspectSink
to them from the Archivist. Today this introduces the problem of having to fully enumerate all such components in cml definitions, however we have a solution that has already been socialized and will be covered in a follow-up RFC.inspect/client.shard.cml
to use this protocol together with exposing the /diagnostics
directory to the framework, thus allowing for a soft transition.InspectSink
instead of exposing a diagnostics
directory in the Inspect libraries.DirectoryReady
in Component manager and remove it from the fuchsia.sys2.Event
definition once all components have been transitioned, and all prebuilts have been refreshed. We'll rely on CTF tests and the support window we have to know when this can be done.Performance should have a positive improvement as we no longer have to traverse directories or create the DirectoryReady
event, we just rely on a single protocol.
This change aligns with component framework security properties, in particular the principle of least privilege and the principle of hierarchical isolation.
No changes regarding privacy. Inspect data continues to go through the regular privacy pipelines.
The implementation of this RFC will be tested in the following ways:
Inspect discovery and hosting will be updated.
The goal is to make this change under the hood, in the libraries that write inspect. However, If we end up requiring code changes when components migrate to v2, we'll reflect those changes in the diagnostics section of the migration guide.
We could have a DiagnosticsSink which allows components to connect Inspect and logs in a single place.
We believe the con makes this alternative very unattractive as logs and Inspect are different things, so it makes sense to route them separately.
N/A