From 1f37fb4d09bde904669d6fcbb223cc4bb58f9e67 Mon Sep 17 00:00:00 2001 From: dr-frmr Date: Tue, 2 Jul 2024 16:46:09 +0200 Subject: [PATCH] fix revoke all behavior, make caps printing on verbosity=3 cleaner --- kinode/src/kernel/mod.rs | 30 +++++++++++++++++---------- kinode/src/kernel/process.rs | 40 +++++++++++++++++------------------- lib/src/core.rs | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 2a1844fa1..34474f693 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -306,7 +306,9 @@ async fn handle_kernel_request( .expect("event loop: fatal: sender died"); None } + // // send 'run' message to a process that's already been initialized + // t::KernelCommand::RunProcess(process_id) => { let response = if let Some(ProcessSender::Userspace(process_sender)) = senders.get(&process_id) { @@ -355,10 +357,14 @@ async fn handle_kernel_request( .await; None } + // + // brutal and savage killing: aborting the task. + // do not do this to a process if you don't want to risk + // dropped messages / un-replied-to-requests + // if you want to immediately restart a process or otherwise + // skip the capabilities-cleanup RevokeAll, pass "no-revoke" in the metadata + // t::KernelCommand::KillProcess(process_id) => { - // brutal and savage killing: aborting the task. - // do not do this to a process if you don't want to risk - // dropped messages / un-replied-to-requests / revoked caps senders.remove(&process_id); let process_handle = match process_handles.remove(&process_id) { Some(ph) => ph, @@ -371,13 +377,15 @@ async fn handle_kernel_request( }; process_handle.abort(); process_map.remove(&process_id); - caps_oracle - .send(t::CapMessage::RevokeAll { - on: process_id.clone(), - responder: None, - }) - .await - .expect("event loop: fatal: sender died"); + if request.metadata != Some("no-revoke".to_string()) { + caps_oracle + .send(t::CapMessage::RevokeAll { + on: process_id.clone(), + responder: None, + }) + .await + .expect("event loop: fatal: sender died"); + } if request.expects_response.is_none() { t::Printout::new(2, format!("kernel: killing process {process_id}")) .send(send_to_terminal) @@ -919,7 +927,7 @@ pub async fn kernel( // capabilities oracle: handles all requests to add, drop, and check capabilities Some(cap_message) = caps_oracle_receiver.recv() => { if print_full_event_loop { - t::Printout::new(3, format!("{cap_message:?}")).send(&send_to_terminal).await; + t::Printout::new(3, format!("{cap_message}")).send(&send_to_terminal).await; } match cap_message { t::CapMessage::Add { on, caps, responder } => { diff --git a/kinode/src/kernel/process.rs b/kinode/src/kernel/process.rs index 63475f3dc..03cfdb7d7 100644 --- a/kinode/src/kernel/process.rs +++ b/kinode/src/kernel/process.rs @@ -334,23 +334,6 @@ pub async fn make_process_loop( // the process has completed, time to perform cleanup // - // get caps before killing - let (tx, rx) = tokio::sync::oneshot::channel(); - caps_oracle - .send(t::CapMessage::GetAll { - on: metadata.our.process.clone(), - responder: tx, - }) - .await?; - let initial_capabilities = rx - .await? - .iter() - .map(|c| t::Capability { - issuer: c.0.issuer.clone(), - params: c.0.params.clone(), - }) - .collect(); - t::Printout::new( 1, format!( @@ -385,7 +368,23 @@ pub async fn make_process_loop( } // if restart, tell ourselves to init the app again, with same capabilities t::OnExit::Restart => { - // kill + // get caps before killing + let (tx, rx) = tokio::sync::oneshot::channel(); + caps_oracle + .send(t::CapMessage::GetAll { + on: metadata.our.process.clone(), + responder: tx, + }) + .await?; + let initial_capabilities = rx + .await? + .iter() + .map(|c| t::Capability { + issuer: c.0.issuer.clone(), + params: c.0.params.clone(), + }) + .collect(); + // kill, **without** revoking capabilities from others! t::KernelMessage::builder() .id(rand::random()) .source((&our.node, KERNEL_PROCESS_ID.clone())) @@ -397,14 +396,14 @@ pub async fn make_process_loop( metadata.our.process.clone(), )) .unwrap(), - metadata: None, + metadata: Some("no-revoke".to_string()), capabilities: vec![], })) .build() .unwrap() .send(&send_to_loop) .await; - // then re-initialize + // then re-initialize with same capabilities t::KernelMessage::builder() .id(rand::random()) .source((&our.node, KERNEL_PROCESS_ID.clone())) @@ -453,7 +452,6 @@ pub async fn make_process_loop( .await; } // if requests, fire them - // even in death, a process can only message processes it has capabilities for t::OnExit::Requests(requests) => { for (address, mut request, blob) in requests { request.expects_response = None; diff --git a/lib/src/core.rs b/lib/src/core.rs index 05e794b6d..1caba025c 100644 --- a/lib/src/core.rs +++ b/lib/src/core.rs @@ -1426,6 +1426,42 @@ pub enum CapMessage { }, } +impl std::fmt::Display for CapMessage { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + CapMessage::Add { on, caps, .. } => write!( + f, + "caps: add {} on {on}", + caps.iter() + .map(|c| c.to_string()) + .collect::>() + .join(", ") + ), + CapMessage::Drop { on, caps, .. } => write!( + f, + "caps: drop {} on {on}", + caps.iter() + .map(|c| c.to_string()) + .collect::>() + .join(", ") + ), + CapMessage::Has { on, cap, .. } => write!(f, "caps: has {} on {on}", cap), + CapMessage::GetAll { on, .. } => write!(f, "caps: get all on {on}"), + CapMessage::RevokeAll { on, .. } => write!(f, "caps: revoke all on {on}"), + CapMessage::FilterCaps { on, caps, .. } => { + write!( + f, + "caps: filter for {} on {on}", + caps.iter() + .map(|c| c.to_string()) + .collect::>() + .join(", ") + ) + } + } + } +} + pub type ReverseCapIndex = HashMap>>; pub type ProcessMap = HashMap;