Struct FaultConfiguration

Source
pub struct FaultConfiguration {
    pub fault_active: Cell<bool>,
    pub admin_fault: AdminQueueFaultConfig,
    pub pci_fault: PciFaultConfig,
    pub namespace_fault: NamespaceFaultConfig,
    pub io_fault: Arc<IoQueueFaultConfig>,
}
Expand description

Fault configuration for the NVMe fault controller.

This struct defines behaviors that inject faults into the NVMe fault controller logic, such as delaying or dropping commands, triggering namespace change notifications, or customizing completion payloads. Fault injection is controlled by the fault_active flag, unless specified otherwise in the fault description. fault_active is managed by the test via [mesh::CellUpdater]. An exception to the fault_active check is the NamespaceFaultConfig which is processed regardless of fault_active state. (See nvme_test crate for details on how the faults are applied.)

§Example

Panic when a command that matches CREATE_IO_COMPLETION_QUEUE is seen in the admin queue:

use mesh::CellUpdater;
use nvme_resources::fault::FaultConfiguration;
use nvme_resources::fault::AdminQueueFaultConfig;
use nvme_resources::fault::CommandMatch;
use nvme_spec::Command;
use nvme_resources::fault::AdminQueueFaultBehavior;
use nvme_resources::NvmeFaultControllerHandle;
use guid::Guid;
use zerocopy::FromZeros;
use zerocopy::IntoBytes;

pub fn example_fault() {
    let mut fault_start_updater = CellUpdater::new(false);

    // Setup command matches
    let mut command = Command::new_zeroed();
    let mut mask = Command::new_zeroed();

    command.cdw0 = command.cdw0.with_opcode(nvme_spec::AdminOpcode::CREATE_IO_COMPLETION_QUEUE.0);
    mask.cdw0 = mask.cdw0.with_opcode(u8::MAX);

    let fault_configuration = FaultConfiguration::new(fault_start_updater.cell())
        .with_admin_queue_fault(
            AdminQueueFaultConfig::new().with_submission_queue_fault(
                CommandMatch {
                    command: command,
                    mask: mask.as_bytes().try_into().expect("mask should be 64 bytes"),
                },
                AdminQueueFaultBehavior::Panic("Received a CREATE_IO_COMPLETION_QUEUE command".to_string()),
            )
        );
    let fault_controller_handle = NvmeFaultControllerHandle {
        subsystem_id: Guid::new_random(),
        msix_count: 10,
        max_io_queues: 10,
        namespaces: vec![
            // Define NamespaceDefinitions here
        ],
        fault_config: fault_configuration,
    };
    // Pass the controller handle in to the vm config to create and attach the fault controller. At this point the fault is inactive.
    fault_start_updater.set(true); // Activate the fault injection.
    // ... run test ...
    fault_start_updater.set(false); // Deactivate the fault injection.
}

Fields§

§fault_active: Cell<bool>

Fault active state

§admin_fault: AdminQueueFaultConfig

Fault to apply to the admin queues

§pci_fault: PciFaultConfig

Fault to apply to management layer of the controller

§namespace_fault: NamespaceFaultConfig

Fault for test triggered namespace change notifications

§io_fault: Arc<IoQueueFaultConfig>

Fault to apply to all IO queues

Implementations§

Source§

impl FaultConfiguration

Source

pub fn new(fault_active: Cell<bool>) -> Self

Create a new empty fault configuration

Source

pub fn with_pci_fault(self, pci_fault: PciFaultConfig) -> Self

Add a PCI fault configuration to the fault configuration

Source

pub fn with_admin_queue_fault(self, admin_fault: AdminQueueFaultConfig) -> Self

Add an admin queue fault configuration to the fault configuration

Source

pub fn with_io_queue_fault(self, io_fault: IoQueueFaultConfig) -> Self

Add an IO queue fault configuration to the fault configuration

Source

pub fn with_namespace_fault(self, namespace_fault: NamespaceFaultConfig) -> Self

Add a namespace fault configuration to the fault configuration

Trait Implementations§

Source§

impl DefaultEncoding for FaultConfiguration

Source§

type Encoding = TableEncoder

The encoding to use for the serialization. Read more
Source§

impl<'encoding> StructDecodeMetadata<'encoding, Resource> for FaultConfiguration

Source§

const DECODERS: &'static [ErasedDecoderEntry]

The list of decoder vtables.
Source§

impl StructEncodeMetadata<Resource> for FaultConfiguration

Source§

const ENCODERS: &'static [ErasedEncoderEntry]

The list of encoder vtables.
Source§

impl StructMetadata for FaultConfiguration

Source§

const NUMBERS: &'static [u32]

The field numbers for each field.
Source§

const OFFSETS: &'static [usize]

The byte offset to each field within the struct.

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> 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.

§

impl<T> MeshField for T
where T: DefaultEncoding, <T as DefaultEncoding>::Encoding: FieldEncode<T, Resource> + for<'a> FieldDecode<'a, T, Resource> + Send + Sync,

§

type Encoding = <T as DefaultEncoding>::Encoding

§

impl<T> MeshPayload for T
where T: DefaultEncoding + Any + Send + 'static, <T as DefaultEncoding>::Encoding: MessageEncode<T, Resource> + for<'a> MessageDecode<'a, T, Resource> + FieldEncode<T, Resource> + for<'a> FieldDecode<'a, T, Resource> + Send + Sync,

§

type Encoding = <T as DefaultEncoding>::Encoding

§

impl<T> SerializeMessage for T
where T: 'static + MeshPayload + Send,

§

type Concrete = T

The underlying concrete message type.
§

fn compute_message_size(&mut self, sizer: MessageSizer<'_>)

Computes the message size, as in [MessageEncode::compute_message_size].
§

fn write_message(self, writer: MessageWriter<'_, '_, Resource>)

Writes the message, as in [MessageEncode::write_message].
§

fn extract(self) -> <T as SerializeMessage>::Concrete

Extract the concrete message.
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<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