Skip to content

Commit cd406de

Browse files
committed
Use libcontainer in vendor locally for enhanced debugging
Signed-off-by: Guvenc Gulce <[email protected]>
1 parent e67b071 commit cd406de

File tree

126 files changed

+27838
-10
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+27838
-10
lines changed

Cargo.lock

Lines changed: 16 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ net_util = {tag = "v41.0", git = "https://github.com/cloud-hypervisor/cloud-hyp
3333
vmm = { tag = "v41.0", git = "https://github.com/cloud-hypervisor/cloud-hypervisor", features = ["kvm"] }
3434
openssl = { version = "0.10.68", features = ["vendored"] }
3535
libcgroups = { version = "0.4.1", default-features = false, features = ["v2",] }
36-
libcontainer = { version = "0.4.1", default-features = false, features = [ "v2",] }
36+
libcontainer = { path = "vendor/libcontainer", default-features = false, features = ["v2"] }
3737
dhcproto = "0.12.0"
3838
rand = "0.8.5"
3939
pnet = "0.35.0"

src/isolated_container/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use hyper_util::rt::TokioIo;
88
use isolated_container_service::isolated_container_service_server::IsolatedContainerService;
99
use log::info;
1010
use std::sync::Arc;
11+
use std::time::Duration;
1112
use std::{collections::HashMap, sync::Mutex};
1213
use std::{fmt::Debug, io, path::PathBuf};
1314
use tokio::io::{AsyncReadExt, AsyncWriteExt};
1415
use tokio::net::UnixStream;
16+
use tokio::time::sleep;
1517
use tonic::transport::{Channel, Endpoint, Uri};
1618
use tonic::{transport, Request, Response, Status};
1719
use tower::service_fn;
@@ -129,15 +131,15 @@ impl IsolatedContainerAPI {
129131
)
130132
.map_err(Error::VMError)?;
131133

132-
self.vmm.boot_vm(id).map_err(Error::VMError)?;
133-
134134
self.vmm
135135
.add_net_device(
136136
id,
137137
NetworkMode::TAPDeviceName(network::Manager::device_name(&id)),
138138
)
139139
.map_err(Error::VMError)?;
140140

141+
self.vmm.boot_vm(id).map_err(Error::VMError)?;
142+
141143
Ok(())
142144
}
143145

@@ -191,6 +193,7 @@ impl IsolatedContainerService for IsolatedContainerAPI {
191193
let id = Uuid::new_v4();
192194

193195
self.prepare_vm(id).map_err(|e| self.handle_error(e))?;
196+
sleep(Duration::from_secs(2)).await;
194197

195198
self.network
196199
.start_dhcp(id)

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{env::args, ffi::CString};
99
use tokio::io;
1010
use tokio::io::{AsyncBufReadExt, BufReader};
1111

12-
#[tokio::main]
12+
#[tokio::main(flavor = "current_thread")]
1313
async fn main() -> Result<(), String> {
1414
let mut ipv6_address = Ipv6Addr::UNSPECIFIED;
1515
let mut prefix_length = 64;

src/ringbuffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,6 @@ pub fn init_logger(buffer: Arc<RingBuffer>) -> Arc<Mutex<mpsc::Receiver<String>>
8484
let (sender, receiver) = mpsc::channel(100);
8585
let logger = SimpleLogger::new(buffer, sender);
8686
log::set_boxed_logger(Box::new(logger)).unwrap();
87-
log::set_max_level(LevelFilter::Info);
87+
log::set_max_level(LevelFilter::Debug);
8888
Arc::new(Mutex::new(receiver))
8989
}

vendor/libcgroups/Cargo.toml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[package]
2+
name = "libcgroups"
3+
version = "0.4.1" # MARK: Version
4+
description = "Library for cgroup"
5+
license-file = "../../LICENSE"
6+
repository = "https://github.com/containers/youki"
7+
homepage = "https://containers.github.io/youki"
8+
readme = "README.md"
9+
authors = ["youki team"]
10+
edition = "2021"
11+
rust-version = "1.58.1"
12+
autoexamples = true
13+
keywords = ["youki", "container", "cgroups"]
14+
15+
[features]
16+
default = ["v1", "v2", "systemd"]
17+
v1 = []
18+
v2 = []
19+
systemd = ["v2", "nix/socket", "nix/uio"]
20+
cgroupsv2_devices = ["rbpf", "libbpf-sys", "errno", "libc", "nix/dir"]
21+
22+
[dependencies]
23+
nix = { version = "0.28.0", features = ["signal", "user", "fs"] }
24+
procfs = "0.16.0"
25+
oci-spec = { version = "~0.6.8", features = ["runtime"] }
26+
fixedbitset = "0.5.7"
27+
serde = { version = "1.0", features = ["derive"] }
28+
rbpf = { version = "0.2.0", optional = true }
29+
libbpf-sys = { version = "1.4.5", optional = true }
30+
errno = { version = "0.3.9", optional = true }
31+
libc = { version = "0.2.158", optional = true }
32+
thiserror = "1.0.63"
33+
tracing = { version = "0.1.40", features = ["attributes"] }
34+
35+
[dev-dependencies]
36+
anyhow = "1.0"
37+
oci-spec = { version = "~0.6.8", features = ["proptests", "runtime"] }
38+
quickcheck = "1"
39+
mockall = { version = "0.13.0", features = [] }
40+
clap = "4.1.6"
41+
serde = { version = "1.0", features = ["derive"] }
42+
serde_json = "1.0"
43+
env_logger = "0.11"
44+
serial_test = "3.1.1"
45+
tempfile = "3"

vendor/libcgroups/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# libcgroups

vendor/libcgroups/examples/bpf.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use anyhow::Result;
2+
3+
#[cfg(feature = "cgroupsv2_devices")]
4+
mod bpf {
5+
use std::os::unix::io::AsRawFd;
6+
use std::path::Path;
7+
8+
use anyhow::{bail, Result};
9+
use clap::{Arg, Command};
10+
use libcgroups::v2::devices::{bpf, emulator, program};
11+
use nix::fcntl::OFlag;
12+
use nix::sys::stat::Mode;
13+
use oci_spec::runtime::LinuxDeviceCgroup;
14+
15+
const LICENSE: &str = "Apache";
16+
fn cli() -> Command {
17+
clap::Command::new("bpf")
18+
.version("0.1")
19+
.about("tools to test BPF program for cgroups v2 devices")
20+
.arg(Arg::new("cgroup_dir").short('c').value_name("CGROUP_DIR"))
21+
.subcommand(
22+
Command::new("query").about("query list of BPF programs attached to cgroup dir"),
23+
)
24+
.subcommand(
25+
Command::new("detach")
26+
.about("detach BPF program by id")
27+
.arg(
28+
Arg::new("id")
29+
.value_name("PROG_ID")
30+
.required(true)
31+
.help("ID of BPF program returned by query command"),
32+
),
33+
)
34+
.subcommand(
35+
Command::new("attach")
36+
.about("compile rules to BPF and attach to cgroup dir")
37+
.arg(
38+
Arg::new("input_file")
39+
.value_name("INPUT_FILE")
40+
.required(true)
41+
.help("File contains Vec<LinuxDeviceCgroup> in json format"),
42+
),
43+
)
44+
}
45+
46+
fn parse_cgroupv1_device_rules<P: AsRef<Path>>(path: P) -> Result<Vec<LinuxDeviceCgroup>> {
47+
let content = std::fs::read_to_string(path)?;
48+
let devices = serde_json::from_str(&content)?;
49+
Ok(devices)
50+
}
51+
52+
pub fn run() -> Result<()> {
53+
let matches = cli().get_matches();
54+
let cgroup_dir = matches.get_one::<String>("cgroup_dir").unwrap();
55+
let cgroup_fd = nix::dir::Dir::open(
56+
cgroup_dir.as_str(),
57+
OFlag::O_RDONLY | OFlag::O_DIRECTORY,
58+
Mode::from_bits(0o600).unwrap(),
59+
)?;
60+
match matches.subcommand() {
61+
Some(("query", _)) => {
62+
let progs = bpf::prog::query(cgroup_fd.as_raw_fd())?;
63+
for prog in &progs {
64+
println!("prog: id={}, fd={}", prog.id, prog.fd);
65+
}
66+
}
67+
Some(("detach", submatch)) => {
68+
let prog_id = submatch.get_one::<String>("id").unwrap().parse::<u32>()?;
69+
let progs = bpf::prog::query(cgroup_fd.as_raw_fd())?;
70+
let prog = progs.iter().find(|v| v.id == prog_id);
71+
if prog.is_none() {
72+
bail!("can't get prog fd by prog id");
73+
}
74+
75+
bpf::prog::detach2(prog.unwrap().fd, cgroup_fd.as_raw_fd())?;
76+
println!("detach ok");
77+
}
78+
Some(("attach", submatch)) => {
79+
let input_file = submatch.get_one::<String>("input_file").unwrap();
80+
let rules = parse_cgroupv1_device_rules(input_file)?;
81+
let mut emulator = emulator::Emulator::with_default_allow(false);
82+
emulator.add_rules(&rules);
83+
let prog = program::Program::from_rules(&emulator.rules, emulator.default_allow)?;
84+
let prog_fd = bpf::prog::load(LICENSE, prog.bytecodes())?;
85+
bpf::prog::attach(prog_fd, cgroup_fd.as_raw_fd())?;
86+
println!("attach ok");
87+
}
88+
89+
_ => unreachable!(),
90+
};
91+
Ok(())
92+
}
93+
}
94+
95+
#[cfg(not(feature = "cgroupsv2_devices"))]
96+
mod bpf {
97+
use anyhow::{bail, Result};
98+
99+
pub fn run() -> Result<()> {
100+
if !cfg!(feature = "cgroupsv2_devices") {
101+
bail!("cgroupsv2_devices feature is not enabled");
102+
}
103+
104+
unreachable!()
105+
}
106+
}
107+
108+
fn main() -> Result<()> {
109+
env_logger::init();
110+
bpf::run()?;
111+
112+
Ok(())
113+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"allow": false,
4+
"access": "rwm"
5+
},
6+
{
7+
"allow": true,
8+
"type": "c",
9+
"access": "rwm"
10+
},
11+
{
12+
"allow": true,
13+
"type": "b",
14+
"major": 8,
15+
"access": "rm"
16+
}
17+
]

0 commit comments

Comments
 (0)