DiskConfig

Struct DiskConfig 

Source
pub struct DiskConfig {
    pub capacity_mib: u32,
    pub filesystem: Filesystem,
    pub throttle: DiskThrottle,
    pub read_only: bool,
    pub name: Option<&'static str>,
    pub no_auto_mount: bool,
}
Expand description

Per-disk config. Default is raw 256 MiB device on /dev/vda; formatting and auto-mount are deferred.

No backing-file path field: the framework owns the per-test backing file (tempfile() for Raw, FICLONE-cloned template for Btrfs). See module docs.

Fields§

§capacity_mib: u32

Advertised capacity in mebibytes (MiB). capacity_bytes() computes capacity_mib << 20. 256 MiB default capacity. Sized to accommodate common guest filesystem formatters; smaller values are accepted but may cause mkfs failures inside the template VM (see crate::vmm::disk_template::build_template_via_vm) for Filesystem::Btrfs.

§filesystem: Filesystem

Filesystem to format the per-test backing with. Raw leaves the device unformatted; Btrfs routes through the template-cache lifecycle.

§throttle: DiskThrottle

IO throttle. Default unthrottled.

§read_only: bool

Read-only at the device level — the device advertises VIRTIO_BLK_F_RO so the guest mounts read-only. Useful for tests that need protection against accidental writes.

§name: Option<&'static str>

Optional human-readable label for this disk. None (the default) is an anonymous disk addressable only by index. A name lets WorkType variants reference the disk symbolically (e.g. "data", "log") instead of by index, which keeps tests stable across topology rearrangements.

Stored as Option<&'static str> so DiskConfig is const-constructible — DiskConfig::DEFAULT.with_name("data") works in a static or const initializer, which the #[ktstr_test(disk = ...)] macro relies on. The field is #[serde(skip)] because &'static str can’t be deserialized from arbitrary input without leaking; the name is operator metadata that the framework computes on-the-fly from the declaration, not state that needs to round-trip through sidecar JSON. Sidecar consumers that need to associate a disk identity with serialized data should use the disk’s index instead.

§no_auto_mount: bool

Opt out of guest-side auto-mount. Default false means a non-Raw disk is auto-mounted at /mnt/disk0 by the guest init (see crate::vmm::rust_init::auto_mount_data_disks); setting true suppresses the auto-mount cmdline tokens and leaves /dev/vda raw to the test author. Has no effect for Filesystem::Raw disks (there is nothing to mount). The only honest reason to flip this is a test that wants to drive the mount path itself (e.g. exercise mount-option fuzzing or fail-injection on the kernel mount syscall).

Implementations§

Source§

impl DiskConfig

Source

pub const DEFAULT: Self

Const-evaluable default — same values as Default::default but usable in static / const initializers. Required for the #[ktstr_test(disk = ...)] macro surface: the macro emits a static containing a DiskConfig, which must be const-constructible.

Spread via ..DiskConfig::DEFAULT in struct-update syntax, or chain const setters (DiskConfig::DEFAULT.with_name("data")).

Source§

impl DiskConfig

Source

pub fn capacity_mib(self, mib: u32) -> Self

Set capacity in mebibytes (MiB). The argument is interpreted as binary mebibytes per Self::capacity_bytes, not decimal megabytes.

Source

pub fn filesystem(self, fs: Filesystem) -> Self

Select the on-disk filesystem.

Filesystem::Raw (the default) leaves the device unformatted. Filesystem::Btrfs routes through crate::vmm::disk_template::ensure_template: on cache miss the framework boots a one-shot template VM that runs mkfs.btrfs inside the guest, caches the formatted image, and per-test boots reflink-clone it. The lifecycle requires a reflink-capable cache directory (btrfs or xfs) and a host mkfs.btrfs binary on PATH at template-build time. See the module-level docs and crate::vmm::disk_template.

§Disk-template lifecycle

For Filesystem::Btrfs, the per-test backing file is produced in three stages — none of which the test author needs to drive explicitly:

  1. Cache lookupdisk_template::ensure_template keys off (filesystem, capacity) and returns the cached image path on hit. See the module docs at crate::vmm::disk_template for the cache-key encoding and on-disk layout.
  2. Template build (cache miss)disk_template::build_template_via_vm boots a one-shot guest with the host’s mkfs.btrfs packed into the initramfs; the guest formats /dev/vda against a sparse staging image, and the framework atomically moves the formatted image into the cache via disk_template::store_atomic. The host never execs mkfs.btrfs against a real backing file — the guest kernel is the on-disk-format authority.
  3. Per-test fan-outdisk_template::clone_to_per_test FICLONE-clones the cached image into a tempfile under the cache root. The clone is O(metadata) and copy-on-write at the extent level, so per-test writes never touch the cached template.

Stage 3 requires the cache directory to live on a reflink- capable filesystem (btrfs or xfs); see disk_template::verify_cache_dir_supports_reflink for the gate and crate::vmm::KtstrVmBuilder::disk for the full builder-side wiring.

Source

pub fn iops(self, iops: u64) -> Self

Set IOPS throttle. Passing 0 disables IOPS throttling (equivalent to None). To throttle near-zero, use iops(1). There is no “block all IO” mode — the minimum throttled rate is 1 op/sec. Any positive value is wrapped in NonZeroU64.

Clearing the rate (iops(0)) also clears the matching iops_burst_capacity — a burst capacity without a refill rate is invalid (caught by DiskThrottle::validate) and keeping a stale burst around after the user explicitly disabled the rate is a footgun: the next validate() call would fail with a less-helpful “burst without rate” error rather than the user’s intent (a fully-unthrottled bucket).

Source

pub fn bytes_per_sec(self, bytes_per_sec: u64) -> Self

Set bandwidth throttle (bytes per second). A zero value disables bandwidth throttling (stored as None); any positive value is wrapped in NonZeroU64.

Clearing the rate (bytes_per_sec(0)) also clears the matching bytes_burst_capacity for the same reason as iops — a burst without a rate is invalid and stale-burst retention turns a deliberate “drop the throttle” into a validate-time failure.

Source

pub fn iops_burst_capacity(self, capacity: u64) -> Self

Set IOPS burst capacity (token-bucket peak). A zero value clears the burst override (stored as None), reverting to the default 1-second burst (capacity equals refill rate). Any positive value is wrapped in NonZeroU64.

The capacity must be >= iops when both are set, and must not be set without iops. Both rules are enforced by DiskThrottle::validate at VM build time, not by the builder — the builder is order-independent (a user may set burst before rate). Tests should call validate() after chaining, or construct an invalid config and observe the error from VM build.

Source

pub fn bytes_burst_capacity(self, capacity: u64) -> Self

Set bandwidth burst capacity in bytes (token-bucket peak). A zero value clears the burst override (stored as None), reverting to the default 1-second burst. Any positive value is wrapped in NonZeroU64.

The capacity must be >= bytes_per_sec when both are set, and must not be set without bytes_per_sec. Both rules are enforced by DiskThrottle::validate at VM build time, not by the builder.

Source

pub fn read_only(self) -> Self

Mark the disk read-only (advertises VIRTIO_BLK_F_RO). Default is read-write; this builder takes no argument (no boolean footgun) and only flips the flag on. To return to read-write, drop the call or reconstruct from DiskConfig::default().

Source

pub const fn with_name(self, name: &'static str) -> Self

Attach a human-readable label to this disk. WorkType variants that need to address a specific disk (e.g. one of several attached) can resolve the name instead of relying on attachment order. Default is anonymous (None); calling .with_name(...) sets it.

The name also drives the guest auto-mount path: a disk named "data" auto-mounts at /mnt/data instead of the default /mnt/disk0. See Self::no_auto_mount to opt out of auto-mount entirely.

Takes &'static str so the builder is const fnDiskConfig::DEFAULT.with_name("data") can spread into a static initializer. String literals are &'static; tests needing a dynamic name should build the disk programmatically rather than going through this builder.

Source

pub fn no_auto_mount(self) -> Self

Suppress the guest-side auto-mount of this disk. Default behavior auto-mounts a non-Raw disk at the path returned by Self::auto_mount_path; calling this method flips the flag on. Useful for tests that want raw access to /dev/vda after a host-driven mkfs (e.g. mount-option fuzzing, deliberate mount-failure injection, manual subvolume traversal).

No-op for Filesystem::Raw disks (there is nothing to mount). The flag is honored at cmdline-emission time in crate::vmm::KtstrVm::build_guest_cmdline (via disk_auto_mount_cmdline_tokens): when set, the KTSTR_DISK0_FS / KTSTR_DISK0_MOUNT / KTSTR_DISK0_RO tokens are not emitted, and the guest’s crate::vmm::rust_init::auto_mount_data_disks short- circuits at the missing-token check.

Trait Implementations§

Source§

impl Clone for DiskConfig

Source§

fn clone(&self) -> DiskConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DiskConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for DiskConfig

Source§

fn default() -> Self

256 MiB, Filesystem::Raw, no throttle. The Raw default keeps the on-host cost minimal — no template-VM build, no cache directory required — and the per-test backing is a fresh sparse tempfile() per VM (see crate::vmm::KtstrVm::init_virtio_blk).

§Memory footprint

The 256 MiB sparse file lives under the host’s TMPDIR (tempfile()); actual host disk/RAM consumption equals the bytes the guest writes, not the advertised capacity. On tmpfs-backed TMPDIR (the default on most Linux distros), a fully-written disk consumes 256 MiB of host RAM per test — operators running large topologies should size host memory accordingly or override TMPDIR to a disk-backed path.

Source§

impl<'de> Deserialize<'de> for DiskConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Hash for DiskConfig

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for DiskConfig

Source§

fn eq(&self, other: &DiskConfig) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for DiskConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for DiskConfig

Source§

impl StructuralPartialEq for DiskConfig

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> MaybeSend for T
where T: Send,