Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/vhost_user_backend/block/sys/windows.rs
5394 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::fs::File;
6
use std::fs::OpenOptions;
7
use std::os::windows::fs::OpenOptionsExt;
8
9
use anyhow::bail;
10
use anyhow::Context;
11
use argh::FromArgs;
12
use base::enable_high_res_timers;
13
use base::info;
14
use base::Event;
15
use base::RawDescriptor;
16
use cros_async::sys::windows::ExecutorKindSys;
17
use cros_async::Executor;
18
use crosvm_cli::sys::windows::exit::Exit;
19
use crosvm_cli::sys::windows::exit::ExitContext;
20
use crosvm_cli::sys::windows::exit::ExitContextAnyhow;
21
use hypervisor::ProtectionType;
22
use proc_init::common_child_setup;
23
use proc_init::CommonChildStartupArgs;
24
use tube_transporter::TubeToken;
25
26
use crate::virtio::base_features;
27
use crate::virtio::block::DiskOption;
28
use crate::virtio::vhost_user_backend::block::BlockBackend;
29
use crate::virtio::vhost_user_backend::handler::sys::windows::read_from_tube_transporter;
30
use crate::virtio::vhost_user_backend::handler::sys::windows::run_handler;
31
use crate::virtio::vhost_user_backend::VhostUserDevice;
32
use crate::virtio::vhost_user_backend::VhostUserDeviceBuilder;
33
use crate::virtio::BlockAsync;
34
35
#[derive(FromArgs, Debug)]
36
#[argh(subcommand, name = "block", description = "")]
37
pub struct Options {
38
#[argh(
39
option,
40
description = "pipe handle end for Tube Transporter",
41
arg_name = "HANDLE"
42
)]
43
bootstrap: usize,
44
}
45
46
pub fn start_device(opts: Options) -> anyhow::Result<()> {
47
cros_tracing::init();
48
49
let raw_transport_tube = opts.bootstrap as RawDescriptor;
50
51
let mut tubes = read_from_tube_transporter(raw_transport_tube)?;
52
53
let vhost_user_tube = tubes.get_tube(TubeToken::VhostUser)?;
54
let _control_tube = tubes.get_tube(TubeToken::Control)?;
55
let bootstrap_tube = tubes.get_tube(TubeToken::Bootstrap)?;
56
57
let startup_args: CommonChildStartupArgs = bootstrap_tube.recv::<CommonChildStartupArgs>()?;
58
let _child_cleanup = common_child_setup(startup_args)?;
59
60
let disk_option: DiskOption = bootstrap_tube.recv::<DiskOption>()?;
61
let exit_event = bootstrap_tube.recv::<Event>()?;
62
63
// TODO(b/213146388): Replace below with `proc_init::common_child_setup`
64
// once `src` directory is upstreamed.
65
let _raise_timer_resolution =
66
enable_high_res_timers().context("failed to set timer resolution")?;
67
68
info!("using {:?} executor.", disk_option.async_executor);
69
70
let kind = disk_option.async_executor.unwrap_or_default();
71
let ex = Executor::with_executor_kind(kind).context("failed to create executor")?;
72
73
let block = Box::new(BlockAsync::new(
74
base_features(ProtectionType::Unprotected),
75
disk_option
76
.open()
77
.exit_context(Exit::OpenDiskImage, "failed to open disk image")?,
78
&disk_option,
79
None,
80
None,
81
None,
82
)?);
83
84
// TODO(b/213170185): Uncomment once sandbox is upstreamed.
85
// if sandbox::is_sandbox_target() {
86
// sandbox::TargetServices::get()
87
// .expect("failed to get target services")
88
// .unwrap()
89
// .lower_token();
90
// }
91
92
// This is basically the event loop.
93
let handler = block.build(&ex)?;
94
95
info!("vhost-user disk device ready, starting run loop...");
96
ex.run_until(run_handler(handler, vhost_user_tube, exit_event, &ex))
97
.context("run_until error")?
98
.context("run_handler error")
99
}
100
101