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:
		@ -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(),
 | 
				
			||||||
 | 
					        )?)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user