tools: implement ReexecContinue for tokio's TcpListener
This is the only thing we currently need to keep alive for reloads. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
4422ba2c7f
commit
af70c1811b
|
@ -1,12 +1,14 @@
|
||||||
//! Helpers for daemons/services.
|
//! Helpers for daemons/services.
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::panic::UnwindSafe;
|
use std::panic::UnwindSafe;
|
||||||
|
|
||||||
use failure::*;
|
use failure::*;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
|
|
||||||
|
use crate::tools::fd_change_cloexec;
|
||||||
use crate::tools::signalfd::{SigSet, SignalFd};
|
use crate::tools::signalfd::{SigSet, SignalFd};
|
||||||
|
|
||||||
// Unfortunately FnBox is nightly-only and Box<FnOnce> is unusable, so just use Box<Fn>...
|
// Unfortunately FnBox is nightly-only and Box<FnOnce> is unusable, so just use Box<Fn>...
|
||||||
|
@ -168,3 +170,28 @@ where
|
||||||
.and_then(|si_res| si_res)
|
.and_then(|si_res| si_res)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For now all we need to do is store and reuse a tcp listening socket:
|
||||||
|
impl ReexecContinue for tokio::net::TcpListener {
|
||||||
|
// NOTE: The socket must not be closed when the store-function is called:
|
||||||
|
// 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()?)
|
||||||
|
fn get_store_func(&self) -> BoxedStoreFunc {
|
||||||
|
let fd = self.as_raw_fd();
|
||||||
|
Box::new(move || {
|
||||||
|
fd_change_cloexec(fd, false)?;
|
||||||
|
Ok(fd.to_string())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore(var: &str) -> Result<Self, Error> {
|
||||||
|
let fd = var.parse::<u32>()
|
||||||
|
.map_err(|e| format_err!("invalid file descriptor: {}", e))?
|
||||||
|
as RawFd;
|
||||||
|
fd_change_cloexec(fd, true)?;
|
||||||
|
Ok(Self::from_std(
|
||||||
|
unsafe { std::net::TcpListener::from_raw_fd(fd) },
|
||||||
|
&tokio::reactor::Handle::default(),
|
||||||
|
)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue