Skip to content

Latest commit

 

History

History
216 lines (159 loc) · 10.6 KB

File metadata and controls

216 lines (159 loc) · 10.6 KB

OpenHCL storage configuration model

The VTL2 settings model describes guest-visible storage controllers, child devices, and their backing devices. For the internal architecture of the disk backend abstraction, the layered disk model, and how frontends translate guest I/O into DiskIo calls, see the storage pipeline page.

Overview

The OpenHCL storage settings surface is easiest to read as a small tree:

  1. a guest-visible controller
  2. one or more guest-visible child devices under that controller
  3. one or more backing devices behind each child

The same tree appears in three places:

This page lines those views up so you do not have to infer the schema from the JSON alone.

Fixed settings

The fixed section of VTL2 settings contains values that apply globally, not per-controller. The key storage-related field is scsi_sub_channels:

Field Type Default Meaning
scsi_sub_channels u16 0 Maximum sub-channel count for all SCSI controllers. Clamped to 256 at runtime.
io_ring_size u32 256 Size of each per-CPU io_uring submission queue in the OpenHCL threadpool. Not StorVSP-specific — affects all async I/O.

See StorVSP Channels & Subchannels for the full subchannel model, performance characteristics, and configuration guidance.

One controller tree

  StorageController (protocol + instance_id)
   ├── Lun / child 0
   │    └── PhysicalDevices::Single
   │         └── PhysicalDevice
   └── Lun / child 1
        └── PhysicalDevices::Striped
             ├── PhysicalDevice A
             └── PhysicalDevice B

The protobuf and JSON surface uses StorageController and Lun. The runtime view in underhill_config splits that same tree into concrete controller and child types such as ScsiController, ScsiDisk, NvmeController, and NvmeNamespace.

Two naming layers

Concept JSON / protobuf surface Runtime surface in underhill_config
Guest-visible controller StorageController IdeController, ScsiController, NvmeController
Guest-visible child device Lun IdeDisk, ScsiDisk, NvmeNamespace
Backing wrapper PhysicalDevices PhysicalDevices
Backing device PhysicalDevice PhysicalDevice

One non-obvious point is that the protobuf type keeps using the name Lun even when the guest-visible protocol is NVMe. At runtime, that same object becomes an NvmeNamespace, because the meaning of the child address depends on the controller protocol.

StorageController

StorageController is the guest-visible controller object. It answers the question "what controller family will VTL0 enumerate?"

Field Meaning
instance_id Guest-visible controller instance GUID
protocol Guest-visible controller family: IDE, SCSI, or NVMe
luns Child devices exposed under that controller
io_queue_depth Optional queue-depth tuning for supported controllers

The protocol field is the most important one architecturally. It does not describe the backing side. It describes what kind of controller the guest will see.

Lun

Lun is the schema object for a guest-visible child device under a controller. The guest meaning of location depends on the controller protocol:

Controller protocol Guest meaning of the child Relevant child fields
IDE IDE drive slot channel + location
SCSI SCSI LUN location
NVMe NVMe namespace location

Besides the child address, a Lun also carries the device identity strings and the backing-device description:

  • device_id, vendor_id, product_id, product_revision_level, serial_number, model_number
  • physical_devices
  • is_dvd
  • chunk_size_in_kb

For NVMe, location becomes the namespace ID at runtime. For IDE, channel is required because the guest-visible slot is a (channel, location) pair instead of a single number.

PhysicalDevices

PhysicalDevices wraps the backing side of a child device. It tells OpenHCL whether the guest-visible child is backed by zero, one, or multiple physical devices.

Shape Meaning
EmptyDrive No backing media. This is the empty-DVD case in the runtime model.
Single { device } Exactly one backing PhysicalDevice
Striped { devices, chunk_size_in_kb } Two or more backing PhysicalDevices combined into one guest-visible child

In the protobuf and JSON shape, Single uses the singular device field. Striped uses the plural devices field and takes the stripe size from chunk_size_in_kb.

PhysicalDevice

PhysicalDevice describes one backing device offered into VTL2.

Field Meaning
device_type Backing device family: nvme or vscsi
device_path VMBus instance GUID of the backing controller or device
sub_device_path Child inside that backing device

The petri::vtl2_settings helpers describe this directly: both SCSI and NVMe backing devices are treated as VMBus devices, so device_path is the VMBus instance ID. The sub_device_path field selects the child inside that device:

  • for vscsi, it is the host LUN
  • for nvme, it is the namespace ID

IDE is a guest-visible target family, but it is not supported as a VTL2 backing device.

Example: one SCSI target backed by one vSCSI device

The Running OpenHCL with Hyper-V page includes a concrete example of this shape:

{
  "instance_id": "<GUEST_SCSI_CONTROLLER_GUID>",
  "protocol": "SCSI",
  "luns": [
    {
      "location": 15,
      "physical_devices": {
        "type": "single",
        "device": {
          "device_type": "vscsi",
          "device_path": "<HOST_SCSI_CONTROLLER_GUID>",
          "sub_device_path": 5
        }
      }
    }
  ]
}

Read this from top to bottom:

  • protocol: "SCSI" says the guest-visible controller is SCSI
  • location: 15 says the child appears as guest LUN 15
  • device_type: "vscsi" says the backing side is vSCSI
  • device_path identifies the backing SCSI controller offered into VTL2
  • sub_device_path: 5 selects host LUN 5 on that controller

That is the clearest example of why the guest-visible target and the backing side are different layers.

Example: striped backing

When a guest-visible child is striped, the guest-visible side can stay the same while the backing side fans out:

{
  "physical_devices": {
    "type": "striped",
    "devices": [
      { "device_type": "nvme", "device_path": "<GUID_A>", "sub_device_path": 1 },
      { "device_type": "nvme", "device_path": "<GUID_B>", "sub_device_path": 1 }
    ]
  },
  "chunk_size_in_kb": 128
}

The schema treats stripe geometry as a property of the guest-visible child, not of the controller as a whole.

Validation rules and limits

The runtime model and schema enforce several important constraints:

Rule Where it shows up
IDE has 2 channels and 2 drive slots per channel underhill_config::IDE_NUM_CHANNELS and IDE_MAX_DRIVES_PER_CHANNEL
SCSI supports up to 4 controllers and 64 LUN slots per controller underhill_config::SCSI_CONTROLLER_NUM and SCSI_LUN_NUM
Single must carry exactly one backing device schema::v1 parses device and rejects extra entries
Striped must carry at least two backing devices schema::v1 rejects too few devices
NVMe namespace IDs cannot be 0 or !0 schema::v1 validates location for NVMe
NVMe children cannot be DVDs schema::v1 rejects is_dvd on NVMe
SCSI subchannel count is clamped to 256 underhill_core::dispatch::vtl2_settings_worker, scsi_sub_channels.min(256)
IDE can be a guest-visible target but not a VTL2 backing source petri::vtl2_settings and openvmm_entry::storage_builder reject IDE backing

These rules are useful when debugging configuration failures because they tell you whether the problem is in controller selection, child addressing, or backing-device declaration.

How OpenVMM fills this model

The Running OpenHCL with OpenVMM page shows where OpenVMM consumes this model. In code, openvmm_entry::storage_builder makes the two-axis split visible:

  1. add_underhill() chooses a source backing device family and a target guest-visible controller family separately.
  2. It derives sub_device_path from the source child it created in VTL2.
  3. It emits Lun objects whose physical_devices point back to that source.
  4. build_underhill() groups those Luns under guest-visible StorageControllers for SCSI or NVMe.

Read the configuration model as a description of the guest-visible tree plus a separate description of the backing tree under each child.

Implementation map

Component Why read it Source Rustdoc
Underhill configuration model Defines the runtime controller, child, and backing types vm/devices/get/underhill_config/src/lib.rs underhill_config
Schema parsing and validation Shows how JSON and protobuf fields map into runtime structs and what errors are enforced vm/devices/get/underhill_config/src/schema/v1.rs underhill_config
Test-side builders Documents device_path, sub_device_path, single backing, and striped backing in a compact API petri/src/vm/vtl2_settings.rs petri
OpenVMM builder path Shows how CLI shorthand is expanded into guest-visible StorageController and Lun objects openvmm/openvmm_entry/src/storage_builder.rs openvmm_entry