-
Notifications
You must be signed in to change notification settings - Fork 31
Clean vsock sockets after krunkit exit
#104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| use std::path::PathBuf; | ||
| use std::sync::Arc; | ||
|
|
||
| /// Remove each socket file, logging the outcome. Missing files are silently ignored. | ||
| fn remove_sockets(paths: &[PathBuf]) { | ||
| for path in paths { | ||
| match std::fs::remove_file(path) { | ||
| Ok(()) => log::info!("removed vsock socket: {}", path.display()), | ||
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} | ||
| Err(e) => log::warn!("failed to remove vsock socket {}: {}", path.display(), e), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Guard that cleans up vsock socket files when dropped (normal exit) and | ||
| /// also installs a Ctrl-C handler so the sockets are removed on SIGINT. | ||
| pub struct VsockCleanupGuard { | ||
| paths: Arc<Vec<PathBuf>>, | ||
| } | ||
|
|
||
| impl VsockCleanupGuard { | ||
| /// Create the guard **and** register the SIGINT handler. | ||
| pub fn new(paths: Vec<PathBuf>) -> Result<Self, anyhow::Error> { | ||
| let paths = Arc::new(paths); | ||
| let handler_paths = Arc::clone(&paths); | ||
| ctrlc::set_handler(move || { | ||
| remove_sockets(&handler_paths); | ||
| std::process::exit(0); | ||
| })?; | ||
| Ok(Self { paths }) | ||
| } | ||
| } | ||
|
|
||
| impl Drop for VsockCleanupGuard { | ||
| fn drop(&mut self) { | ||
| remove_sockets(&self.paths); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,7 @@ use std::{ | |
| }; | ||
|
|
||
| use crate::timesync::timesync_listener; | ||
| use crate::virtio::{VsockAction, VsockConfig}; | ||
| use crate::virtio::{VirtioDeviceConfig, VsockAction, VsockConfig}; | ||
| use anyhow::{anyhow, Context}; | ||
| use env_logger::{Builder, Env, Target}; | ||
|
|
||
|
|
@@ -202,10 +202,7 @@ impl TryFrom<Args> for KrunContext { | |
| if let Some(timesync_port) = args.timesync { | ||
| let vsock_config = VsockConfig { | ||
| port: timesync_port, | ||
| socket_url: PathBuf::from(format!( | ||
| "/tmp/krunkit_timesync_{}.sock", | ||
| std::process::id() | ||
| )), | ||
| socket_url: Self::timesync_socket_path(), | ||
| action: VsockAction::Connect, | ||
| }; | ||
| unsafe { vsock_config.krun_ctx_set(id)? } | ||
|
|
@@ -217,6 +214,30 @@ impl TryFrom<Args> for KrunContext { | |
| } | ||
|
|
||
| impl KrunContext { | ||
| /// Generate the timesync socket path for this process. | ||
| fn timesync_socket_path() -> PathBuf { | ||
| PathBuf::from(format!( | ||
| "/tmp/krunkit_timesync_{}.sock", | ||
| std::process::id() | ||
| )) | ||
| } | ||
|
|
||
| /// Collect all vsock socket paths that should be cleaned up on exit. | ||
| pub fn vsock_socket_paths(&self) -> Vec<PathBuf> { | ||
| let mut paths = Vec::new(); | ||
| for device in &self.args.devices { | ||
| if let VirtioDeviceConfig::Vsock(vsock) = device { | ||
| if vsock.action == VsockAction::Connect { | ||
| paths.push(vsock.socket_url.clone()); | ||
| } | ||
| } | ||
| } | ||
| if self.args.timesync.is_some() { | ||
| paths.push(Self::timesync_socket_path()); | ||
| } | ||
| paths | ||
| } | ||
|
Comment on lines
+225
to
+239
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for generating the timesync socket path is duplicated here and in the fn timesync_socket_path() -> PathBuf {
PathBuf::from(format!(
"/tmp/krunkit_timesync_{}.sock",
std::process::id()
))
}
/// Collect all vsock socket paths that should be cleaned up on exit.
pub fn vsock_socket_paths(&self) -> Vec<PathBuf> {
let mut paths = Vec::new();
for device in &self.args.devices {
if let VirtioDeviceConfig::Vsock(vsock) = device {
paths.push(vsock.socket_url.clone());
}
}
if self.args.timesync.is_some() {
paths.push(Self::timesync_socket_path());
}
paths
} |
||
|
|
||
| /// Spawn a thread to listen for shutdown requests and run the workload. If behaving properly, | ||
| /// the main thread will never return from this function. | ||
| pub fn run(&self) -> Result<(), anyhow::Error> { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be cautious here of who owns the socket. If the user uses
VsockAction::Connectkrunkit is the one creating the socket file, so we can clean this up.However, if the user uses
VsockAction::Listenthen we're listening to a socket that was created and owned by another process. We shouldn't clean these up.So I think we need to check the vsock action before adding it to the list of paths: