Compare commits

...

2 Commits

Author SHA1 Message Date
d469da4d9b chore: release (#303)
Co-authored-by: edera-cultivation[bot] <165992271+edera-cultivation[bot]@users.noreply.github.com>
2024-08-06 01:57:25 +00:00
99091df3cf fix(zone): waitpid should be limited when no child processes exist (fixes #304) (#305) 2024-08-05 18:48:30 -07:00
13 changed files with 71 additions and 53 deletions

View File

@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.0.15](https://github.com/edera-dev/krata/compare/v0.0.14...v0.0.15) - 2024-08-06
### Fixed
- *(zone)* waitpid should be limited when no child processes exist (fixes [#304](https://github.com/edera-dev/krata/pull/304)) ([#305](https://github.com/edera-dev/krata/pull/305))
## [0.0.14](https://github.com/edera-dev/krata/compare/v0.0.13...v0.0.14) - 2024-08-06 ## [0.0.14](https://github.com/edera-dev/krata/compare/v0.0.13...v0.0.14) - 2024-08-06
### Added ### Added

30
Cargo.lock generated
View File

@ -1281,7 +1281,7 @@ dependencies = [
[[package]] [[package]]
name = "krata" name = "krata"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1321,7 +1321,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-buildtools" name = "krata-buildtools"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"env_logger", "env_logger",
@ -1336,7 +1336,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-ctl" name = "krata-ctl"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1366,7 +1366,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-daemon" name = "krata-daemon"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1395,14 +1395,14 @@ dependencies = [
[[package]] [[package]]
name = "krata-loopdev" name = "krata-loopdev"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "krata-network" name = "krata-network"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1426,7 +1426,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-oci" name = "krata-oci"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-compression", "async-compression",
@ -1453,7 +1453,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-runtime" name = "krata-runtime"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"backhand", "backhand",
@ -1494,7 +1494,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xencall" name = "krata-xencall"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"env_logger", "env_logger",
"libc", "libc",
@ -1507,7 +1507,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenclient" name = "krata-xenclient"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"env_logger", "env_logger",
@ -1525,7 +1525,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenevtchn" name = "krata-xenevtchn"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@ -1536,7 +1536,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xengnt" name = "krata-xengnt"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"libc", "libc",
"nix 0.29.0", "nix 0.29.0",
@ -1545,7 +1545,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenplatform" name = "krata-xenplatform"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"c2rust-bitfields", "c2rust-bitfields",
@ -1568,7 +1568,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenstore" name = "krata-xenstore"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"env_logger", "env_logger",
@ -1580,7 +1580,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-zone" name = "krata-zone"
version = "0.0.14" version = "0.0.15"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cgroups-rs", "cgroups-rs",

View File

@ -18,7 +18,7 @@ members = [
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
version = "0.0.14" version = "0.0.15"
homepage = "https://krata.dev" homepage = "https://krata.dev"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/edera-dev/krata" repository = "https://github.com/edera-dev/krata"

View File

@ -16,7 +16,7 @@ oci-spec = { workspace = true }
scopeguard = { workspace = true } scopeguard = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tokio-stream = { workspace = true } tokio-stream = { workspace = true }
krata-oci = { path = "../oci", version = "^0.0.14" } krata-oci = { path = "../oci", version = "^0.0.15" }
krata-tokio-tar = { workspace = true } krata-tokio-tar = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }

View File

@ -20,7 +20,7 @@ env_logger = { workspace = true }
fancy-duration = { workspace = true } fancy-duration = { workspace = true }
human_bytes = { workspace = true } human_bytes = { workspace = true }
indicatif = { workspace = true } indicatif = { workspace = true }
krata = { path = "../krata", version = "^0.0.14" } krata = { path = "../krata", version = "^0.0.15" }
log = { workspace = true } log = { workspace = true }
prost-reflect = { workspace = true, features = ["serde"] } prost-reflect = { workspace = true, features = ["serde"] }
prost-types = { workspace = true } prost-types = { workspace = true }

View File

@ -17,9 +17,9 @@ circular-buffer = { workspace = true }
clap = { workspace = true } clap = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
krata = { path = "../krata", version = "^0.0.14" } krata = { path = "../krata", version = "^0.0.15" }
krata-oci = { path = "../oci", version = "^0.0.14" } krata-oci = { path = "../oci", version = "^0.0.15" }
krata-runtime = { path = "../runtime", version = "^0.0.14" } krata-runtime = { path = "../runtime", version = "^0.0.15" }
log = { workspace = true } log = { workspace = true }
prost = { workspace = true } prost = { workspace = true }
redb = { workspace = true } redb = { workspace = true }

View File

@ -16,7 +16,7 @@ clap = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
etherparse = { workspace = true } etherparse = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
krata = { path = "../krata", version = "^0.0.14" } krata = { path = "../krata", version = "^0.0.15" }
krata-advmac = { workspace = true } krata-advmac = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }

View File

@ -12,20 +12,20 @@ resolver = "2"
anyhow = { workspace = true } anyhow = { workspace = true }
backhand = { workspace = true } backhand = { workspace = true }
ipnetwork = { workspace = true } ipnetwork = { workspace = true }
krata = { path = "../krata", version = "^0.0.14" } krata = { path = "../krata", version = "^0.0.15" }
krata-advmac = { workspace = true } krata-advmac = { workspace = true }
krata-oci = { path = "../oci", version = "^0.0.14" } krata-oci = { path = "../oci", version = "^0.0.15" }
log = { workspace = true } log = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
krata-loopdev = { path = "../loopdev", version = "^0.0.14" } krata-loopdev = { path = "../loopdev", version = "^0.0.15" }
krata-xencall = { path = "../xen/xencall", version = "^0.0.14" } krata-xencall = { path = "../xen/xencall", version = "^0.0.15" }
krata-xenclient = { path = "../xen/xenclient", version = "^0.0.14" } krata-xenclient = { path = "../xen/xenclient", version = "^0.0.15" }
krata-xenevtchn = { path = "../xen/xenevtchn", version = "^0.0.14" } krata-xenevtchn = { path = "../xen/xenevtchn", version = "^0.0.15" }
krata-xengnt = { path = "../xen/xengnt", version = "^0.0.14" } krata-xengnt = { path = "../xen/xengnt", version = "^0.0.15" }
krata-xenplatform = { path = "../xen/xenplatform", version = "^0.0.14" } krata-xenplatform = { path = "../xen/xenplatform", version = "^0.0.15" }
krata-xenstore = { path = "../xen/xenstore", version = "^0.0.14" } krata-xenstore = { path = "../xen/xenstore", version = "^0.0.15" }
walkdir = { workspace = true } walkdir = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }

View File

@ -13,9 +13,9 @@ async-trait = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
krata-xencall = { path = "../xencall", version = "^0.0.14" } krata-xencall = { path = "../xencall", version = "^0.0.15" }
krata-xenplatform = { path = "../xenplatform", version = "^0.0.14" } krata-xenplatform = { path = "../xenplatform", version = "^0.0.15" }
krata-xenstore = { path = "../xenstore", version = "^0.0.14" } krata-xenstore = { path = "../xenstore", version = "^0.0.15" }
regex = { workspace = true } regex = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }

View File

@ -16,7 +16,7 @@ flate2 = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
krata-xencall = { path = "../xencall", version = "^0.0.14" } krata-xencall = { path = "../xencall", version = "^0.0.15" }
memchr = { workspace = true } memchr = { workspace = true }
nix = { workspace = true } nix = { workspace = true }
regex = { workspace = true } regex = { workspace = true }

View File

@ -14,8 +14,8 @@ cgroups-rs = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
ipnetwork = { workspace = true } ipnetwork = { workspace = true }
krata = { path = "../krata", version = "^0.0.14" } krata = { path = "../krata", version = "^0.0.15" }
krata-xenstore = { path = "../xen/xenstore", version = "^0.0.14" } krata-xenstore = { path = "../xen/xenstore", version = "^0.0.15" }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
nix = { workspace = true, features = ["ioctl", "process", "fs"] } nix = { workspace = true, features = ["ioctl", "process", "fs"] }

View File

@ -16,6 +16,7 @@ use krata::idm::{
}; };
use log::debug; use log::debug;
use nix::unistd::Pid; use nix::unistd::Pid;
use tokio::sync::broadcast::Receiver;
use tokio::{select, sync::broadcast}; use tokio::{select, sync::broadcast};
pub struct ZoneBackground { pub struct ZoneBackground {
@ -23,15 +24,18 @@ pub struct ZoneBackground {
child: Pid, child: Pid,
_cgroup: Cgroup, _cgroup: Cgroup,
wait: ChildWait, wait: ChildWait,
child_receiver: Receiver<ChildEvent>,
} }
impl ZoneBackground { impl ZoneBackground {
pub async fn new(idm: IdmInternalClient, cgroup: Cgroup, child: Pid) -> Result<ZoneBackground> { pub async fn new(idm: IdmInternalClient, cgroup: Cgroup, child: Pid) -> Result<ZoneBackground> {
let (wait, child_receiver) = ChildWait::new()?;
Ok(ZoneBackground { Ok(ZoneBackground {
idm, idm,
child, child,
_cgroup: cgroup, _cgroup: cgroup,
wait: ChildWait::new()?, wait,
child_receiver,
}) })
} }
@ -39,7 +43,6 @@ impl ZoneBackground {
let mut event_subscription = self.idm.subscribe().await?; let mut event_subscription = self.idm.subscribe().await?;
let mut requests_subscription = self.idm.requests().await?; let mut requests_subscription = self.idm.requests().await?;
let mut request_streams_subscription = self.idm.request_streams().await?; let mut request_streams_subscription = self.idm.request_streams().await?;
let mut wait_subscription = self.wait.subscribe().await?;
loop { loop {
select! { select! {
x = event_subscription.recv() => match x { x = event_subscription.recv() => match x {
@ -86,7 +89,7 @@ impl ZoneBackground {
} }
}, },
event = wait_subscription.recv() => match event { event = self.child_receiver.recv() => match event {
Ok(event) => self.child_event(event).await?, Ok(event) => self.child_event(event).await?,
Err(_) => { Err(_) => {
break; break;

View File

@ -1,3 +1,9 @@
use anyhow::Result;
use libc::{c_int, waitpid, WEXITSTATUS, WIFEXITED};
use log::warn;
use nix::unistd::Pid;
use std::thread::sleep;
use std::time::Duration;
use std::{ use std::{
ptr::addr_of_mut, ptr::addr_of_mut,
sync::{ sync::{
@ -6,11 +12,6 @@ use std::{
}, },
thread::{self, JoinHandle}, thread::{self, JoinHandle},
}; };
use anyhow::Result;
use libc::{c_int, waitpid, WEXITSTATUS, WIFEXITED};
use log::warn;
use nix::unistd::Pid;
use tokio::sync::broadcast::{channel, Receiver, Sender}; use tokio::sync::broadcast::{channel, Receiver, Sender};
const CHILD_WAIT_QUEUE_LEN: usize = 10; const CHILD_WAIT_QUEUE_LEN: usize = 10;
@ -29,8 +30,8 @@ pub struct ChildWait {
} }
impl ChildWait { impl ChildWait {
pub fn new() -> Result<ChildWait> { pub fn new() -> Result<(ChildWait, Receiver<ChildEvent>)> {
let (sender, _) = channel(CHILD_WAIT_QUEUE_LEN); let (sender, receiver) = channel(CHILD_WAIT_QUEUE_LEN);
let signal = Arc::new(AtomicBool::new(false)); let signal = Arc::new(AtomicBool::new(false));
let mut processor = ChildWaitTask { let mut processor = ChildWaitTask {
sender: sender.clone(), sender: sender.clone(),
@ -41,11 +42,14 @@ impl ChildWait {
warn!("failed to process child updates: {}", error); warn!("failed to process child updates: {}", error);
} }
}); });
Ok(ChildWait { Ok((
sender, ChildWait {
signal, sender,
_task: Arc::new(task), signal,
}) _task: Arc::new(task),
},
receiver,
))
} }
pub async fn subscribe(&self) -> Result<Receiver<ChildEvent>> { pub async fn subscribe(&self) -> Result<Receiver<ChildEvent>> {
@ -63,7 +67,13 @@ impl ChildWaitTask {
loop { loop {
let mut status: c_int = 0; let mut status: c_int = 0;
let pid = unsafe { waitpid(-1, addr_of_mut!(status), 0) }; let pid = unsafe { waitpid(-1, addr_of_mut!(status), 0) };
// pid being -1 indicates an error occurred, wait 100 microseconds to avoid
// overloading the channel. Right now we don't consider any other errors
// but that is fine for now, as waitpid shouldn't ever stop anyway.
if pid == -1 {
sleep(Duration::from_micros(100));
continue;
}
if WIFEXITED(status) { if WIFEXITED(status) {
let event = ChildEvent { let event = ChildEvent {
pid: Pid::from_raw(pid), pid: Pid::from_raw(pid),