flock-agent: GC orphaned allocations; retry birdc on socket-not-ready (#5)
flock / release (push) Successful in 1m7s
flock / release (push) Successful in 1m7s
flock-agent: GC orphaned allocations; retry birdc on socket-not-ready
This commit was merged in pull request #5.
This commit is contained in:
+40
-8
@@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -137,6 +138,15 @@ func (b *BirdManager) scheduleReload() {
|
||||
})
|
||||
}
|
||||
|
||||
// birdcMaxAttempts and birdcRetryDelay bound the startup-socket retry loop.
|
||||
// BIRD may not have bound its control socket yet when flock-agent first
|
||||
// tries to configure it; 20 × 500 ms = 10 s covers the typical BIRD
|
||||
// startup window without blocking indefinitely.
|
||||
const (
|
||||
birdcMaxAttempts = 20
|
||||
birdcRetryDelay = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
func (b *BirdManager) reload() {
|
||||
birdctl := b.BirdctlPath
|
||||
if birdctl == "" {
|
||||
@@ -146,18 +156,40 @@ func (b *BirdManager) reload() {
|
||||
if socket == "" {
|
||||
socket = "/run/flock/bird.ctl"
|
||||
}
|
||||
cmd := exec.Command(birdctl, "-s", socket, "configure")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
// First-run case: bird may not be ready yet — retry on next change.
|
||||
if errors.Is(err, exec.ErrNotFound) || os.IsNotExist(err) {
|
||||
b.Logger.Warn("birdc not available", "err", err)
|
||||
|
||||
for attempt := 1; attempt <= birdcMaxAttempts; attempt++ {
|
||||
if attempt > 1 {
|
||||
time.Sleep(birdcRetryDelay)
|
||||
}
|
||||
// Socket absent → BIRD hasn't bound it yet; retry.
|
||||
if _, err := os.Stat(socket); os.IsNotExist(err) {
|
||||
b.Logger.Debug("birdc socket not ready, retrying",
|
||||
"attempt", attempt, "socket", socket)
|
||||
continue
|
||||
}
|
||||
cmd := exec.Command(birdctl, "-s", socket, "configure")
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil {
|
||||
b.Logger.Info("birdc configure ok", "out", string(out))
|
||||
return
|
||||
}
|
||||
b.Logger.Warn("birdc reload failed", "err", err, "out", string(out))
|
||||
if errors.Is(err, exec.ErrNotFound) {
|
||||
b.Logger.Warn("birdc not found", "err", err)
|
||||
return
|
||||
}
|
||||
outStr := string(out)
|
||||
// "Unable to connect" means BIRD exists but isn't listening yet.
|
||||
if strings.Contains(outStr, "Unable to connect") {
|
||||
b.Logger.Debug("birdc not ready, retrying",
|
||||
"attempt", attempt, "err", err)
|
||||
continue
|
||||
}
|
||||
// Any other failure (syntax error, etc.) is not retriable.
|
||||
b.Logger.Warn("birdc reload failed", "err", err, "out", outStr)
|
||||
return
|
||||
}
|
||||
b.Logger.Info("birdc configure ok", "out", string(out))
|
||||
b.Logger.Error("birdc configure gave up after retries",
|
||||
"socket", socket, "attempts", birdcMaxAttempts)
|
||||
}
|
||||
|
||||
// SummaryRoutes installs blackhole kernel routes for each NodeConfig CIDR.
|
||||
|
||||
Reference in New Issue
Block a user