Skip to content

Commit

Permalink
main: run aardvark as a daemon via forking
Browse files Browse the repository at this point in the history
This is one the redesign PR for aardvark-dns and netavark. Design
proposes that  forking will happen at aardvark-end instead of
netavark and aardvark will verify if servers are up before parent goes
away.

Redesign proposal

* Aardvark will invoke server on the child process by  forking.
* Parent waits for child to show up  and verify against a dummy DNS
  query to check if server is running.
* Exit parent on success and deatch child.

* Calling process will wait for aardvark's parent process to return.
* On successful return from parent it will be assumed that aardvark is
  running properly

One new design is implemented and merged and netavark starts using this
it should close

* containers/podman#14173
* containers/podman#14171

Signed-off-by: Aditya R <[email protected]>
  • Loading branch information
flouthoc committed Jul 13, 2022
1 parent c3403f6 commit 631a2b6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 11 deletions.
30 changes: 30 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ signal-hook = "0.3.13"
tokio = { version = "1.19.2", features = ["tokio-macros", "full"] }
async-broadcast = "0.4.0"
resolv-conf = "0.7.0"
nix = "0.23.0"
libc = "0.2"

[build-dependencies]
chrono = "0.4.7"
74 changes: 63 additions & 11 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
//! Runs the aardvark dns server with provided config
use crate::server::serve;
use clap::Parser;
use log::debug;
use nix::unistd;
use nix::unistd::{dup2, fork, ForkResult};
use std::fs::File;
use std::fs::OpenOptions;
use std::io::Error;
use std::io::Write;
use std::os::unix::io::AsRawFd;
use std::os::unix::io::FromRawFd;

#[derive(Parser, Debug)]
pub struct Run {}
Expand All @@ -19,18 +25,64 @@ impl Run {
port: u32,
filter_search_domain: String,
) -> Result<(), Error> {
debug!(
"Setting up aardvark server with input directory as {:?}",
input_dir
);
// create a temporary path for unix socket
// so parent can communicate with child and
// only exit when child is ready to serve.
let (ready_pipe_read, ready_pipe_write) = nix::unistd::pipe()?;

if let Err(er) = serve::serve(&input_dir, port, &filter_search_domain) {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Error starting server {}", er),
));
// fork and verify if server is running
// and exit parent
// setsid() ensures that there is no controlling terminal on the child process
match unsafe { fork() } {
Ok(ForkResult::Parent { child, .. }) => {
log::debug!("starting aardvark on a child with pid {}", child);
// verify aardvark here and block till will start
unistd::read(ready_pipe_read, &mut [0_u8; 1])?;
unistd::close(ready_pipe_read)?;
unistd::close(ready_pipe_write)?;
Ok(())
}
Ok(ForkResult::Child) => {
// remove any controlling terminals
// but don't hardstop if this fails
let _ = unsafe { libc::setsid() }; // check https://docs.rs/libc
// close fds -> stdout, stdin and stderr
let dev_null = OpenOptions::new()
.read(true)
.write(true)
.open("/dev/null")
.map_err(|e| std::io::Error::new(e.kind(), format!("/dev/null: {}", e)));
// redirect stdout, stdin and stderr to /dev/null
if let Ok(dev_null) = dev_null {
let fd = dev_null.as_raw_fd();
let _ = dup2(fd, 0);
let _ = dup2(fd, 1);
let _ = dup2(fd, 2);
if fd < 2 {
std::mem::forget(dev_null);
}
}

let mut f = unsafe { File::from_raw_fd(ready_pipe_write) };
write!(&mut f, "ready")?;
unistd::close(ready_pipe_read)?;
unistd::close(ready_pipe_write)?;
if let Err(er) = serve::serve(&input_dir, port, &filter_search_domain) {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Error starting server {}", er),
));
}
Ok(())
}
Err(err) => {
log::debug!("fork failed with error {}", err);
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("fork failed with error: {}", err),
));
}
}
Ok(())
}
}

Expand Down

0 comments on commit 631a2b6

Please sign in to comment.