From 126477ef884ebdda7cd9dd2b057d622344df051a Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Tue, 22 Aug 2023 03:50:53 +0000 Subject: [PATCH] all: do not depend on vyatta-dhcpd service on EdgeOS The only reason that forces ctrld to depend on vyatta-dhcpd service on EdgeOS is allowing ctrld to watch lease files properly, because those files may not be created at the time client info table initialized. However, on some EdgeOS version, vyatta-dhcpd could not start with an empty config file, causing restart loop itself, flooding systemd log, making the router run out of memory. To fix this, instead of depending on vyatta-dhcpd, we should just watch for lease files creation, then adding them to watch list. While at it, also making ctrld starts after nss-lookup, ensuring we have a working DNS before starting ctrld. --- cmd/cli/prog_linux.go | 6 ++---- internal/clientinfo/dhcp.go | 13 +++++++++++++ internal/router/edgeos/edgeos.go | 7 +++++++ internal/router/router.go | 22 ++++++++-------------- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/cmd/cli/prog_linux.go b/cmd/cli/prog_linux.go index 6f28083..ed28561 100644 --- a/cmd/cli/prog_linux.go +++ b/cmd/cli/prog_linux.go @@ -4,7 +4,6 @@ import ( "github.com/kardianos/service" "github.com/Control-D-Inc/ctrld/internal/dns" - "github.com/Control-D-Inc/ctrld/internal/router" ) func init() { @@ -21,9 +20,8 @@ func setDependencies(svc *service.Config) { "After=NetworkManager-wait-online.service", "Wants=systemd-networkd-wait-online.service", "After=systemd-networkd-wait-online.service", - } - if routerDeps := router.ServiceDependencies(); len(routerDeps) > 0 { - svc.Dependencies = append(svc.Dependencies, routerDeps...) + "Wants=nss-lookup.target", + "After=nss-lookup.target", } } diff --git a/internal/clientinfo/dhcp.go b/internal/clientinfo/dhcp.go index 27e2bf4..a5b6a57 100644 --- a/internal/clientinfo/dhcp.go +++ b/internal/clientinfo/dhcp.go @@ -47,12 +47,25 @@ func (d *dhcp) watchChanges() { if d.watcher == nil { return } + if dir := router.LeaseFilesDir(); dir != "" { + if err := d.watcher.Add(dir); err != nil { + ctrld.ProxyLogger.Load().Err(err).Str("dir", dir).Msg("could not watch lease dir") + } + } for { select { case event, ok := <-d.watcher.Events: if !ok { return } + if event.Has(fsnotify.Create) { + if format, ok := clientInfoFiles[event.Name]; ok { + if err := d.addLeaseFile(event.Name, format); err != nil { + ctrld.ProxyLogger.Load().Err(err).Str("file", event.Name).Msg("could not add lease file") + } + } + continue + } if event.Has(fsnotify.Write) || event.Has(fsnotify.Rename) || event.Has(fsnotify.Chmod) || event.Has(fsnotify.Remove) { format := clientInfoFiles[event.Name] if err := d.readLeaseFile(event.Name, format); err != nil && !os.IsNotExist(err) { diff --git a/internal/router/edgeos/edgeos.go b/internal/router/edgeos/edgeos.go index 014a594..939012c 100644 --- a/internal/router/edgeos/edgeos.go +++ b/internal/router/edgeos/edgeos.go @@ -169,6 +169,13 @@ func ContentFilteringEnabled() bool { return err == nil && !st.IsDir() } +func LeaseFileDir() string { + if checkUSG() { + return "" + } + return "/run" +} + func checkUSG() bool { out, _ := exec.Command("mca-cli-op", "info").Output() return bytes.Contains(out, []byte("UniFi-Gateway-")) diff --git a/internal/router/router.go b/internal/router/router.go index ad3c641..b8a414b 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -173,20 +173,6 @@ func CanListenLocalhost() bool { } } -// ServiceDependencies returns list of dependencies that ctrld services needs on this router. -// See https://pkg.go.dev/github.com/kardianos/service#Config for list format. -func ServiceDependencies() []string { - if Name() == edgeos.Name { - // On EdeOS, ctrld needs to start after vyatta-dhcpd, so it can read leases file. - return []string{ - "Wants=vyatta-dhcpd.service", - "After=vyatta-dhcpd.service", - "Wants=dnsmasq.service", - } - } - return nil -} - // SelfInterfaces return list of *net.Interface that will be source of requests from router itself. func SelfInterfaces() []*net.Interface { switch Name() { @@ -197,6 +183,14 @@ func SelfInterfaces() []*net.Interface { } } +// LeaseFilesDir is the directory which contains lease files. +func LeaseFilesDir() string { + if Name() == edgeos.Name { + edgeos.LeaseFileDir() + } + return "" +} + func distroName() string { switch { case bytes.HasPrefix(unameO(), []byte("DD-WRT")):