Documentation
¶
Overview ¶
Package blk is a pure-Go virtio-blk (block device) driver. It drives a modern (Virtio 1.0+) PCI virtio-blk device through the transport interfaces defined in github.com/go-virtio/common; the same code drives a UEFI-backed device, a bare-metal device, or a virtio-mmio device depending on which common.Transport implementation the caller supplies.
Scope — like go-virtio/net this package owns device bring-up, the single request virtqueue, and the on-the-wire request format (header + data + status descriptor chain, Virtio 1.1 §5.2.6), exposing a block-level ReadBlocks / WriteBlocks / Flush API. The protocol sector size is always 512 bytes (BlockSize) regardless of any logical block size the device advertises.
- Modern transport (VIRTIO_F_VERSION_1 mandatory). Legacy devices are rejected by the common init sequence.
- One request virtqueue; requests are descriptor chains built with common.AddChain.
- VIRTIO_BLK_F_RO is honoured (read-only devices reject writes). No other feature bit is negotiated (FLUSH works regardless on the devices we target; richer features are out of scope).
References:
- Virtio 1.1 §5.2 "Block Device" — device-type 2 binding.
- Virtio 1.1 §5.2.4 "Device configuration layout" — le64 capacity.
- Virtio 1.1 §5.2.6 "Device Operation" — struct virtio_blk_req.
- Virtio 1.1 §3.1.1 "Device Initialization".
Index ¶
Constants ¶
const ( BlkTypeIn uint32 = 0 // read (device writes data) BlkTypeOut uint32 = 1 // write (device reads data) BlkTypeFlush uint32 = 4 )
Request types (Virtio 1.1 §5.2.6 — virtio_blk_req.type).
const ( BlkStatusOK uint8 = 0 BlkStatusIOErr uint8 = 1 BlkStatusUnsupp uint8 = 2 )
Status byte values (Virtio 1.1 §5.2.6 — the device-writable trailer).
const AcceptedFeatures uint64 = common.FeatureVersion1
AcceptedFeatures is the feature mask the driver negotiates ON — only the non-negotiable VIRTIO_F_VERSION_1. (F_RO is inspected from the device's offered set but is not a driver-acked bit.)
const BlkReqHeaderSize = 16
BlkReqHeaderSize is the on-the-wire size of struct virtio_blk_req's header (Virtio 1.1 §5.2.6.1): le32 type, le32 reserved, le64 sector.
const BlockSize = 512
BlockSize is the virtio-blk protocol sector size — always 512 bytes (Virtio 1.1 §5.2.6); the device's `sector` fields count 512-byte units.
const DeviceType uint16 = 2
DeviceType is the virtio device-type encoding for virtio-blk (Virtio 1.1 §5.2.1). Retained from the package's placeholder era for callers enumerating PCI devices that want a stable name.
const RequestQueueIdx uint16 = 0
RequestQueueIdx is the index of the single virtio-blk request queue.
const RequestQueueSize uint16 = 16
RequestQueueSize is the desired ring size (clamped + rounded during setup). A request consumes 2–3 descriptors, so this bounds the number of in-flight requests; the driver issues them one at a time.
const TxPollIterations = 200000
TxPollIterations is the default busy-poll budget for one request.
Variables ¶
var ( ErrNotModernDevice = commonBlkError("go-virtio/blk: device doesn't offer VIRTIO_F_VERSION_1 (legacy-only)") ErrFeaturesNotOK = commonBlkError("go-virtio/blk: FEATURES_OK status bit didn't stick after DriverFeature write") ErrInitWrongDeviceID = commonBlkError("go-virtio/blk: PCI device ID is not 0x1042 (modern block device)") ErrQueueNotAvailable = commonBlkError("go-virtio/blk: device reports QueueSize=0 for the request queue") ErrRequestTimeout = commonBlkError("go-virtio/blk: request poll timeout (device did not complete the request)") ErrZeroCount = commonBlkError("go-virtio/blk: ReadBlocks count must be positive") ErrUnalignedLength = commonBlkError("go-virtio/blk: write length must be a positive multiple of BlockSize (512)") ErrReadOnly = commonBlkError("go-virtio/blk: device is read-only (VIRTIO_BLK_F_RO)") ErrIO = commonBlkError("go-virtio/blk: device reported VIRTIO_BLK_S_IOERR") ErrUnsupported = commonBlkError("go-virtio/blk: device reported VIRTIO_BLK_S_UNSUPP") )
Sentinel errors for the virtio-blk path.
Functions ¶
func AcceptFeatures ¶ added in v0.2.0
AcceptFeatures returns the negotiated mask (requires VERSION_1).
Types ¶
type VirtioBlk ¶ added in v0.2.0
type VirtioBlk struct {
// Cfg is the modern-transport handle.
Cfg *common.ModernConfig
// Capacity is the device size in 512-byte sectors (Virtio 1.1
// §5.2.4), read from DeviceCfg at OpenVirtioBlk.
Capacity uint64
// ReadOnly reflects VIRTIO_BLK_F_RO in the device's offered features.
ReadOnly bool
// NegotiatedFeatures records the driver-feature handshake result.
NegotiatedFeatures uint64
// contains filtered or unexported fields
}
VirtioBlk wraps one initialised virtio-blk device.
func OpenVirtioBlk ¶ added in v0.2.0
OpenVirtioBlk drives the full bring-up of one virtio-blk device:
- Verify the PCI device ID is 0x1042 (modern block).
- InitModernConfig walks PCI caps + populates the BAR locators.
- Reset → ACK → DRIVER status progression.
- Read DeviceFeature, record RO, mask to VERSION_1, write DriverFeature.
- Set FEATURES_OK, verify it stuck.
- Allocate + publish the request queue (queue 0).
- DRIVER_OK status.
- Read capacity (le64 sectors) from DeviceCfg.
func (*VirtioBlk) Flush ¶ added in v0.2.0
Flush issues a VIRTIO_BLK_T_FLUSH request, asking the device to commit volatile write caches to stable storage.
func (*VirtioBlk) ReadBlocks ¶ added in v0.2.0
ReadBlocks reads `count` 512-byte sectors starting at `sector` and returns the data. count must be positive.
func (*VirtioBlk) RequestQueue ¶ added in v0.2.0
RequestQueue exposes the request virtqueue handle for diagnostics.
func (*VirtioBlk) WriteBlocks ¶ added in v0.2.0
WriteBlocks writes `data` (a whole number of 512-byte sectors) starting at `sector`. Returns ErrReadOnly if the device is read-only, or ErrUnalignedLength if len(data) is not a positive multiple of BlockSize.