bug fixes

This commit is contained in:
elliptic
2024-02-16 04:32:20 -05:00
parent fbbe26aad1
commit 224b564595
5 changed files with 64 additions and 15 deletions

View File

@@ -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()
})
}

View File

@@ -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
});
});

View File

@@ -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));

View File

@@ -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")?;

View File

@@ -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)
})
}
}