mirror of
https://github.com/michael-yuji/xc.git
synced 2026-03-12 06:04:12 +01:00
bug fixes
This commit is contained in:
@@ -159,6 +159,9 @@ pub(crate) struct CreateArgs {
|
||||
|
||||
#[arg(long = "tun")]
|
||||
pub(crate) tun_ifaces: Vec<String>,
|
||||
|
||||
#[arg(long = "max.children", default_value="0")]
|
||||
pub(crate) max_children: u32
|
||||
}
|
||||
|
||||
impl CreateArgs {
|
||||
@@ -288,6 +291,7 @@ impl CreateArgs {
|
||||
main_ip_selector: self.main_address_selector,
|
||||
tun_interfaces: Some(self.tun_ifaces),
|
||||
tap_interfaces: Some(self.tap_ifaces),
|
||||
children_max: self.max_children,
|
||||
..InstantiateRequest::default()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -406,6 +406,8 @@ impl ProcessRunner {
|
||||
use ipc::proto::write_response;
|
||||
use ipc::transport::PacketTransport;
|
||||
|
||||
debug!(method, "runloop control stream event");
|
||||
|
||||
let packet = if method == "exec" {
|
||||
let jexec = IpcJexec::from_packet_failable(request, |value| {
|
||||
serde_json::from_value(value.clone())
|
||||
@@ -499,7 +501,7 @@ impl ProcessRunner {
|
||||
trace!(
|
||||
pid,
|
||||
ancestor,
|
||||
"NOTE_EXIT: {pid} exited; ancestor: {ancestor}"
|
||||
"NOTE_EXIT"
|
||||
);
|
||||
|
||||
if let Some(pos) = descentdant.iter().position(|x| *x == pid) {
|
||||
@@ -507,7 +509,7 @@ impl ProcessRunner {
|
||||
}
|
||||
let descentdant_gone = descentdant.is_empty();
|
||||
if descentdant_gone {
|
||||
debug!("all descentdant of pid {ancestor} are gone");
|
||||
debug!(ancestor, "all descentdants are gone");
|
||||
}
|
||||
|
||||
if ancestor == pid || descentdant_gone {
|
||||
@@ -515,7 +517,7 @@ impl ProcessRunner {
|
||||
if stat.pid() == ancestor {
|
||||
if ancestor == pid {
|
||||
stat.set_exited(event.data() as i32);
|
||||
info!("exited: {}", event.data());
|
||||
info!(pid, exit_code=event.data(), "pid exited");
|
||||
unsafe {
|
||||
freebsd::nix::libc::waitpid(pid as i32, std::ptr::null_mut(), 0)
|
||||
};
|
||||
@@ -544,6 +546,7 @@ impl ProcessRunner {
|
||||
if descentdant_gone {
|
||||
stat.set_tree_exited();
|
||||
if stat.id() == "main" {
|
||||
info!(id=self.container.id, jid=self.container.jid, "main process exited");
|
||||
self.main_exited = true;
|
||||
self.container.finished_at = Some(epoch_now_nano());
|
||||
if (self.container.deinit_norun || self.deinits.is_empty())
|
||||
@@ -694,14 +697,12 @@ impl ProcessRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.should_kill {
|
||||
break 'kq;
|
||||
}
|
||||
}
|
||||
}
|
||||
EventFilter::EVFILT_USER => {
|
||||
debug!("{event:#?}");
|
||||
if self.container.deinit_norun || self.deinits.is_empty() {
|
||||
// this is a hard kill
|
||||
break 'kq;
|
||||
} else {
|
||||
debug!("activating deinit queue");
|
||||
@@ -772,12 +773,18 @@ pub fn run(
|
||||
auto_start: bool,
|
||||
) -> (i32, Receiver<ContainerManifest>, Receiver<bool>) {
|
||||
let (tx, rx) = channel(container.serialized());
|
||||
let (ltx, lrx) = channel(true);
|
||||
let (ltx, lrx) = channel(false);
|
||||
let (parent, sender) = std::os::unix::net::UnixStream::pair().unwrap();
|
||||
|
||||
if let Ok(fork_result) = unsafe { freebsd::nix::unistd::fork() } {
|
||||
ltx.send_if_modified(|x| {
|
||||
*x = true;
|
||||
true
|
||||
});
|
||||
match fork_result {
|
||||
freebsd::nix::unistd::ForkResult::Child => {
|
||||
let title = std::ffi::CString::new(format!("worker jid={}", container.jid)).unwrap();
|
||||
unsafe { freebsd::libc::setproctitle(title.as_ptr()) };
|
||||
let kq = unsafe { freebsd::nix::libc::kqueue() };
|
||||
let mut pr = ProcessRunner::new(kq, container, auto_start);
|
||||
pr.add_control_stream(ControlStream::new(control_stream));
|
||||
@@ -793,8 +800,11 @@ pub fn run(
|
||||
kevent_classic(kq, &recv_events, &mut []).unwrap();
|
||||
|
||||
let mut control_stream = ControlStream::new(parent);
|
||||
let mut control_stream_closed = false;
|
||||
let mut worker_process_exited = false;
|
||||
|
||||
std::thread::spawn(move || {
|
||||
'kq: loop {
|
||||
while !(control_stream_closed && worker_process_exited) {
|
||||
let nenv = kevent_classic(kq, &[], &mut recv_events).unwrap();
|
||||
let events = &recv_events[..nenv];
|
||||
|
||||
@@ -802,7 +812,7 @@ pub fn run(
|
||||
if event.filter().unwrap() == EventFilter::EVFILT_READ {
|
||||
let bytes = event.data() as usize;
|
||||
if bytes == 0 {
|
||||
break 'kq;
|
||||
control_stream_closed = true;
|
||||
} else {
|
||||
match control_stream.try_get_request(event.data() as usize) {
|
||||
Err(err) => {
|
||||
@@ -823,12 +833,19 @@ pub fn run(
|
||||
}
|
||||
}
|
||||
} else if event.filter().unwrap() == EventFilter::EVFILT_PROC {
|
||||
break 'kq;
|
||||
info!("worker process exited with status {}", event.data());
|
||||
worker_process_exited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("reap worker process");
|
||||
unsafe {
|
||||
freebsd::libc::waitpid(child.as_raw(), core::ptr::null_mut(), 0);
|
||||
}
|
||||
|
||||
ltx.send_if_modified(|x| {
|
||||
*x = true;
|
||||
*x = false;
|
||||
true
|
||||
});
|
||||
});
|
||||
|
||||
@@ -552,6 +552,7 @@ impl ServerContext {
|
||||
site.stage(&applied.image)?;
|
||||
let netgroups = applied.request.netgroups.clone();
|
||||
|
||||
let jailing_datasets = applied.request.jail_datasets.clone();
|
||||
let blueprint =
|
||||
InstantiateBlueprint::new(id, applied, &mut this.devfs_store, &cred, &mut res)?;
|
||||
|
||||
@@ -569,7 +570,16 @@ impl ServerContext {
|
||||
warn!("pf is disabled");
|
||||
}
|
||||
|
||||
site.run_container(blueprint)?;
|
||||
match site.run_container(blueprint) {
|
||||
Ok(_) => (),
|
||||
Err(error) => {
|
||||
for dataset in jailing_datasets.iter() {
|
||||
res.dataset_tracker.unjail(dataset);
|
||||
}
|
||||
return Err(error)
|
||||
}
|
||||
};
|
||||
|
||||
let notify = site.container_notify.clone().unwrap();
|
||||
let jail = site.container_dump().unwrap();
|
||||
let arc_site = Arc::new(RwLock::new(site));
|
||||
|
||||
@@ -587,13 +587,31 @@ impl RootFsRecipe {
|
||||
file.push(digest.digest.as_str());
|
||||
let file_path = file.to_string_lossy().to_string();
|
||||
debug!(file_path, "extracting");
|
||||
_ = tokio::process::Command::new("ocitar")
|
||||
match tokio::process::Command::new("ocitar")
|
||||
.arg("-xf")
|
||||
.arg(&file)
|
||||
.arg("-C")
|
||||
.arg(&root)
|
||||
.status()
|
||||
.await;
|
||||
.await
|
||||
{
|
||||
Ok(status) => {
|
||||
if !status.success() {
|
||||
debug!(
|
||||
file_path,
|
||||
root=root.to_str(),
|
||||
exit_code=status.code(),
|
||||
"failed to extract file to root: ocitar exit with non-zero exit code")
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
debug!(
|
||||
file_path,
|
||||
root=root.to_str(),
|
||||
error=error.to_string(),
|
||||
"failed to extract file to root");
|
||||
}
|
||||
}
|
||||
debug!(file_path, "finished");
|
||||
}
|
||||
handle.snapshot2(target_dataset, "xc")?;
|
||||
|
||||
@@ -144,7 +144,7 @@ impl VolumeDriver for ZfsDriver {
|
||||
|
||||
Ok(Mount {
|
||||
options: Vec::from_iter(mount_options),
|
||||
..Mount::nullfs(&mount_point, &real_dest)
|
||||
..Mount::nullfs(&mount_point, real_dest)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user