[CF/DF] The boundary between worlds

8 views
Skip to first unread message

Hunter Freyer

unread,
Feb 23, 2021, 7:15:35 PM2/23/21
to drive...@fuchsia.dev, component-framework-dev
I wanted to do a better job of articulating the thing I said I didn't understand in the meeting.

I'm trying to get a handle on the boundary between the Driver world and the Component world: what's the interface there? And how does it compare to the way Drivers talk to each other?

Here's my understanding of the current situation:
  1. If you're a Driver talking to another Driver, your routes of communication are defined by the device topology: you can talk to the protocols that the device you bound to offers by calling a Driver Framework API. When you do so, that connection is established by some Driver Framework code. There's no devfs involved, and a Driver can't just reach out and connect to some other arbitrary Driver that it didn't bind to.
  2. If you're a Component talking to a Driver, you get /dev/ routed into your incoming namespace, and you rummage around in that until you find the device you're interested in. Then you open that path and (as long as nobody else is already using it), start talking to the Driver. If you get access to devfs, there aren't any limits to what drivers you can talk to.
Is that correct?

Here's my understanding of the plan of record:
  1. If you're a Driver talking to another Driver, your routes of communication are still defined by the device topology, but the way you access those protocols changes (for FIDL-based channels). Instead of dealing with Driver Framework APIs, you just open a path in your incoming namespace the way any other Component would access a capability it "use"s. Driver Framework is responsible for wiring these "use"d capabilities up to capabilities implemented by other Drivers, pretty much just like before, but now it's doing it behind-the-scenes.
  2. If you're a Component talking to a Driver.... I have no understanding of how that works.
Once Drivers are Components, it's less about the Driver world vs the Components world, but there's still a big distinction between the dynamic world and the static world. If you want a Capability corresponding to input events to get routed to the incoming namespace of root_presenter, you're going to have to say, in the CML, where that Capability comes from. The real source of that Capability (some Driver somewhere) doesn't exist in CML. So... how does that work?

Hunter

Seth Ladd

unread,
Feb 23, 2021, 7:34:06 PM2/23/21
to Hunter Freyer, Dave Smith, drive...@fuchsia.dev, component-framework-dev

--
All posts must follow the Fuchsia Code of Conduct https://fuchsia.dev/fuchsia-src/CODE_OF_CONDUCT or may be removed.
---
You received this message because you are subscribed to the Google Groups "component-framework-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to component-framewo...@fuchsia.dev.
To view this discussion on the web visit https://groups.google.com/a/fuchsia.dev/d/msgid/component-framework-dev/CAMkOBfsYtAPPf9D4dGPJPsFbhWZK6gQvLTawv%3Dwff89UCME0zg%40mail.gmail.com.

Justin Mattson

unread,
Feb 23, 2021, 8:04:08 PM2/23/21
to Seth Ladd, Hunter Freyer, Dave Smith, drive...@fuchsia.dev, component-framework-dev
Re: PoR, #1

Are you saying, in this case, that the plan is that there will be a driver-runner manifest of sorts which does capability routing between drivers and component manager will not be aware of this?

Suraj Malhotra

unread,
Feb 23, 2021, 8:15:26 PM2/23/21
to Justin Mattson, Seth Ladd, Hunter Freyer, Dave Smith, drive...@fuchsia.dev, component-framework-dev
The plan of record for routing from the driver collection to non drivers is something along the lines of:

Driver manager will export a "service" such as `/svc/<SERVICE_NAME>/`. Devices will dynamically add service instances such as `/svc/<SERVICE_NAME>/<INSTANCE>/`. This is analogous to the existing system where driver manager exports `/dev/` and drivers dynamically add entries to `/dev/class/<CLASS_NAME>/`. You can probably attempt to route subdirectories of the exported `/svc/<SERVICE_NAME>/` directory to get a particular instance routed to a particular component in the static topology, but I imagine most often folks will do what is done today with /dev and only route a particular class, use a directory watcher to see all instances as they appear dynamically, and figure out which instances they want to talk to.

I think there are a lot of shortcomings to this design as I've mentioned in other forums which is why I'm encouraging exploration of alternatives, but as it stands, that is the design we're working towards.

Abdulla Kamar

unread,
Feb 23, 2021, 10:26:06 PM2/23/21
to Suraj Malhotra, Justin Mattson, Seth Ladd, Hunter Freyer, Dave Smith, drive...@fuchsia.dev, component-framework-dev
POR #1 — that's correct. We currently can't directly inject things into the incoming namespace, so we have a side-channel where we provide a clone of the exposed_dir to the driver using an offer:

This is where I would like dynamic capability routing to help us. If the driver manager can specify the things we want to offer when we create the driver component, component manager can then make those available directly through the incoming namespace. Currently the things a driver component users in its manifest only come from what is offered to the collection.

POR #2 — The POR is if you're a driver component, you expose a unified service to the collection, and you can then route that to the rest of the system from the collection, just as you would anything else in the component topology. This also aligns with how we use devfs today, where a driver directly exposes services to devfs, and doesn't rely on its parent driver to act as an intermediary.

All this to say a driver component communicating with another component in the system, looks like any other component in a collection. However, we need unified services to make the exposing of a protocol/service from a collection sensible.

As Suraj alluded to, there's issues of watching for service instances and exclusive ownership. Right now, it seems like we're leaning towards routing services to components that manage policy, like fshost, to then make smarter decisions about what to do with certain services.

David Gilhooley

unread,
Feb 24, 2021, 10:12:16 AM2/24/21
to Abdulla Kamar, Suraj Malhotra, Justin Mattson, Seth Ladd, Hunter Freyer, Dave Smith, drive...@fuchsia.dev, component-framework-dev
> Then you open that path and (as long as nobody else is already using it), start talking to the Driver. 

Some drivers want exclusive access but many do not. Lots of drivers can handle multiple clients talking to them. For example, the Input drivers you're using as an example allocates new buffers for each new client and sends reports to all clients that are connected.

>  If you want a Capability corresponding to input events to get routed to the incoming namespace of root_presenter, you're going to have to say, in the CML, where that Capability comes from. The real source of that Capability (some Driver somewhere) doesn't exist in CML. So... how does that work?

DISCLAIMER: I DO NOT KNOW HOW THIS WORKS. THIS IS MY "BEST GUESS" AND SOMEONE PLEASE CORRECT ME IF I'M WRONG

How I imagine this would work is RootPresent's CML would use a "fuchsia.input.report" unified-service capability, and the code in RP could use that capability to iterate over all of the InputReport devices. In the CML above RP the "fuchsia.input.report" unified-service capability is "offered" from DriverManager. Within DriverManager, this capability comes from within the driver-components collection, specifically all of the InputReport devices.

(Forgive me if this explanation is way off base, I would be really interested in hearing the correct explanation)

Hunter Freyer

unread,
Feb 24, 2021, 1:41:38 PM2/24/21
to Abdulla Kamar, Suraj Malhotra, Justin Mattson, Seth Ladd, Dave Smith, drive...@fuchsia.dev, component-framework-dev
On Tue, Feb 23, 2021 at 10:26 PM Abdulla Kamar <abd...@google.com> wrote:
POR #1 — that's correct. We currently can't directly inject things into the incoming namespace, so we have a side-channel where we provide a clone of the exposed_dir to the driver using an offer:

This is where I would like dynamic capability routing to help us. If the driver manager can specify the things we want to offer when we create the driver component, component manager can then make those available directly through the incoming namespace. Currently the things a driver component users in its manifest only come from what is offered to the collection.

POR #2 — The POR is if you're a driver component, you expose a unified service to the collection, and you can then route that to the rest of the system from the collection, just as you would anything else in the component topology. This also aligns with how we use devfs today, where a driver directly exposes services to devfs, and doesn't rely on its parent driver to act as an intermediary.

All this to say a driver component communicating with another component in the system, looks like any other component in a collection. However, we need unified services to make the exposing of a protocol/service from a collection sensible.

As Suraj alluded to, there's issues of watching for service instances and exclusive ownership. Right now, it seems like we're leaning towards routing services to components that manage policy, like fshost, to then make smarter decisions about what to do with certain services.

On Wed, 24 Feb 2021 at 12:15, 'Suraj Malhotra' via component-framework-dev <component-f...@fuchsia.dev> wrote:
The plan of record for routing from the driver collection to non drivers is something along the lines of:

Driver manager will export a "service" such as `/svc/<SERVICE_NAME>/`. Devices will dynamically add service instances such as `/svc/<SERVICE_NAME>/<INSTANCE>/`. This is analogous to the existing system where driver manager exports `/dev/` and drivers dynamically add entries to `/dev/class/<CLASS_NAME>/`. You can probably attempt to route subdirectories of the exported `/svc/<SERVICE_NAME>/` directory to get a particular instance routed to a particular component in the static topology, but I imagine most often folks will do what is done today with /dev and only route a particular class, use a directory watcher to see all instances as they appear dynamically, and figure out which instances they want to talk to.

So, the schema here is the particular thing I'm interested in and where I think there might be misalignment. 

What is "<INSTANCE>" in your example above? It's an identifier for a node (aka "device"), correct? The plan that adamlesinski@ is working on is designed to make it easy to implement a FIDL service when the schema is "/svc/<SERVICE_NAME>/<COMPONENT_MONIKER>". Since the model is Component-per-driver, rather than Component-per-node, this isn't exactly right. 

You could have a structure like "/svc/<SERVICE_NAME>/<DRIVER_COMPONENT_MONIKER>/<NODE_ID>" coming out of the collection, but the current design doesn't support that as-is. Regardless, I don't think email is the best place to design a solution to this, but I want to make sure we acknowledge the issue.

Suraj and Adam, do I have my facts straight?

Hunter

Suraj Malhotra

unread,
Feb 24, 2021, 2:00:32 PM2/24/21
to Hunter Freyer, Abdulla Kamar, Justin Mattson, Seth Ladd, Dave Smith, drive...@fuchsia.dev, component-framework-dev
My understanding originates from the original go/unified-device-discovery design doc. Adding the driver moniker here seems like a bad idea as the client should not know what driver is implementing the service. In my example, <INSTANCE> should be dynamically determined by the provider of the service. For a network service, it could simply be MAC address, for a block partition, it could be the GPT UUID, etc. Ensuring that instance-ids don't conflict is a difficult problem I guess, but erroring out on conflicts or automatically adding a counter `-##` to duplicates would be simple solutions we could use for now.

Hunter Freyer

unread,
Feb 24, 2021, 2:11:17 PM2/24/21
to Suraj Malhotra, Abdulla Kamar, Justin Mattson, Seth Ladd, Dave Smith, drive...@fuchsia.dev, component-framework-dev
On Wed, Feb 24, 2021 at 2:00 PM Suraj Malhotra <surajm...@google.com> wrote:
My understanding originates from the original go/unified-device-discovery design doc. Adding the driver moniker here seems like a bad idea as the client should not know what driver is implementing the service. In my example, <INSTANCE> should be dynamically determined by the provider of the service. For a network service, it could simply be MAC address, for a block partition, it could be the GPT UUID, etc. Ensuring that instance-ids don't conflict is a difficult problem I guess, but erroring out on conflicts or automatically adding a counter `-##` to duplicates would be simple solutions we could use for now.

To me, this again suggests that there ought to be a layer to coordinate access to these resources (not in an ACL way, just in a resource-discovery-and-management way). It wouldn't necessarily be a problem for that layer to see which driver exposes which service, and it could name instances and reconcile conflicts in a domain-specific way. 
Reply all
Reply to author
Forward
0 new messages