integration-test: remove `netns-rs`

This crate uses a very old version of `nix` which is preventing us from
adding support for loongarch64.

Make panic-in-panic more uniform while I'm here.
reviewable/pr1374/r3
Tamir Duberstein 3 days ago
parent 12d963ddfd
commit 9e577f60b5
No known key found for this signature in database

@ -81,7 +81,6 @@ hashbrown = { version = "0.16.0", default-features = false }
indoc = { version = "2.0", default-features = false }
libc = { version = "0.2.105", default-features = false }
log = { version = "0.4", default-features = false }
netns-rs = { version = "0.1", default-features = false }
network-types = { version = "0.1.0", default-features = false }
nix = { version = "0.30.1", default-features = false }
num_enum = { version = "0.7", default-features = false }

@ -26,7 +26,7 @@ futures = { workspace = true, features = ["alloc"] }
integration-common = { path = "../integration-common", features = ["user"] }
libc = { workspace = true }
log = { workspace = true }
netns-rs = { workspace = true }
nix = { workspace = true, features = ["mount", "sched"] }
object = { workspace = true, features = ["elf", "read_core", "std"] }
procfs = { workspace = true, features = ["flate2"] }
rand = { workspace = true, features = ["thread_rng"] }

@ -11,9 +11,9 @@ use std::{
sync::atomic::{AtomicU64, Ordering},
};
use anyhow::{Context as _, Result};
use aya::netlink_set_link_up;
use libc::if_nametoindex;
use netns_rs::{NetNs, get_from_current_thread};
const CGROUP_ROOT: &str = "/sys/fs/cgroup";
const CGROUP_PROCS: &str = "cgroup.procs";
@ -91,46 +91,80 @@ impl Drop for ChildCgroup<'_> {
fd: _,
} = self;
let pids = fs::read_to_string(path.as_ref().join(CGROUP_PROCS)).unwrap();
let mut dst = fs::OpenOptions::new()
.append(true)
.open(parent.path().join(CGROUP_PROCS))
.unwrap();
for pid in pids.split_inclusive('\n') {
dst.write_all(pid.as_bytes()).unwrap();
}
match (|| -> Result<()> {
let dst = parent.path().join(CGROUP_PROCS);
let mut dst = fs::OpenOptions::new()
.append(true)
.open(&dst)
.with_context(|| {
format!(
"fs::OpenOptions::new().append(true).open(\"{}\")",
dst.display()
)
})?;
let pids = path.as_ref().join(CGROUP_PROCS);
let pids = fs::read_to_string(&pids)
.with_context(|| format!("fs::read_to_string(\"{}\")", pids.display()))?;
for pid in pids.split_inclusive('\n') {
dst.write_all(pid.as_bytes())
.with_context(|| format!("dst.write_all(\"{}\")", pid))?;
}
if let Err(e) = fs::remove_dir(&path) {
eprintln!("failed to remove {}: {e}", path.display());
fs::remove_dir(&path)
.with_context(|| format!("fs::remove_dir(\"{}\")", path.display()))?;
Ok(())
})() {
Ok(()) => (),
Err(err) => {
// Avoid panic in panic.
if std::thread::panicking() {
eprintln!("{err:?}");
} else {
panic!("{err:?}");
}
}
}
}
}
pub(crate) struct NetNsGuard {
name: String,
old_ns: NetNs,
ns: Option<NetNs>,
old_ns: fs::File,
}
impl NetNsGuard {
const PERSIST_DIR: &str = "/var/run/netns/";
pub(crate) fn new() -> Self {
let old_ns = get_from_current_thread().expect("Failed to get current netns");
let current_thread_netns_path = format!("/proc/self/task/{}/ns/net", nix::unistd::gettid());
let old_ns = fs::File::open(&current_thread_netns_path).unwrap_or_else(|err| {
panic!("fs::File::open(\"{current_thread_netns_path}\"): {err:?}")
});
static COUNTER: AtomicU64 = AtomicU64::new(0);
let pid = process::id();
let name = format!("aya-test-{pid}-{}", COUNTER.fetch_add(1, Ordering::Relaxed));
let ns = NetNs::new(&name).unwrap_or_else(|e| panic!("failed to create netns {name}: {e}"));
fs::create_dir_all(Self::PERSIST_DIR)
.unwrap_or_else(|err| panic!("fs::create_dir_all(\"{}\"): {err:?}", Self::PERSIST_DIR));
let ns_path = Path::new(Self::PERSIST_DIR).join(&name);
let _: fs::File = fs::File::create(&ns_path)
.unwrap_or_else(|err| panic!("fs::File::create(\"{}\"): {err:?}", ns_path.display()));
nix::sched::unshare(nix::sched::CloneFlags::CLONE_NEWNET)
.expect("nix::sched::unshare(CLONE_NEWNET)");
nix::mount::mount(
Some(current_thread_netns_path.as_str()),
&ns_path,
Some("none"),
nix::mount::MsFlags::MS_BIND,
None::<&str>,
)
.expect("nix::mount::mount");
ns.enter()
.unwrap_or_else(|e| panic!("failed to enter network namespace {name}: {e}"));
println!("entered network namespace {name}");
let ns = Self {
old_ns,
ns: Some(ns),
name,
};
let ns = Self { old_ns, name };
// By default, the loopback in a new netns is down. Set it up.
let lo = CString::new("lo").unwrap();
@ -153,17 +187,28 @@ impl NetNsGuard {
impl Drop for NetNsGuard {
fn drop(&mut self) {
let Self { old_ns, ns, name } = self;
// Avoid panic in panic.
if let Err(e) = old_ns.enter() {
eprintln!("failed to return to original netns: {e}");
}
if let Some(ns) = ns.take() {
if let Err(e) = ns.remove() {
eprintln!("failed to remove netns {name}: {e}");
let Self { old_ns, name } = self;
match (|| -> Result<()> {
nix::sched::setns(old_ns, nix::sched::CloneFlags::CLONE_NEWNET)
.context("nix::sched::setns(_, CLONE_NEWNET)")?;
let ns_path = Path::new(Self::PERSIST_DIR).join(&name);
nix::mount::umount2(&ns_path, nix::mount::MntFlags::MNT_DETACH).with_context(|| {
format!("nix::mount::umount2(\"{}\", MNT_DETACH)", ns_path.display())
})?;
fs::remove_file(&ns_path)
.with_context(|| format!("fs::remove_file(\"{}\")", ns_path.display()))?;
Ok(())
})() {
Ok(()) => (),
Err(err) => {
// Avoid panic in panic.
if std::thread::panicking() {
eprintln!("{err:?}");
} else {
panic!("{err:?}");
}
}
}
println!("exited network namespace {name}");
}
}

Loading…
Cancel
Save