blob: caee35096948b2834b0aff7704b1a187e55b8023 [file] [log] [blame] [view]
# Storage capabilities
<<../../_v2_banner.md>>
[Storage capabilities][glossary.storage-capability] allocate per-component
*isolated* storage within a filesystem directory. This prevents component
instances from accessing files belonging to other components, including their
own children.
For information on directories that can be shared between components, see
[directory capabilities][directory-capabilities].
## Backing directories {#backing-dir}
Each storage capability must be backed by a corresponding
[directory capability][glossary.directory-capability] to host an isolated
subdirectory for each component. When a component instance attempts to access
the directory provided to it through a storage capability, the framework
generates a unique subdirectory inside the backing directory for that component.
Caution: The backing directory capability can also be routed directly to other
components. Providing this capability allows components to access all the
isolated storage directories it contains.
The framework allocates storage subdirectories based on either the component
instance's [moniker][glossary.moniker] or a static
[instance ID][glossary.component-instance-identifier]. Each instance ID is a
256-bit globally unique identifier listed in a component storage index file.
The following is an example entry in a component storage index file containing a
stable instance ID:
```json5
{
instances: [
{
instance_id: "47c3bf08f3e560c4dee659c28fa8d863dbdc0b1dbb74065e6cb1f38441ac759c",
moniker: "/core/my_component",
},
],
}
```
Instance IDs allow a component's storage to persist across changes to the
component's moniker, such as moving the component instance to a different realm.
Storage IDs based on moniker are a good secondary option for tests or other use
cases where storage does not need to be durable.
For more details on instance IDs, see [Component storage index][storage-index].
## Providing storage capabilities {#provide}
To provide a storage capability, a component must declare the capability and
[route](#route) it from `self`.
```json5
{
capabilities: [
{
storage: "tmp",
from: "self",
backing_dir: "memfs",
storage_id: "static_instance_id",
},
],
}
```
You must specify [`backing_dir`](#backing-dir) with a valid directory capability
name.
The `from` field declares the component providing the backing directory.
You may supply a [component reference][component-reference] if the provider is
another component.
## Routing storage capabilities {#route}
Storage capabilities cannot be exposed to a parent component. Components should
route the [backing directory](#backing-dir) to an appropriate parent component
where storage can be [declared](#provide) and [offered](#offer) to the necessary
children.
For more details on how the framework routes component capabilities,
see [capability routing][capability-routing].
### Offering {#offer}
Offering a storage capability gives a child component access to that
capability:
```json5
{
offer: [
{
storage: "data",
from: "self",
to: [ "#storage-user" ],
},
],
}
```
## Consuming storage capabilities {#consume}
To consume a storage capability, the component must request the capability and
open the corresponding path in its [namespace][glossary.namespace].
To request the capability, add a `use` declaration for it:
```json5
{
use: [
{
storage: "data",
path: "/example_dir",
},
],
}
```
This populates the component's namespace with a directory at the provided `path`
containing the isolated storage contents.
## Storage example {#example}
Consider the following example where component `A` requests isolated storage
`tmp` from its parent:
```json5
// A.cml
{
use: [
{
storage: "tmp",
path: "/example_dir",
},
],
}
```
This provides an isolated storage directory at `/example_dir` in the namespace
of component `A`.
The parent component `B` offers this capability to `A` using a backing directory
provided by the `memfs` component in the same realm:
```json5
// B.cml
{
capabilities: [
{
storage: "tmp",
from: "#memfs",
backing_dir: "memfs",
},
],
offer: [
{
storage: "tmp",
from: "self",
to: [ "#A" ],
},
],
children: [
{ name: "A", url: "fuchsia-pkg://...", },
{ name: "memfs", url: "fuchsia-pkg://..." },
],
}
```
For more details on implementing directories, see
[directory capabilities][directory-capabilities].
[glossary.directory-capability]: /docs/glossary/README.md#directory-capability
[glossary.component-instance-identifier]: /docs/glossary/README.md#component-instance-identifier
[glossary.moniker]: /docs/glossary/README.md#moniker
[glossary.namespace]: /docs/glossary/README.md#namespace
[glossary.outgoing-directory]: /docs/glossary/README.md#outgoing-directory
[glossary.storage-capability]: /docs/glossary/README.md#storage-capability
[capability-routing]: /docs/concepts/components/v2/capabilities/README.md#routing
[component-reference]: https://fuchsia.dev/reference/cml#references
[directory-capabilities]: /docs/concepts/components/v2/capabilities/directory.md
[storage-index]: /docs/development/components/component_id_index.md