()
| 963 | /// we can depend on a new enough ostree |
| 964 | #[context("Ensuring mountns")] |
| 965 | pub(crate) fn ensure_self_unshared_mount_namespace() -> Result<()> { |
| 966 | let uid = rustix::process::getuid(); |
| 967 | if !uid.is_root() { |
| 968 | tracing::debug!("Not root, assuming no need to unshare"); |
| 969 | return Ok(()); |
| 970 | } |
| 971 | let recurse_env = "_ostree_unshared"; |
| 972 | let ns_pid1 = std::fs::read_link("/proc/1/ns/mnt").context("Reading /proc/1/ns/mnt")?; |
| 973 | let ns_self = std::fs::read_link("/proc/self/ns/mnt").context("Reading /proc/self/ns/mnt")?; |
| 974 | // If we already appear to be in a mount namespace, or we're already pid1, we're done |
| 975 | if ns_pid1 != ns_self { |
| 976 | tracing::debug!("Already in a mount namespace"); |
| 977 | return Ok(()); |
| 978 | } |
| 979 | if std::env::var_os(recurse_env).is_some() { |
| 980 | let am_pid1 = rustix::process::getpid().is_init(); |
| 981 | if am_pid1 { |
| 982 | tracing::debug!("We are pid 1"); |
| 983 | return Ok(()); |
| 984 | } else { |
| 985 | anyhow::bail!("Failed to unshare mount namespace"); |
| 986 | } |
| 987 | } |
| 988 | bootc_utils::reexec::reexec_with_guardenv(recurse_env, &["unshare", "-m", "--"]) |
| 989 | } |
| 990 | |
| 991 | /// Load global storage state, expecting that we're booted into a bootc system. |
| 992 | /// This prepares the process for write operations (re-exec, mount namespace, etc). |
no test coverage detected