fn get_mount_namespaces()

in xar/clean_xar_mounts/src/main.rs [83:118]


fn get_mount_namespaces() -> Result<Vec<MountNamespaceInfo>> {
    // The inode of the /proc/PID/ns/mnt file (not the symlink itself,
    // but the dereferenced symlink) is the namespace id.  Build a
    // HashMap mapping the namespace id to an arbitrary symlink that
    // pointed to it.
    let mut namespace_dedup = HashMap::new();
    for entry in fs::read_dir("/proc")? {
        let entry = entry.unwrap();
        let entry_name = entry.file_name().into_string().unwrap();
        let pid = match u64::from_str(&entry_name) {
            Ok(pid) => pid,
            Err(_) => continue,
        };
        if !entry.file_type()?.is_dir() {
            continue;
        }
        let namespace_path = PathBuf::from(format!("/proc/{}/ns/mnt", entry_name));
        let inode = match fs::metadata(&namespace_path) {
            Ok(st) => st.st_ino(),
            Err(_) => continue,
        };
        let chroot_path = match fs::read_link(PathBuf::from(format!("/proc/{}/root", entry_name))) {
            Ok(path) => path,
            Err(_) => continue,
        };
        namespace_dedup.insert(
            inode,
            MountNamespaceInfo {
                namespace_path,
                chroot_path,
                pid,
            },
        );
    }
    Ok(namespace_dedup.into_iter().map(|p| p.1).collect())
}