move src/tools/daemon.rs to proxmox-rest-server workspace

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Dietmar Maurer 2021-09-21 07:58:41 +02:00 committed by Thomas Lamprecht
parent ca7a26166f
commit 51d84f9847
3 changed files with 38 additions and 7 deletions

View File

@ -13,6 +13,7 @@ http = "0.2"
hyper = { version = "0.14", features = [ "full" ] } hyper = { version = "0.14", features = [ "full" ] }
lazy_static = "1.4" lazy_static = "1.4"
libc = "0.2" libc = "0.2"
log = "0.4"
nix = "0.19.1" nix = "0.19.1"
serde = { version = "1.0", features = [] } serde = { version = "1.0", features = [] }
serde_json = "1.0" serde_json = "1.0"

View File

@ -15,8 +15,9 @@ use anyhow::{bail, format_err, Error};
use futures::future::{self, Either}; use futures::future::{self, Either};
use proxmox::tools::io::{ReadExt, WriteExt}; use proxmox::tools::io::{ReadExt, WriteExt};
use proxmox::tools::fd::Fd;
use crate::tools::{fd_change_cloexec, self}; use crate::fd_change_cloexec;
#[link(name = "systemd")] #[link(name = "systemd")]
extern "C" { extern "C" {
@ -218,7 +219,7 @@ impl Reloadable for tokio::net::TcpListener {
// FIXME: We could become "independent" of the TcpListener and its reference to the file // FIXME: We could become "independent" of the TcpListener and its reference to the file
// descriptor by `dup()`ing it (and check if the listener still exists via kcmp()?) // descriptor by `dup()`ing it (and check if the listener still exists via kcmp()?)
fn get_store_func(&self) -> Result<BoxedStoreFunc, Error> { fn get_store_func(&self) -> Result<BoxedStoreFunc, Error> {
let mut fd_opt = Some(tools::Fd( let mut fd_opt = Some(Fd(
nix::fcntl::fcntl(self.as_raw_fd(), nix::fcntl::FcntlArg::F_DUPFD_CLOEXEC(0))? nix::fcntl::fcntl(self.as_raw_fd(), nix::fcntl::FcntlArg::F_DUPFD_CLOEXEC(0))?
)); ));
Ok(Box::new(move || { Ok(Box::new(move || {
@ -273,11 +274,11 @@ where
).await?; ).await?;
let server_future = create_service(listener, NotifyReady)?; let server_future = create_service(listener, NotifyReady)?;
let shutdown_future = proxmox_rest_server::shutdown_future(); let shutdown_future = crate::shutdown_future();
let finish_future = match future::select(server_future, shutdown_future).await { let finish_future = match future::select(server_future, shutdown_future).await {
Either::Left((_, _)) => { Either::Left((_, _)) => {
proxmox_rest_server::request_shutdown(); // make sure we are in shutdown mode crate::request_shutdown(); // make sure we are in shutdown mode
None None
} }
Either::Right((_, server_future)) => Some(server_future), Either::Right((_, server_future)) => Some(server_future),
@ -285,7 +286,7 @@ where
let mut reloader = Some(reloader); let mut reloader = Some(reloader);
if proxmox_rest_server::is_reload_request() { if crate::is_reload_request() {
log::info!("daemon reload..."); log::info!("daemon reload...");
if let Err(e) = systemd_notify(SystemdNotify::Reloading) { if let Err(e) = systemd_notify(SystemdNotify::Reloading) {
log::error!("failed to notify systemd about the state change: {}", e); log::error!("failed to notify systemd about the state change: {}", e);
@ -304,7 +305,7 @@ where
} }
// FIXME: this is a hack, replace with sd_notify_barrier when available // FIXME: this is a hack, replace with sd_notify_barrier when available
if proxmox_rest_server::is_reload_request() { if crate::is_reload_request() {
wait_service_is_not_state(service_name, "reloading").await?; wait_service_is_not_state(service_name, "reloading").await?;
} }

View File

@ -1,4 +1,10 @@
use anyhow::{bail, Error}; use std::os::unix::io::RawFd;
use anyhow::{bail, format_err, Error};
use proxmox::tools::fd::Fd;
pub mod daemon;
mod state; mod state;
pub use state::*; pub use state::*;
@ -52,3 +58,26 @@ pub fn fail_on_shutdown() -> Result<(), Error> {
Ok(()) Ok(())
} }
/// Helper to set/clear the FD_CLOEXEC flag on file descriptors
pub fn fd_change_cloexec(fd: RawFd, on: bool) -> Result<(), Error> {
use nix::fcntl::{fcntl, FdFlag, F_GETFD, F_SETFD};
let mut flags = FdFlag::from_bits(fcntl(fd, F_GETFD)?)
.ok_or_else(|| format_err!("unhandled file flags"))?; // nix crate is stupid this way...
flags.set(FdFlag::FD_CLOEXEC, on);
fcntl(fd, F_SETFD(flags))?;
Ok(())
}
/// safe wrapper for `nix::sys::socket::socketpair` defaulting to `O_CLOEXEC` and guarding the file
/// descriptors.
pub fn socketpair() -> Result<(Fd, Fd), Error> {
use nix::sys::socket;
let (pa, pb) = socket::socketpair(
socket::AddressFamily::Unix,
socket::SockType::Stream,
None,
socket::SockFlag::SOCK_CLOEXEC,
)?;
Ok((Fd(pa), Fd(pb)))
}