Skip to content

Commit 1c30403

Browse files
committed
install: Do a dynamic mount for /var/tmp
Closes: #1292 Basically we were doing the `/proc/1/root/var/tmp` trick for `/var/tmp` because we didn't have the dynamic bind mount infrastructure before. Now we do, so use it instead. The specific motivation is that Go in some cases uses `EvalSymlinks` which gets confused by the `/proc/<pid>/root` magic links. Also, this deletes a lot of code. Signed-off-by: Colin Walters <[email protected]>
1 parent 3b41d81 commit 1c30403

File tree

1 file changed

+13
-55
lines changed

1 file changed

+13
-55
lines changed

lib/src/install.rs

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,22 +1103,11 @@ fn require_host_userns() -> Result<()> {
11031103
Ok(())
11041104
}
11051105

1106-
// Ensure the `/var` directory exists.
1107-
fn ensure_var() -> Result<()> {
1108-
std::fs::create_dir_all("/var")?;
1109-
Ok(())
1110-
}
1111-
1112-
/// We want to have proper /tmp and /var/tmp without requiring the caller to set them up
1113-
/// in advance by manually specifying them via `podman run -v /tmp:/tmp` etc.
1114-
/// Unfortunately, it's quite complex right now to "gracefully" dynamically reconfigure
1115-
/// the mount setup for a container. See https://brauner.io/2023/02/28/mounting-into-mount-namespaces.html
1116-
/// So the brutal hack we do here is to rely on the fact that we're running in the host
1117-
/// pid namespace, and so the magic link for /proc/1/root will escape our mount namespace.
1118-
/// We can't bind mount though - we need to symlink it so that each calling process
1119-
/// will traverse the link.
1120-
#[context("Linking tmp mounts to host")]
1121-
pub(crate) fn setup_tmp_mounts() -> Result<()> {
1106+
/// Ensure that /tmp is a tmpfs because in some cases we might perform
1107+
/// operations which expect it (as it is on a proper host system).
1108+
/// Ideally we have people run this container via podman run --read-only-tmpfs
1109+
/// actually.
1110+
pub(crate) fn setup_tmp_mount() -> Result<()> {
11221111
let st = rustix::fs::statfs("/tmp")?;
11231112
if st.f_type == libc::TMPFS_MAGIC {
11241113
tracing::trace!("Already have tmpfs /tmp")
@@ -1130,42 +1119,6 @@ pub(crate) fn setup_tmp_mounts() -> Result<()> {
11301119
.quiet()
11311120
.run()?;
11321121
}
1133-
1134-
// Point our /var/tmp at the host, via the /proc/1/root magic link
1135-
for path in ["/var/tmp"].map(Utf8Path::new) {
1136-
if path.try_exists()? {
1137-
let st = rustix::fs::statfs(path.as_std_path()).context(path)?;
1138-
if st.f_type != libc::OVERLAYFS_SUPER_MAGIC {
1139-
tracing::trace!("Already have {path} with f_type={}", st.f_type);
1140-
continue;
1141-
}
1142-
}
1143-
let target = format!("/proc/1/root/{path}");
1144-
let tmp = format!("{path}.tmp");
1145-
// Ensure idempotence in case we're re-executed
1146-
if path.is_symlink() {
1147-
continue;
1148-
}
1149-
tracing::debug!("Retargeting {path} to host");
1150-
if path.try_exists()? {
1151-
std::os::unix::fs::symlink(&target, &tmp)
1152-
.with_context(|| format!("Symlinking {target} to {tmp}"))?;
1153-
let cwd = rustix::fs::CWD;
1154-
rustix::fs::renameat_with(
1155-
cwd,
1156-
path.as_os_str(),
1157-
cwd,
1158-
&tmp,
1159-
rustix::fs::RenameFlags::EXCHANGE,
1160-
)
1161-
.with_context(|| format!("Exchanging {path} <=> {tmp}"))?;
1162-
std::fs::rename(&tmp, format!("{path}.old"))
1163-
.with_context(|| format!("Renaming old {tmp}"))?;
1164-
} else {
1165-
std::os::unix::fs::symlink(&target, path)
1166-
.with_context(|| format!("Symlinking {target} to {path}"))?;
1167-
};
1168-
}
11691122
Ok(())
11701123
}
11711124

@@ -1293,11 +1246,16 @@ async fn prepare_install(
12931246
};
12941247
tracing::debug!("Target image reference: {target_imgref}");
12951248

1296-
// A bit of basic global state setup
1249+
// We need to access devices that are set up by the host udev
12971250
bootc_mount::ensure_mirrored_host_mount("/dev")?;
1251+
// We need to read our own container image (and any logically bound images)
1252+
// from the host container store.
12981253
bootc_mount::ensure_mirrored_host_mount("/var/lib/containers")?;
1299-
ensure_var()?;
1300-
setup_tmp_mounts()?;
1254+
// In some cases we may create large files, and it's better not to have those
1255+
// in our overlayfs.
1256+
bootc_mount::ensure_mirrored_host_mount("/var/tmp")?;
1257+
// We also always want /tmp to be a proper tmpfs on general principle.
1258+
setup_tmp_mount()?;
13011259
// Allocate a temporary directory we can use in various places to avoid
13021260
// creating multiple.
13031261
let tempdir = cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;

0 commit comments

Comments
 (0)