Path: blob/main/devices/src/virtio/vhost_user_backend/block/sys/windows.rs
5394 views
// Copyright 2022 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::fs::File;5use std::fs::OpenOptions;6use std::os::windows::fs::OpenOptionsExt;78use anyhow::bail;9use anyhow::Context;10use argh::FromArgs;11use base::enable_high_res_timers;12use base::info;13use base::Event;14use base::RawDescriptor;15use cros_async::sys::windows::ExecutorKindSys;16use cros_async::Executor;17use crosvm_cli::sys::windows::exit::Exit;18use crosvm_cli::sys::windows::exit::ExitContext;19use crosvm_cli::sys::windows::exit::ExitContextAnyhow;20use hypervisor::ProtectionType;21use proc_init::common_child_setup;22use proc_init::CommonChildStartupArgs;23use tube_transporter::TubeToken;2425use crate::virtio::base_features;26use crate::virtio::block::DiskOption;27use crate::virtio::vhost_user_backend::block::BlockBackend;28use crate::virtio::vhost_user_backend::handler::sys::windows::read_from_tube_transporter;29use crate::virtio::vhost_user_backend::handler::sys::windows::run_handler;30use crate::virtio::vhost_user_backend::VhostUserDevice;31use crate::virtio::vhost_user_backend::VhostUserDeviceBuilder;32use crate::virtio::BlockAsync;3334#[derive(FromArgs, Debug)]35#[argh(subcommand, name = "block", description = "")]36pub struct Options {37#[argh(38option,39description = "pipe handle end for Tube Transporter",40arg_name = "HANDLE"41)]42bootstrap: usize,43}4445pub fn start_device(opts: Options) -> anyhow::Result<()> {46cros_tracing::init();4748let raw_transport_tube = opts.bootstrap as RawDescriptor;4950let mut tubes = read_from_tube_transporter(raw_transport_tube)?;5152let vhost_user_tube = tubes.get_tube(TubeToken::VhostUser)?;53let _control_tube = tubes.get_tube(TubeToken::Control)?;54let bootstrap_tube = tubes.get_tube(TubeToken::Bootstrap)?;5556let startup_args: CommonChildStartupArgs = bootstrap_tube.recv::<CommonChildStartupArgs>()?;57let _child_cleanup = common_child_setup(startup_args)?;5859let disk_option: DiskOption = bootstrap_tube.recv::<DiskOption>()?;60let exit_event = bootstrap_tube.recv::<Event>()?;6162// TODO(b/213146388): Replace below with `proc_init::common_child_setup`63// once `src` directory is upstreamed.64let _raise_timer_resolution =65enable_high_res_timers().context("failed to set timer resolution")?;6667info!("using {:?} executor.", disk_option.async_executor);6869let kind = disk_option.async_executor.unwrap_or_default();70let ex = Executor::with_executor_kind(kind).context("failed to create executor")?;7172let block = Box::new(BlockAsync::new(73base_features(ProtectionType::Unprotected),74disk_option75.open()76.exit_context(Exit::OpenDiskImage, "failed to open disk image")?,77&disk_option,78None,79None,80None,81)?);8283// TODO(b/213170185): Uncomment once sandbox is upstreamed.84// if sandbox::is_sandbox_target() {85// sandbox::TargetServices::get()86// .expect("failed to get target services")87// .unwrap()88// .lower_token();89// }9091// This is basically the event loop.92let handler = block.build(&ex)?;9394info!("vhost-user disk device ready, starting run loop...");95ex.run_until(run_handler(handler, vhost_user_tube, exit_event, &ex))96.context("run_until error")?97.context("run_handler error")98}99100101