[lxc-devel] [lxd/master] main_forkdns: Ensures forkdns remains running when LXD exits
tomponline on Github
lxc-bot at linuxcontainers.org
Tue Jun 11 16:44:04 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 442 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190611/457f27c4/attachment.bin>
-------------- next part --------------
From a98648e58284e817517a2d250e9e0762b447c368 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 11 Jun 2019 17:14:31 +0100
Subject: [PATCH] main_forkdns: Ensures forkdns remains running when LXD exits
Adds double fork to forkdns.
Also adds PID path as first command argument.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/main_forkdns.go | 112 +++++++++++++++++++++++++++++++++++++++++---
lxd/main_nsexec.go | 3 ++
lxd/networks.go | 10 +---
3 files changed, 109 insertions(+), 16 deletions(-)
diff --git a/lxd/main_forkdns.go b/lxd/main_forkdns.go
index 2ac8b0d366..3f11e830ea 100644
--- a/lxd/main_forkdns.go
+++ b/lxd/main_forkdns.go
@@ -20,6 +20,99 @@ import (
"github.com/lxc/lxd/shared/logging"
)
+/*
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+extern char* advance_arg(bool required);
+
+static int wait_for_pid(pid_t pid)
+{
+ int status, ret;
+
+again:
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1) {
+ if (errno == EINTR)
+ goto again;
+ return -1;
+ }
+ if (ret != pid)
+ goto again;
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return -1;
+ return 0;
+}
+
+void forkdns()
+{
+ ssize_t ret;
+ pid_t pid;
+ FILE *pid_file;
+ char *pid_path;
+
+ pid_path = advance_arg(true);
+
+ pid_file = fopen(pid_path, "we+");
+ if (!pid_file) {
+ fprintf(stderr,
+ "%s - Failed to create pid file for forkdns daemon\n",
+ strerror(errno));
+ _exit(EXIT_FAILURE);
+ }
+
+ // daemonize
+ pid = fork();
+ if (pid < 0)
+ _exit(EXIT_FAILURE);
+
+ if (pid != 0) {
+ ret = wait_for_pid(pid);
+ if (ret < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ pid = fork();
+ if (pid < 0)
+ _exit(EXIT_FAILURE);
+
+ if (pid != 0) {
+ ret = fprintf(pid_file, "%d", pid);
+ fclose(pid_file);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to write forkdns daemon pid %d to \"%s\"\n",
+ pid, pid_path);
+ ret = EXIT_FAILURE;
+ }
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ _exit(EXIT_SUCCESS);
+ }
+
+ ret = setsid();
+ if (ret < 0)
+ fprintf(stderr, "%s - Failed to setsid in forkdns daemon\n",
+ strerror(errno));
+}
+*/
+// #cgo CFLAGS: -std=gnu11 -Wvla
+import "C"
+
type cmdForkDNS struct {
global *cmdGlobal
}
@@ -303,7 +396,7 @@ func (h *dnsHandler) getLeaseHostByDNSName(dnsName string) (string, error) {
func (c *cmdForkDNS) Command() *cobra.Command {
// Main subcommand
cmd := &cobra.Command{}
- cmd.Use = "forkdns <listen address> <domain> <network name>"
+ cmd.Use = "forkdns <pid path> <listen address> <domain> <network name>"
cmd.Short = "Internal DNS proxy for clustering"
cmd.Long = `Description:
Spawns a specialised DNS server designed for relaying A and PTR queries that cannot be answered by
@@ -324,7 +417,7 @@ func (c *cmdForkDNS) Command() *cobra.Command {
func (c *cmdForkDNS) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- if len(args) < 3 {
+ if len(args) < 4 {
cmd.Help()
if len(args) == 0 {
@@ -346,24 +439,29 @@ func (c *cmdForkDNS) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Unable to setup fsnotify: %s", err)
}
- networkName := args[2]
- err = watcher.Watch(shared.VarPath("networks", networkName, forkdnsServersListPath))
+ networkName := args[3]
+ path := shared.VarPath("networks", networkName, forkdnsServersListPath)
+ err = watcher.Watch(path)
if err != nil {
- return fmt.Errorf("Unable to setup fsnotify watch: %s", err)
+ return fmt.Errorf("Unable to setup fsnotify watch on %s: %s", path, err)
}
+ os.Stdin.Close()
+ os.Stderr.Close()
+ os.Stdout.Close()
+
// Run the server list monitor concurrently waiting for file changes.
go serversFileMonitor(watcher, networkName)
logger.Info("Started")
srv := &dns.Server{
- Addr: args[0],
+ Addr: args[1],
Net: "udp",
}
srv.Handler = &dnsHandler{
- domain: args[1],
+ domain: args[2],
leaseFile: shared.VarPath("networks", networkName, "dnsmasq.leases"),
}
diff --git a/lxd/main_nsexec.go b/lxd/main_nsexec.go
index 8fa6db708a..69c2d4e6d2 100644
--- a/lxd/main_nsexec.go
+++ b/lxd/main_nsexec.go
@@ -41,6 +41,7 @@ extern void forkfile();
extern void forkmknod();
extern void forkmount();
extern void forknet();
+extern void forkdns();
extern void forkproxy();
extern void forkuevent();
@@ -272,6 +273,8 @@ __attribute__((constructor)) void init(void) {
forkmount();
else if (strcmp(cmdline_cur, "forknet") == 0)
forknet();
+ else if (strcmp(cmdline_cur, "forkdns") == 0)
+ forkdns();
else if (strcmp(cmdline_cur, "forkproxy") == 0)
forkproxy();
else if (strcmp(cmdline_cur, "forkuevent") == 0)
diff --git a/lxd/networks.go b/lxd/networks.go
index b28fecfa93..86412ec629 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -17,7 +17,6 @@ import (
"github.com/gorilla/mux"
log "github.com/lxc/lxd/shared/log15"
"github.com/pkg/errors"
- "golang.org/x/sys/unix"
lxd "github.com/lxc/lxd/client"
"github.com/lxc/lxd/lxd/cluster"
@@ -2088,6 +2087,7 @@ func (n *network) spawnForkDNS(listenAddress string) error {
cmd.Args = []string{
n.state.OS.ExecPath,
"forkdns",
+ shared.VarPath("networks", n.name, "forkdns.pid"),
fmt.Sprintf("%s:1053", listenAddress),
dnsDomain,
n.name,
@@ -2098,14 +2098,6 @@ func (n *network) spawnForkDNS(listenAddress string) error {
return err
}
- // Write the PID file
- pidPath := shared.VarPath("networks", n.name, "forkdns.pid")
- err = ioutil.WriteFile(pidPath, []byte(fmt.Sprintf("%d\n", cmd.Process.Pid)), 0600)
- if err != nil {
- unix.Kill(cmd.Process.Pid, unix.SIGKILL)
- return err
- }
-
return nil
}
More information about the lxc-devel
mailing list