@@ -4,10 +4,13 @@ import (
44 "context"
55 "errors"
66 "fmt"
7+ "math/rand/v2"
78 "sync"
9+ "time"
810
911 systemdDbus "github.com/coreos/go-systemd/v22/dbus"
1012 dbus "github.com/godbus/dbus/v5"
13+ "golang.org/x/sys/unix"
1114)
1215
1316var (
@@ -64,10 +67,34 @@ func (d *dbusConnManager) getConnection() (*systemdDbus.Conn, error) {
6467}
6568
6669func (d * dbusConnManager ) newConnection () (* systemdDbus.Conn , error ) {
67- if dbusRootless {
68- return newUserSystemdDbus ()
70+ newDbusConn := func () (* systemdDbus.Conn , error ) {
71+ if dbusRootless {
72+ return newUserSystemdDbus ()
73+ }
74+ return systemdDbus .NewWithContext (context .TODO ())
75+ }
76+
77+ var conn * systemdDbus.Conn
78+ var err error
79+ for retry := range 5 {
80+ conn , err = newDbusConn ()
81+ if err == nil {
82+ break
83+ }
84+ if ! errors .Is (err , unix .EAGAIN ) {
85+ return nil , err
86+ }
87+ if retry < 4 {
88+ // Exponential backoff with jitter: base delay doubles each retry, plus random jitter up to 1 second
89+ baseDelay := time .Second << retry // 1s, 2s, 4s, 8s
90+ jitter := time .Duration (rand .IntN (1000 )) * time .Millisecond
91+ time .Sleep (baseDelay + jitter )
92+ } else {
93+ // despite retries, still EAGAIN
94+ return nil , fmt .Errorf ("dbus connection failed after 5 retries: %w" , err )
95+ }
6996 }
70- return systemdDbus . NewWithContext ( context . TODO ())
97+ return conn , nil
7198}
7299
73100// resetConnection resets the connection to its initial state
0 commit comments