-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
kernel should automatically connect its vat/devices at startup #4523
Comments
For const vatAdminService = await E(vats.vatAdmin).getService(); instead of: const vatAdminService = await E(vats.vatAdmin).createVatAdminService(devices.vatAdmin, devices.bundle); |
While implementing #4521, I was reminded that the kernel needs to send messages to built-in vats like The I'm wondering if we could do something like:
Implementing this sounds a bit tricky (we synthesize and queue Another possibility is to swap the two: the kernel gets exclusive access to an object returned by |
De-prioritized for MN-1 in discussion with @warner on Feb 22. |
What is the Problem Being Solved?
One of the motivations for #1346 was the awkwardness of having both a device (which gets endowments, but is awkward to work with) and a companion vat (which provides a nice API, but lacks endowments). We do this for a couple services:
src/devices/timer.js
src/devices/timer-src.js
src/vats/vat-timerWrapper.js
src/devices/plugin.js
src/devices/plugin-src.js
src/vats/plugin-manager.js
src/kernel/vatAdmin/vatAdmin-src.js
src/kernel/vatAdmin/vatAdminWrapper.js
#4521 ("bundle is installed" promise) could be implemented either with a companion
vats.bundles
or by adding promise support to raw devices. I'm kind of in favor of the companion vat, at the moment, because I think I can hide the device entirely, reducing the cognitive burden on bundle users. Bundlecaps would still be device nodes, but you'd useE(vats.bundles).getBundlecap(bundleID)
to get one (which could then trivially return a Promise that fires later, after installation). The one case where you'd needD()
is to get synchronous access to the bundle contents, and in the long run we want userspace to stop doing that anyways.But adding a companion vat, in all cases so far, has also imposed a burden on
bootstrap()
to wire it up. Every swingset that uses a timer must do:(#4492 also complains about this).
Swingsets that want to use vat-admin and dynamic vats must do:
To use comms and vattp and a mailbox, you need:
plus a pair of
vats.comms
/vats.vattp
messages for each remote system.It would be great if all of these obligations could go away, and the swingset itself could be responsible for the standard cross-wiring of components that live in the swingset source tree anyways.
Description of the Design
I'm thinking that
config.vats.NAME.initialize=
becomes an indicator that the given static vat wants to have access to some list of devices and/or other vats. SoinitializeSwingset()
could set:(and maybe also accept
vats:
for cross-vat connections).Then during
initializeKernel()
where we parseconfig.vats
andconfig.devices
, we'd react to.initialize
by pushing a run-queue message that will be delivered beforebootstrap()
, the equivalent of:E(vats.vatAdmin).initialize({ devices: { vatAdmin } })
E(vats.timer).initialize({ devices: { timer } })
E(vats.vattp).initialize({ devices: { mailbox } })
{ devices, vats }
if you included any vats in the config statement)When #2910 lands, we'll have an additional
start-vat
run-queue event for each static vat, which must execute before any messages can be delivered to that vat. The complete sequence of pre-queued events will then be:start-vat(vat-bootstrap)
start-vat(vat-admin)
deliver(vat-admin, initialize, { devices: { vatAdmin } })
deliver(vat-bootstrap, bootstrap, { vats, devices })
Alternatives
We could simplify the config syntax by making it coarser:
config.vats.NAME.initializeDevices
is a boolean flag that provides all devices, with a boot-timeE(vats.NAME).initializeDevices(devices)
. But if we do end up adding cross-vat links, that would give all initialized vats access to all other vats, which seems like too much authority.What This Simplifies
User-written bootstrap vats could remove some annoying boilerplate that exposes kernel/device internals they really shouldn't have to be aware of.
Adding a companion vat (e.g.
vats.bundles
) is cheaper, and doesn't increase userspace requirements.Security Considerations
The
config
object defines the initial vat configuration, including the definition of the bootstrap vat, so it already has full authority over everything that happens. It's no authority leak to allow it to share device authority to whatever vats it wants.The vat root object which receives
initialize()
is the same one that gets exposed tobootstrap()
. The bootstrap vat is ultimately trusted, but still it's a bit weird to realize that bootstrap is also in a position to send the sameinitialize()
and cause problems. And you probably wouldn't want to expose a vat root object with.initialize()
to any other vat. We already perform this separation with e.g.vatAdminService = await E(vats.vatAdmin).stuff(..)
, wherevatAdminService !== vats.vatAdmin
. So to get this attenuation and share a non-.initialize()
-bearing object with other code, you'd still need some boilerplate duringbootstrap()
. I can't think of a great way to improve this, short of changingbuildRootObject()
entirely and allow it to return multiple objects, one forinitialize()
, one for bootstrapvats.NAME
.It'd probably be a good idea for
initialize()
to throw if called more than once.Test Plan
unit tests
cc @FUDCo what do you think?
The text was updated successfully, but these errors were encountered: