Skip to content

Instantly share code, notes, and snippets.

@leseb
Created December 2, 2022 09:57
Show Gist options
  • Save leseb/cbc975e07ddb3851a95f0cdd692c50b2 to your computer and use it in GitHub Desktop.
Save leseb/cbc975e07ddb3851a95f0cdd692c50b2 to your computer and use it in GitHub Desktop.
use log::info;
use nix::{
sched::{unshare, CloneFlags},
sys::stat::stat,
unistd::{getpid, getppid, gettid},
};
pub type StratisResult<T> = Result<T, StratisError>;
#[derive(Debug)]
pub enum StratisError {
Msg(String),
Nix(nix::Error),
}
impl From<nix::Error> for StratisError {
fn from(err: nix::Error) -> StratisError {
StratisError::Nix(err)
}
}
/// Path to the root mount namespace
const INIT_MNT_NS_PATH: &str = "/proc/1/ns/mnt";
fn main() {
env_logger::init();
let main_pid = getpid();
let ppid = getppid();
let tid = gettid();
info!("main pid: {}", main_pid);
info!("ppid: {}", ppid);
info!("tid: {}", tid);
unshare_namespace().unwrap();
}
/// Check if the stratisd mount namespace for this thread is in the root namespace.
fn is_in_root_namespace() -> StratisResult<bool> {
let tid = gettid();
let pid_one_stat = stat(INIT_MNT_NS_PATH)?;
let self_stat = stat(format!("/proc/self/task/{}/ns/mnt", tid).as_str())?;
info!("pid_one_stat.st_ino: {}", pid_one_stat.st_ino);
info!("self_stat.st_ino: {}", self_stat.st_ino);
info!("pid_one_stat.st_dev: {}", pid_one_stat.st_dev);
info!("self_stat.st_dev: {}", self_stat.st_dev);
Ok(pid_one_stat.st_ino == self_stat.st_ino && pid_one_stat.st_dev == self_stat.st_dev)
}
fn unshare_namespace() -> StratisResult<()> {
if is_in_root_namespace()? {
info!("unshare");
unshare(CloneFlags::CLONE_NEWNS)?;
assert!(!is_in_root_namespace()?);
}
info!("success");
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment