mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
main: Enable the api-socket to be passed as an fd
To avoid race issues where the api-socket may not be created by the time a cloud-hypervisor caller is ready to look for it, enable the caller to pass the api-socket fd directly. Avoid breaking current callers by allowing the --api-socket path to be passed as it is now in addition to through the path argument. Signed-off-by: William Douglas <william.r.douglas@gmail.com>
This commit is contained in:
55
src/main.rs
55
src/main.rs
@@ -25,7 +25,7 @@ use signal_hook::{
|
||||
};
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::FromRawFd;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::sync::mpsc::channel;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
@@ -62,6 +62,8 @@ enum Error {
|
||||
ThreadJoin(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||
#[error("VMM thread exited with error: {0}")]
|
||||
VmmThread(#[source] vmm::Error),
|
||||
#[error("Error parsing --api-socket: {0}")]
|
||||
ParsingApiSocket(std::num::ParseIntError),
|
||||
#[error("Error parsing --event-monitor: {0}")]
|
||||
ParsingEventMonitor(option_parser::OptionParserError),
|
||||
#[error("Error parsing --event-monitor: path or fd required")]
|
||||
@@ -324,7 +326,7 @@ fn create_app<'a, 'b>(
|
||||
.arg(
|
||||
Arg::with_name("api-socket")
|
||||
.long("api-socket")
|
||||
.help("HTTP API socket path (UNIX domain socket).")
|
||||
.help("HTTP API socket (UNIX domain socket): path=</path/to/a/file> or fd=<fd>.")
|
||||
.takes_value(true)
|
||||
.min_values(1)
|
||||
.group("vmm-config"),
|
||||
@@ -379,7 +381,7 @@ fn create_app<'a, 'b>(
|
||||
app
|
||||
}
|
||||
|
||||
fn start_vmm(cmd_arguments: ArgMatches, api_socket_path: &Option<String>) -> Result<(), Error> {
|
||||
fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
||||
let log_level = match cmd_arguments.occurrences_of("v") {
|
||||
0 => LevelFilter::Warn,
|
||||
1 => LevelFilter::Info,
|
||||
@@ -402,6 +404,29 @@ fn start_vmm(cmd_arguments: ArgMatches, api_socket_path: &Option<String>) -> Res
|
||||
.map(|()| log::set_max_level(log_level))
|
||||
.map_err(Error::LoggerSetup)?;
|
||||
|
||||
let (api_socket_path, api_socket_fd) =
|
||||
if let Some(socket_config) = cmd_arguments.value_of("api-socket") {
|
||||
let mut parser = OptionParser::new();
|
||||
parser.add("path").add("fd");
|
||||
parser.parse(socket_config).unwrap_or_default();
|
||||
|
||||
if let Some(fd) = parser.get("fd") {
|
||||
(
|
||||
None,
|
||||
Some(fd.parse::<RawFd>().map_err(Error::ParsingApiSocket)?),
|
||||
)
|
||||
} else if let Some(path) = parser.get("path") {
|
||||
(Some(path), None)
|
||||
} else {
|
||||
(
|
||||
cmd_arguments.value_of("api-socket").map(|s| s.to_string()),
|
||||
None,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
if let Some(monitor_config) = cmd_arguments.value_of("event-monitor") {
|
||||
let mut parser = OptionParser::new();
|
||||
parser.add("path").add("fd");
|
||||
@@ -474,7 +499,8 @@ fn start_vmm(cmd_arguments: ArgMatches, api_socket_path: &Option<String>) -> Res
|
||||
let hypervisor = hypervisor::new().map_err(Error::CreateHypervisor)?;
|
||||
let vmm_thread = vmm::start_vmm_thread(
|
||||
env!("CARGO_PKG_VERSION").to_string(),
|
||||
api_socket_path,
|
||||
&api_socket_path,
|
||||
api_socket_fd,
|
||||
api_evt.try_clone().unwrap(),
|
||||
http_sender,
|
||||
api_request_receiver,
|
||||
@@ -510,7 +536,9 @@ fn start_vmm(cmd_arguments: ArgMatches, api_socket_path: &Option<String>) -> Res
|
||||
vmm_thread
|
||||
.join()
|
||||
.map_err(Error::ThreadJoin)?
|
||||
.map_err(Error::VmmThread)
|
||||
.map_err(Error::VmmThread)?;
|
||||
|
||||
Ok(api_socket_path)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -519,16 +547,17 @@ fn main() {
|
||||
|
||||
let (default_vcpus, default_memory, default_rng) = prepare_default_values();
|
||||
let cmd_arguments = create_app(&default_vcpus, &default_memory, &default_rng).get_matches();
|
||||
let api_socket_path = cmd_arguments.value_of("api-socket").map(|s| s.to_string());
|
||||
|
||||
let exit_code = if let Err(e) = start_vmm(cmd_arguments, &api_socket_path) {
|
||||
eprintln!("{}", e);
|
||||
1
|
||||
} else {
|
||||
0
|
||||
let exit_code = match start_vmm(cmd_arguments) {
|
||||
Ok(path) => {
|
||||
path.map(|s| std::fs::remove_file(s).ok());
|
||||
0
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
1
|
||||
}
|
||||
};
|
||||
|
||||
api_socket_path.map(|s| std::fs::remove_file(s).ok());
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user