devices/virtio/vhost_user_backend/block/sys/
linux.rs1use anyhow::Context;
6use argh::FromArgs;
7use base::RawDescriptor;
8use cros_async::Executor;
9use hypervisor::ProtectionType;
10
11use crate::virtio::base_features;
12use crate::virtio::block::DiskOption;
13use crate::virtio::vhost_user_backend::BackendConnection;
14use crate::virtio::BlockAsync;
15
16#[derive(FromArgs)]
17#[argh(subcommand, name = "block")]
18pub struct Options {
20 #[argh(option, arg_name = "PATH", hidden_help)]
21 socket: Option<String>,
23 #[argh(option, arg_name = "PATH")]
24 socket_path: Option<String>,
27 #[argh(option, arg_name = "FD")]
28 fd: Option<RawDescriptor>,
31
32 #[argh(option, arg_name = "PATH<:read-only>")]
33 file: String,
35}
36
37pub fn start_device(opts: Options) -> anyhow::Result<()> {
40 let ex = Executor::new().context("failed to create executor")?;
41
42 let mut fileopts = opts.file.split(':').collect::<Vec<_>>();
43 let filename = fileopts.remove(0);
44
45 let disk = DiskOption {
46 path: filename.into(),
47 read_only: fileopts.contains(&"read-only"),
48 sparse: false,
49 ..DiskOption::default()
50 };
51
52 let block = Box::new(BlockAsync::new(
53 base_features(ProtectionType::Unprotected),
54 disk.open()?,
55 &disk,
56 None,
57 None,
58 None,
59 )?);
60
61 let conn =
62 BackendConnection::from_opts(opts.socket.as_deref(), opts.socket_path.as_deref(), opts.fd)?;
63
64 conn.run_device(ex, block)
65}