Skip to content

Commit 908ee54

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

File tree

7 files changed

+147
-27
lines changed

7 files changed

+147
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hack/libvirt/libvirt-kvm.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<libosinfo:os id="http://libosinfo.org/linux/2022"/>
66
</libosinfo:libosinfo>
77
</metadata>
8-
<memory unit='MiB'>2048</memory>
8+
<memory unit='MiB'>8048</memory>
99
<vcpu>4</vcpu>
1010
<os firmware="efi">
1111
<type arch="x86_64" machine="q35">hvm</type>
@@ -17,7 +17,7 @@
1717
<acpi/>
1818
<apic/>
1919
</features>
20-
<cpu mode="host-passthrough"/>
20+
<cpu mode="host-passthrough" check='none' migratable='on'/>
2121
<clock offset="utc">
2222
<timer name="rtc" tickpolicy="catchup"/>
2323
<timer name="pit" tickpolicy="delay"/>

src/filesystem.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
1-
use log::{debug, error, info};
1+
use log::{debug, info};
22
use nix::mount::{mount, MsFlags};
3-
use std::fs;
4-
5-
fn list_cgroup2_contents() {
6-
match fs::read_dir("/sys/fs/cgroup") {
7-
Ok(entries) => {
8-
info!("Contents of /sys/fs/cgroup:");
9-
for entry in entries.flatten() {
10-
info!(" - {}", entry.file_name().to_string_lossy());
11-
}
12-
}
13-
Err(e) => {
14-
error!("Failed to read /sys/fs/cgroup: {}", e);
15-
}
16-
}
17-
}
3+
use std::fs::{self, File};
4+
use std::io::{Error, Write};
185

196
pub fn mount_virtual_filesystems() {
207
const NONE: Option<&'static [u8]> = None;
@@ -70,5 +57,16 @@ pub fn mount_virtual_filesystems() {
7057
)
7158
.unwrap_or_else(|e| panic!("/sys/fs/cgroup mount failed: {e}"));
7259

73-
list_cgroup2_contents();
60+
enable_ipv6_forwarding().unwrap_or_else(|e| panic!("Failed to enable ipv6 forwarding: {e}"));
61+
}
62+
63+
fn enable_ipv6_forwarding() -> Result<(), Error> {
64+
let forwarding_paths = ["/proc/sys/net/ipv6/conf/all/forwarding"];
65+
66+
for path in forwarding_paths {
67+
let mut file = File::create(path)?;
68+
file.write_all(b"1")?;
69+
}
70+
71+
Ok(())
7472
}

src/isolated_container/mod.rs

Lines changed: 6 additions & 3 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;
@@ -117,7 +119,7 @@ impl IsolatedContainerAPI {
117119
id,
118120
2,
119121
// TODO make configurable through container request
120-
536870912,
122+
4294967296,
121123
vm::BootMode::KernelBoot(vm::KernelBootMode {
122124
kernel: PathBuf::from("/usr/share/feos/vmlinuz"),
123125
initramfs: PathBuf::from("/usr/share/feos/initramfs"),
@@ -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/network/dhcpv6.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ pub fn add_to_ipv6(addr: Ipv6Addr, prefix_length: u8, increment: u128) -> Ipv6Ad
10071007
Ipv6Addr::from(new_addr)
10081008
}
10091009

1010-
async fn _set_ipv6_gateway(
1010+
pub async fn set_ipv6_gateway(
10111011
handle: &Handle,
10121012
interface_name: &str,
10131013
ipv6_gateway: Ipv6Addr,

src/network/utils.rs

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use std::error::Error;
12
use std::io;
23

34
use crate::network::dhcpv6::*;
45
use futures::stream::TryStreamExt;
5-
use log::{info, warn};
6-
use rtnetlink::new_connection;
6+
use log::{debug, info, warn};
7+
use rtnetlink::{new_connection, Handle, IpVersion};
78
use std::net::Ipv6Addr;
89
use tokio::fs::{read_link, OpenOptions};
910
use tokio::io::{AsyncReadExt, AsyncWriteExt};
@@ -20,6 +21,7 @@ use pnet::packet::udp::UdpPacket;
2021
use pnet::packet::Packet;
2122

2223
use netlink_packet_route::neighbour::*;
24+
use netlink_packet_route::route::{RouteAddress, RouteAttribute};
2325

2426
const INTERFACE_NAME: &str = "eth0";
2527

@@ -122,6 +124,13 @@ pub async fn configure_network_devices() -> Result<Option<(Ipv6Addr, u8)>, Strin
122124
} else {
123125
info!("No prefix delegation received.");
124126
}
127+
info!(
128+
"Setting IPv6 gateway to {} on interface {}",
129+
ipv6_gateway, interface_name
130+
);
131+
if let Err(e) = set_ipv6_gateway(&handle, &interface_name, ipv6_gateway).await {
132+
warn!("Failed to set IPv6 gateway: {}", e);
133+
}
125134
}
126135
Err(e) => warn!("Error: {}", e),
127136
}
@@ -148,6 +157,116 @@ pub async fn configure_network_devices() -> Result<Option<(Ipv6Addr, u8)>, Strin
148157
Ok(delegated_prefix_option)
149158
}
150159

160+
// Keep for debugging purposes
161+
async fn _print_ipv6_routes(
162+
handle: &Handle,
163+
iface_index: u32,
164+
interface_name: &str,
165+
) -> Result<(), Box<dyn Error>> {
166+
info!("IPv6 Routes:");
167+
168+
let mut route_ts = handle.route().get(IpVersion::V6).execute();
169+
170+
while let Some(route_msg) = route_ts
171+
.try_next()
172+
.await
173+
.map_err(|e| format!("Could not get route: {}", e))?
174+
{
175+
let mut destination: Option<String> = None;
176+
let mut gateway: Option<String> = None;
177+
let mut oif: Option<u32> = None;
178+
179+
for attr in &route_msg.attributes {
180+
match attr {
181+
RouteAttribute::Oif(oif_idx) => {
182+
oif = Some(*oif_idx);
183+
debug!("Route OIF: {}", oif_idx);
184+
}
185+
186+
RouteAttribute::Destination(dest) => {
187+
match dest {
188+
RouteAddress::Inet6(addr) => {
189+
destination = Some(format!(
190+
"{}/{}",
191+
addr, route_msg.header.destination_prefix_length
192+
));
193+
debug!("Parsed IPv6 Destination: {}", addr);
194+
}
195+
RouteAddress::Other(v) => {
196+
if v.is_empty() {
197+
destination = Some("::/0".to_string());
198+
debug!("Parsed Default Route");
199+
} else {
200+
// Unknown or unsupported address
201+
let hex_str = v
202+
.iter()
203+
.map(|b| format!("{:02x}", b))
204+
.collect::<Vec<String>>()
205+
.join(":");
206+
destination = Some(format!("unknown({})", hex_str));
207+
debug!("Parsed Unknown Destination: {}", hex_str);
208+
}
209+
}
210+
_ => {
211+
debug!("Unhandled Destination variant");
212+
}
213+
}
214+
}
215+
216+
RouteAttribute::Gateway(gw) => {
217+
match gw {
218+
RouteAddress::Inet6(addr) => {
219+
gateway = Some(addr.to_string());
220+
debug!("Parsed IPv6 Gateway: {}", addr);
221+
}
222+
RouteAddress::Other(v) => {
223+
// Some other form of gateway, handle if needed
224+
if v.is_empty() {
225+
debug!("Parsed Empty Gateway");
226+
} else {
227+
let hex_str = v
228+
.iter()
229+
.map(|b| format!("{:02x}", b))
230+
.collect::<Vec<String>>()
231+
.join(":");
232+
gateway = Some(format!("unknown({})", hex_str));
233+
debug!("Parsed Unknown Gateway: {}", hex_str);
234+
}
235+
}
236+
_ => {
237+
debug!("Unhandled Gateway variant");
238+
}
239+
}
240+
}
241+
_ => {}
242+
}
243+
}
244+
245+
if oif != Some(iface_index) {
246+
debug!(
247+
"Skipping route not associated with interface '{}'",
248+
interface_name
249+
);
250+
continue;
251+
}
252+
253+
if route_msg.header.destination_prefix_length == 0 && destination.is_none() {
254+
destination = Some("::/0".to_string());
255+
debug!("Default route detected (no destination attribute)");
256+
}
257+
258+
let dest_str = destination.unwrap_or_else(|| "unknown".to_string());
259+
let mut route_str = dest_str.to_string();
260+
if let Some(gw) = gateway {
261+
route_str.push_str(&format!(" via {}", gw));
262+
}
263+
route_str.push_str(&format!(" dev {}", interface_name));
264+
265+
info!("- {}", route_str);
266+
}
267+
Ok(())
268+
}
269+
151270
fn format_mac(bytes: Vec<u8>) -> String {
152271
bytes
153272
.iter()

0 commit comments

Comments
 (0)