block: medium presence — the medium_changed event and usb-storage as publisher (V2b)
The block protocol gains a pushed medium_changed event (present + a monotonic change counter; presence only, never content). usb-storage becomes a Subscribers provider and runs a slow TEST UNIT READY poll (1 s): success is present, failure absent, and a transition bumps the counter and publishes. This is the second removal trigger — the DEVICE stays while the MEDIUM leaves (card readers, ATAPI trays) — which channel death cannot see (storage-architecture.md, two triggers one lifecycle). The subscriber is the volume manager (V3); until it exists the publish is a no-op fan-out, so this commit is behaviour-neutral, and its end-to-end test (eject -> medium_changed -> unmount/remount) lands in V4 with the real consumer rather than a throwaway subscriber fixture (recorded sequencing). Sense-key inspection to tell medium-absent from other transport errors is a noted refinement; a clean eject reads correctly as not-ready. Neutral: 12/12 across the block-serving surface, restart, confinement, conformance, and logging.
This commit is contained in:
@@ -57,9 +57,27 @@ pub const DefineRange = extern struct {
|
||||
block_count: u64,
|
||||
};
|
||||
|
||||
/// The `medium_changed` event payload: whether a medium is now present, and a
|
||||
/// monotonic counter so a subscriber that missed an edge still sees that
|
||||
/// SOMETHING changed. Pushed by a driver whose transport can tell medium from
|
||||
/// device (a card reader, an ATAPI tray): the device stays, the medium comes and
|
||||
/// goes. The volume manager consumes it into the same unmount/remount path it
|
||||
/// runs on device death — one lifecycle, two triggers
|
||||
/// (docs/file-system-development/storage-architecture.md). Presence only, never
|
||||
/// content: the driver reports that the medium changed, not what is on it.
|
||||
pub const MediumChanged = extern struct {
|
||||
present: u8, // 1 present, 0 absent
|
||||
_padding: u8 = 0,
|
||||
_padding2: u16 = 0,
|
||||
change_count: u32,
|
||||
};
|
||||
|
||||
pub const Protocol = envelope.Define(.{
|
||||
.name = "block",
|
||||
.version = 1,
|
||||
.events = &.{
|
||||
.{ .name = "medium_changed", .payload = MediumChanged },
|
||||
},
|
||||
.operations = &.{
|
||||
.{ .name = "geometry", .reply = Geometry },
|
||||
.{ .name = "read", .request = Transfer, .reply = Transferred },
|
||||
@@ -88,4 +106,5 @@ pub const Protocol = envelope.Define(.{
|
||||
});
|
||||
|
||||
pub const Operation = Protocol.Operation;
|
||||
pub const Event = Protocol.Event;
|
||||
pub const message_maximum: usize = Protocol.message_maximum;
|
||||
|
||||
Reference in New Issue
Block a user