/// Builds and starts a microVM based on the current Firecracker VmResources configuration.
///
/// This is the default build recipe, one could build other microVM flavors by using the
/// independent functions in this module instead of calling this recipe.
///
/// An `Arc` reference of the built `Vmm` is also plugged in the `EventManager`, while another
/// is returned.
Builds and starts a microVM based on the current Firecracker VmResources configuration.
This is the default build recipe, one could build other microVM flavors by using the
independent functions in this module instead of calling this recipe.


Builds and starts a microVM based on the current Firecracker VmResources configuration . This is the default build recipe one could build other microVM flavors by using the independent functions in this module instead of calling this recipe .
pub fn build_microvm_for_boot(
    instance_info: &InstanceInfo,
    vm_resources: &super::resources::VmResources,
    event_manager: &mut EventManager,
    seccomp_filters: &BpfThreadMap,
) -> std::result::Result<Arc<Mutex<Vmm>>, StartMicrovmError> {
    use self::StartMicrovmError::*;
    // Timestamp for measuring microVM boot duration.
    let request_ts = TimestampUs::default();
    let boot_config = vm_resources.boot_source().ok_or(MissingKernelConfig)?;
    let track_dirty_pages = vm_resources.track_dirty_pages();
    let guest_memory = create_guest_memory(
        vm_resources
            .vm_config()
            .mem_size_mib
            .ok_or(MissingMemSizeConfig)?,
        track_dirty_pages,
    )?;
    let vcpu_config = vm_resources.vcpu_config();
    let entry_addr = load_kernel(boot_config, &guest_memory)?;
    let initrd = load_initrd_from_config(boot_config, &guest_memory)?;
    // Clone the command-line so that a failed boot doesn't pollute the original.
    #[allow(unused_mut)]
    let mut boot_cmdline = linux_loader::cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
    boot_cmdline.insert_str(boot_config.cmdline.as_str())?;
    let (mut vmm, mut vcpus) = create_vmm_and_vcpus(
        instance_info,
        event_manager,
        guest_memory,
        track_dirty_pages,
        vcpu_config.vcpu_count,
    )?;
    // The boot timer device needs to be the first device attached in order
    // to maintain the same MMIO address referenced in the documentation
    // and tests.
    if vm_resources.boot_timer {
        attach_boot_timer_device(&mut vmm, request_ts)?;
    }
    if let Some(balloon) = vm_resources.balloon.get() {
        attach_balloon_device(&mut vmm, &mut boot_cmdline, balloon, event_manager)?;
    }
    attach_block_devices(
        &mut vmm,
        &mut boot_cmdline,
        vm_resources.block.list.iter(),
        event_manager,
    )?;
    attach_net_devices(
        &mut vmm,
        &mut boot_cmdline,
        vm_resources.net_builder.iter(),
        event_manager,
    )?;
    if let Some(unix_vsock) = vm_resources.vsock.get() {
        attach_unixsock_vsock_device(&mut vmm, &mut boot_cmdline, unix_vsock, event_manager)?;
    }
    #[cfg(target_arch = "aarch64")]
    attach_legacy_devices_aarch64(event_manager, &mut vmm, &mut boot_cmdline).map_err(Internal)?;
    configure_system_for_boot(
        &vmm,
        vcpus.as_mut(),
        vcpu_config,
        entry_addr,
        &initrd,
        boot_cmdline,
    )?;
    // Move vcpus to their own threads and start their state machine in the 'Paused' state.
    vmm.start_vcpus(
        vcpus,
        seccomp_filters
            .get("vcpu")
            .ok_or_else(|| MissingSeccompFilters("vcpu".to_string()))?
            .clone(),
    )
    .map_err(Internal)?;
    // Load seccomp filters for the VMM thread.
    // Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
    // altogether is the desired behaviour.
    // Keep this as the last step before resuming vcpus.
    seccompiler::apply_filter(
        seccomp_filters
            .get("vmm")
            .ok_or_else(|| MissingSeccompFilters("vmm".to_string()))?,
    )
    .map_err(Error::SeccompFilters)
    .map_err(Internal)?;
    // The vcpus start off in the `Paused` state, let them run.
    vmm.resume_vm().map_err(Internal)?;
    let vmm = Arc::new(Mutex::new(vmm));
    event_manager.add_subscriber(vmm.clone());
    Ok(vmm)
}
pub fn build_microvm_for_boot ( instance_info : & InstanceInfo , vm_resources : & super :: resources :: VmResources , event_manager : & mut EventManager , seccomp_filters : & BpfThreadMap , ) -> std :: result :: Result < Arc < Mutex < Vmm > > , StartMicrovmError > { use self :: StartMicrovmError :: * ; // Timestamp for measuring microVM boot duration. let request_ts = TimestampUs :: default ( ) ; let boot_config = vm_resources . boot_source ( ) . ok_or ( MissingKernelConfig ) ? ; let track_dirty_pages = vm_resources . track_dirty_pages ( ) ; let guest_memory = create_guest_memory ( vm_resources . vm_config ( ) . mem_size_mib . ok_or ( MissingMemSizeConfig ) ? , track_dirty_pages , ) ? ; let vcpu_config = vm_resources . vcpu_config ( ) ; let entry_addr = load_kernel ( boot_config , & guest_memory ) ? ; let initrd = load_initrd_from_config ( boot_config , & guest_memory ) ? ; // Clone the command-line so that a failed boot doesn't pollute the original. # [ allow ( unused_mut ) ] let mut boot_cmdline = linux_loader :: cmdline :: Cmdline :: new ( arch :: CMDLINE_MAX_SIZE ) ; boot_cmdline . insert_str ( boot_config . cmdline . as_str ( ) ) ? ; let ( mut vmm , mut vcpus ) = create_vmm_and_vcpus ( instance_info , event_manager , guest_memory , track_dirty_pages , vcpu_config . vcpu_count , ) ? ; // The boot timer device needs to be the first device attached in order // to maintain the same MMIO address referenced in the documentation // and tests. if vm_resources . boot_timer { attach_boot_timer_device ( & mut vmm , request_ts ) ? ; } if let Some ( balloon ) = vm_resources . balloon . get ( ) { attach_balloon_device ( & mut vmm , & mut boot_cmdline , balloon , event_manager ) ? ; } attach_block_devices ( & mut vmm , & mut boot_cmdline , vm_resources . block . list . iter ( ) , event_manager , ) ? ; attach_net_devices ( & mut vmm , & mut boot_cmdline , vm_resources . net_builder . iter ( ) , event_manager , ) ? ; if let Some ( unix_vsock ) = vm_resources . vsock . get ( ) { attach_unixsock_vsock_device ( & mut vmm , & mut boot_cmdline , unix_vsock , event_manager ) ? ; } # [ cfg ( target_arch " " ) ] attach_legacy_devices_aarch64 ( event_manager , & mut vmm , & mut boot_cmdline ) . map_err ( Internal ) ? ; configure_system_for_boot ( & vmm , vcpus . as_mut ( ) , vcpu_config , entry_addr , & initrd , boot_cmdline , ) ? ; // Move vcpus to their own threads and start their state machine in the 'Paused' state. vmm . start_vcpus ( vcpus , seccomp_filters . get ( " " ) . ok_or_else ( | | MissingSeccompFilters ( " " . to_string ( ) ) ) ? . clone ( ) , ) . map_err ( Internal ) ? ; // Load seccomp filters for the VMM thread. // Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters // altogether is the desired behaviour. // Keep this as the last step before resuming vcpus. seccompiler :: apply_filter ( seccomp_filters . get ( " " ) . ok_or_else ( | | MissingSeccompFilters ( " " . to_string ( ) ) ) ? , ) . map_err ( Error :: SeccompFilters ) . map_err ( Internal ) ? ; // The vcpus start off in the `Paused` state, let them run. vmm . resume_vm ( ) . map_err ( Internal ) ? ; let vmm = Arc :: new ( Mutex :: new ( vmm ) ) ; event_manager . add_subscriber ( vmm . clone ( ) ) ; Ok ( vmm ) }
Builds and starts a microVM based on the current Firecracker VmResources configuration.
Builds and starts a microVM based on the current Firecracker VmResources configuration .
instance_info
&InstanceInfo
vm_resources
&super::resources::VmResources
event_manager
&mut EventManager
seccomp_filters
&BpfThreadMap