cmd/ctrld: only watch config when doing self-check

Avoiding reading/writing global config, causing a data race. While at
it, also guarding read/write access to cfg.Service.AllocateIP field,
since when it is read/write by multiple goroutines.
This commit is contained in:
Cuong Manh Le
2023-03-31 10:12:01 +07:00
committed by Cuong Manh Le
parent 8a56389396
commit f0c604a9f1
2 changed files with 27 additions and 7 deletions
+19 -7
View File
@@ -15,6 +15,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
@@ -508,13 +509,6 @@ func readConfigFile(writeDefaultConfig bool) bool {
if err == nil { if err == nil {
fmt.Println("loading config file from:", v.ConfigFileUsed()) fmt.Println("loading config file from:", v.ConfigFileUsed())
defaultConfigFile = v.ConfigFileUsed() defaultConfigFile = v.ConfigFileUsed()
v.OnConfigChange(func(in fsnotify.Event) {
if err := v.UnmarshalKey("listener", &cfg.Listener); err != nil {
log.Printf("failed to unmarshal listener config: %v", err)
return
}
})
v.WatchConfig()
return true return true
} }
@@ -727,8 +721,26 @@ func selfCheckStatus(status service.Status) service.Status {
err := errors.New("query failed") err := errors.New("query failed")
maxAttempts := 20 maxAttempts := 20
mainLog.Debug().Msg("Performing self-check") mainLog.Debug().Msg("Performing self-check")
var (
lcChanged map[string]*ctrld.ListenerConfig
mu sync.Mutex
)
v.OnConfigChange(func(in fsnotify.Event) {
mu.Lock()
defer mu.Unlock()
if err := v.UnmarshalKey("listener", &lcChanged); err != nil {
log.Printf("failed to unmarshal listener config: %v", err)
return
}
})
v.WatchConfig()
for i := 0; i < maxAttempts; i++ { for i := 0; i < maxAttempts; i++ {
lc := cfg.Listener["0"] lc := cfg.Listener["0"]
mu.Lock()
if lcChanged != nil {
lc = lcChanged["0"]
}
mu.Unlock()
m := new(dns.Msg) m := new(dns.Msg)
m.SetQuestion(selfCheckFQDN+".", dns.TypeA) m.SetQuestion(selfCheckFQDN+".", dns.TypeA)
m.RecursionDesired = true m.RecursionDesired = true
+8
View File
@@ -28,6 +28,8 @@ var svcConfig = &service.Config{
} }
type prog struct { type prog struct {
mu sync.Mutex
cfg *ctrld.Config cfg *ctrld.Config
cache dnscache.Cacher cache dnscache.Cacher
} }
@@ -106,7 +108,9 @@ func (p *prog) run() {
} else { } else {
mainLog.Info().Msg("writing config file to: " + defaultConfigFile) mainLog.Info().Msg("writing config file to: " + defaultConfigFile)
} }
p.mu.Lock()
p.cfg.Service.AllocateIP = true p.cfg.Service.AllocateIP = true
p.mu.Unlock()
p.preRun() p.preRun()
mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port))) mainLog.Info().Msgf("Starting DNS server on listener.%s: %s", listenerNum, net.JoinHostPort(ip, strconv.Itoa(port)))
if err := p.serveDNS(listenerNum); err != nil { if err := p.serveDNS(listenerNum); err != nil {
@@ -132,6 +136,8 @@ func (p *prog) Stop(s service.Service) error {
} }
func (p *prog) allocateIP(ip string) error { func (p *prog) allocateIP(ip string) error {
p.mu.Lock()
defer p.mu.Unlock()
if !p.cfg.Service.AllocateIP { if !p.cfg.Service.AllocateIP {
return nil return nil
} }
@@ -139,6 +145,8 @@ func (p *prog) allocateIP(ip string) error {
} }
func (p *prog) deAllocateIP() error { func (p *prog) deAllocateIP() error {
p.mu.Lock()
defer p.mu.Unlock()
if !p.cfg.Service.AllocateIP { if !p.cfg.Service.AllocateIP {
return nil return nil
} }