Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Use MS_SLAVE instead of MS_PRIVATE when starting a new namespace #1025

Merged
merged 2 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions crates/spfs/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,27 +326,42 @@ impl<MountNamespace> RuntimeConfigurator<IsRootUser, MountNamespace>
where
MountNamespace: __private::CurrentThreadIsInMountNamespace,
{
/// Privatize mounts in the current namespace, so that new mounts and changes
/// Remount key existing mount points so that new mounts and changes
/// to existing mounts don't propagate to the parent namespace.
pub async fn privatize_existing_mounts(&self) -> Result<()> {
///
/// We use MS_SLAVE for system mounts because we still want mount and
/// unmount events from the system to propagate into this new namespace.
/// We privatize any existing /spfs mount, though because we are likely
/// to replace it and don't want to affect any parent runtime.
pub async fn remove_mount_propagation(&self) -> Result<()> {
use nix::mount::{mount, MsFlags};

tracing::debug!("privatizing existing mounts...");
tracing::debug!("disable sharing of new mounts...");

let mut res = mount(NONE, "/", NONE, MsFlags::MS_PRIVATE, NONE);
let mut res = mount(NONE, "/", NONE, MsFlags::MS_SLAVE, NONE);
if let Err(err) = res {
return Err(Error::wrap_nix(
err,
"Failed to privatize existing mount: /",
"Failed to remove propagation from existing mount: /",
));
}

if self.is_mounted("/spfs").await? {
res = mount(NONE, "/spfs", NONE, MsFlags::MS_PRIVATE, NONE);
if let Err(err) = res {
return Err(Error::wrap_nix(
err,
"Failed to privatize existing mount: /spfs",
));
}
}

if self.is_mounted("/tmp").await? {
res = mount(NONE, "/tmp", NONE, MsFlags::MS_PRIVATE, NONE);
res = mount(NONE, "/tmp", NONE, MsFlags::MS_SLAVE, NONE);
if let Err(err) = res {
return Err(Error::wrap_nix(
err,
"Failed to privatize existing mount: /tmp",
"Failed to remove propagation from existing mount: /tmp",
));
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/spfs/src/status_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub async fn initialize_runtime(rt: &mut runtime::Runtime) -> Result<RenderSumma
rt.save_state_to_storage().await?;

let with_root = in_namespace.become_root()?;
with_root.privatize_existing_mounts().await?;
with_root.remove_mount_propagation().await?;
with_root.ensure_mount_targets_exist(&rt.config)?;
match rt.config.mount_backend {
runtime::MountBackend::OverlayFsWithRenders => {
Expand Down
Loading