diff --git a/src/agent/src/mount.rs b/src/agent/src/mount.rs index 17ea3859c2..bc13a6896f 100644 --- a/src/agent/src/mount.rs +++ b/src/agent/src/mount.rs @@ -240,6 +240,70 @@ async fn ephemeral_storage_handler( Ok("".to_string()) } +// update_ephemeral_mounts takes a list of ephemeral mounts and remounts them +// with mount options passed by the caller +#[instrument] +pub async fn update_ephemeral_mounts( + logger: Logger, + storages: Vec, + sandbox: Arc>, +) -> Result<()> { + for (_, storage) in storages.iter().enumerate() { + let handler_name = storage.driver.clone(); + let logger = logger.new(o!( + "msg" => "updating tmpfs storage", + "subsystem" => "storage", + "storage-type" => handler_name.to_owned())); + + match handler_name.as_str() { + DRIVER_EPHEMERAL_TYPE => { + fs::create_dir_all(Path::new(&storage.mount_point))?; + + if storage.options.is_empty() { + continue; + } else { + // assume that fsGid has already been set + let mut opts = Vec::<&str>::new(); + for (_, opt) in storage.options.iter().enumerate() { + if opt.starts_with(FS_GID) { + continue; + } + opts.push(opt) + } + let mount_path = Path::new(&storage.mount_point); + let src_path = Path::new(&storage.source); + + let (flags, options) = parse_mount_flags_and_options(opts); + + info!(logger, "mounting storage"; + "mount-source" => src_path.display(), + "mount-destination" => mount_path.display(), + "mount-fstype" => storage.fstype.as_str(), + "mount-options" => options.as_str(), + ); + + return baremount( + src_path, + mount_path, + storage.fstype.as_str(), + flags, + options.as_str(), + &logger, + ); + } + } + _ => { + return Err(anyhow!( + "Unsupported storage type for syncing mounts {}. Only ephemeral storage update is supported", + storage.driver.to_owned() + )); + } + }; + } + + Ok(()) +} + #[instrument] async fn overlayfs_storage_handler( logger: &Logger, diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs index 3c0bc54c75..3a927b3b56 100644 --- a/src/agent/src/rpc.rs +++ b/src/agent/src/rpc.rs @@ -51,7 +51,7 @@ use crate::device::{ }; use crate::linux_abi::*; use crate::metrics::get_metrics; -use crate::mount::{add_storages, baremount, STORAGE_HANDLER_LIST}; +use crate::mount::{add_storages, baremount, update_ephemeral_mounts, STORAGE_HANDLER_LIST}; use crate::namespace::{NSTYPEIPC, NSTYPEPID, NSTYPEUTS}; use crate::network::setup_guest_dns; use crate::pci; @@ -997,6 +997,23 @@ impl agent_ttrpc::AgentService for AgentService { }) } + async fn update_ephemeral_mounts( + &self, + ctx: &TtrpcContext, + req: protocols::agent::UpdateEphemeralMountsRequest, + ) -> ttrpc::Result { + trace_rpc_call!(ctx, "update_mounts", req); + is_allowed!(req); + + match update_ephemeral_mounts(sl!(), req.storages.to_vec(), self.sandbox.clone()).await { + Ok(_) => Ok(Empty::new()), + Err(e) => Err(ttrpc_error!( + ttrpc::Code::INTERNAL, + format!("Failed to update mounts: {:?}", e), + )), + } + } + async fn get_ip_tables( &self, ctx: &TtrpcContext,