Skip to content

Commit

Permalink
virtiofs: add mount options to resource (#416)
Browse files Browse the repository at this point in the history
Add mount options to the virtiofs resource.

Allow the virtiofs mount options to be provided on the command line. To
make this work cleanly, change the `:` separator to `,`.
  • Loading branch information
jstarks authored Dec 2, 2024
1 parent dd781a0 commit 048f4de
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Guide/src/reference/openvmm/management/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ as well as the generated CLI help (via `cargo run -- --help`).
* `--virtio-console`: Enables a virtio serial device (via the MMIO transport) for Linux console access instead of COM1.
* `--virtio-console-pci`: Uses the PCI transport for the virtio serial console.
* `--gfx`: Enable a graphical console over VNC (see below)
* `--virtio-9p`: Expose a virtio 9p file system. Uses the format `tag:root_path`, e.g. `myfs:C:\\`.
* `--virtio-9p`: Expose a virtio 9p file system. Uses the format `tag,root_path`, e.g. `myfs,C:\\`.
The file system can be mounted in a Linux guest using `mount -t 9p -o trans=virtio tag /mnt/point`.
You can specify this argument multiple times to create multiple file systems.
* `--virtio-fs`: Expose a virtio-fs file system. The format is the same as `--virtio-9p`. The
Expand Down
67 changes: 55 additions & 12 deletions openvmm/openvmm_entry/src/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,21 +316,21 @@ flags:
#[clap(long, requires("igvm"), default_value = "auto=filesize", value_parser = parse_vtl2_relocation)]
pub igvm_vtl2_relocation_type: Vtl2BaseAddressType,

/// add a virtio_9p device (e.g. myfs:C:\)
#[clap(long, value_name = "tag:root_path", value_parser = parse_fs_arg)]
pub virtio_9p: Vec<(String, String)>,
/// add a virtio_9p device (e.g. myfs,C:\)
#[clap(long, value_name = "tag,root_path")]
pub virtio_9p: Vec<FsArgs>,

/// output debug info from the 9p server
#[clap(long)]
pub virtio_9p_debug: bool,

/// add a virtio_fs device (e.g. myfs:C:\)
#[clap(long, value_name = "tag:root_path", value_parser = parse_fs_arg)]
pub virtio_fs: Vec<(String, String)>,
/// add a virtio_fs device (e.g. myfs,C:\,uid=1000,gid=2000)
#[clap(long, value_name = "tag,root_path,[options]")]
pub virtio_fs: Vec<FsArgsWithOptions>,

/// add a virtio_fs device for sharing memory (e.g. myfs:\SectionDirectoryPath)
#[clap(long, value_name = "tag:root_path", value_parser = parse_fs_arg)]
pub virtio_fs_shmem: Vec<(String, String)>,
/// add a virtio_fs device for sharing memory (e.g. myfs,\SectionDirectoryPath)
#[clap(long, value_name = "tag,root_path")]
pub virtio_fs_shmem: Vec<FsArgs>,

/// add a virtio_fs device under either the PCI or MMIO bus, or whatever the hypervisor supports (pci | mmio | auto)
#[clap(long, value_name = "BUS", default_value = "auto")]
Expand Down Expand Up @@ -525,9 +525,52 @@ flags:
pub uefi_console_mode: Option<UefiConsoleModeCli>,
}

fn parse_fs_arg(opt: &str) -> Result<(String, String), &'static str> {
let (tag, root_path) = opt.split_once(':').ok_or("invalid value")?;
Ok((tag.to_owned(), root_path.to_owned()))
#[derive(Clone)]
pub struct FsArgs {
pub tag: String,
pub path: String,
}

impl FromStr for FsArgs {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.split(',');
let (Some(tag), Some(path), None) = (s.next(), s.next(), s.next()) else {
anyhow::bail!("expected <tag>,<path>");
};
Ok(Self {
tag: tag.to_owned(),
path: path.to_owned(),
})
}
}

#[derive(Clone)]
pub struct FsArgsWithOptions {
/// The file system tag.
pub tag: String,
/// The root path.
pub path: String,
/// The extra options, joined with ';'.
pub options: String,
}

impl FromStr for FsArgsWithOptions {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.split(',');
let (Some(tag), Some(path)) = (s.next(), s.next()) else {
anyhow::bail!("expected <tag>,<path>[,<options>]");
};
let options = s.collect::<Vec<_>>().join(";");
Ok(Self {
tag: tag.to_owned(),
path: path.to_owned(),
options,
})
}
}

#[derive(Copy, Clone, clap::ValueEnum)]
Expand Down
19 changes: 10 additions & 9 deletions openvmm/openvmm_entry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1172,38 +1172,39 @@ fn vm_config_from_command_line(
);
}

for (tag, root_path) in &opt.virtio_fs {
for args in &opt.virtio_fs {
add_virtio_device(
opt.virtio_fs_bus,
virtio_resources::fs::VirtioFsHandle {
tag: tag.clone(),
tag: args.tag.clone(),
fs: virtio_resources::fs::VirtioFsBackend::HostFs {
root_path: root_path.clone(),
root_path: args.path.clone(),
mount_options: args.options.clone(),
},
}
.into_resource(),
);
}

for (tag, root_path) in &opt.virtio_fs_shmem {
for args in &opt.virtio_fs_shmem {
add_virtio_device(
opt.virtio_fs_bus,
virtio_resources::fs::VirtioFsHandle {
tag: tag.clone(),
tag: args.tag.clone(),
fs: virtio_resources::fs::VirtioFsBackend::SectionFs {
root_path: root_path.clone(),
root_path: args.path.clone(),
},
}
.into_resource(),
);
}

for (tag, root_path) in &opt.virtio_9p {
for args in &opt.virtio_9p {
add_virtio_device(
VirtioBusCli::Auto,
virtio_resources::p9::VirtioPlan9Handle {
tag: tag.clone(),
root_path: root_path.clone(),
tag: args.tag.clone(),
root_path: args.path.clone(),
debug: opt.virtio_9p_debug,
}
.into_resource(),
Expand Down
1 change: 1 addition & 0 deletions openvmm/openvmm_entry/src/ttrpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ impl VmService {
tag: virtiofs.tag,
fs: virtio_resources::fs::VirtioFsBackend::HostFs {
root_path: virtiofs.root_path,
mount_options: String::new(),
},
}
.into_resource();
Expand Down
9 changes: 7 additions & 2 deletions vm/devices/virtio/virtio_resources/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ pub mod fs {

#[derive(MeshPayload)]
pub enum VirtioFsBackend {
HostFs { root_path: String },
SectionFs { root_path: String },
HostFs {
root_path: String,
mount_options: String,
},
SectionFs {
root_path: String,
},
}

impl ResourceId<VirtioDeviceHandle> for VirtioFsHandle {
Expand Down
11 changes: 9 additions & 2 deletions vm/devices/virtio/virtiofs/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use crate::virtio::VirtioFsDevice;
use crate::VirtioFs;
use lxutil::LxVolumeOptions;
use virtio::resolve::ResolvedVirtioDevice;
use virtio::resolve::VirtioResolveInput;
use virtio_resources::fs::VirtioFsBackend;
Expand All @@ -31,10 +32,16 @@ impl ResolveResource<VirtioDeviceHandle, VirtioFsHandle> for VirtioFsResolver {
input: VirtioResolveInput<'_>,
) -> Result<Self::Output, Self::Error> {
let device = match &resource.fs {
VirtioFsBackend::HostFs { root_path } => VirtioFsDevice::new(
VirtioFsBackend::HostFs {
root_path,
mount_options,
} => VirtioFsDevice::new(
input.driver_source,
&resource.tag,
VirtioFs::new(root_path, None)?,
VirtioFs::new(
root_path,
Some(&LxVolumeOptions::from_option_string(mount_options)),
)?,
input.guest_memory.clone(),
0,
None,
Expand Down

0 comments on commit 048f4de

Please sign in to comment.