libnetwork: open-code updating svc records

Inline the tortured logic for deciding when to skip updating the svc
records to give us a fighting chance at deciphering the logic behind the
logic and spotting logic bugs.

Update the service records synchronously. The only potential for issues
is if this change introduces deadlocks, which should be fixed by
restrucuting the mutexes rather than papering over the issue with
sketchy hacks like deferring the operation to a goroutine.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider 2023-10-17 19:43:12 -04:00
parent 33cf73f699
commit bcca214e36
4 changed files with 19 additions and 40 deletions

View file

@ -12,6 +12,7 @@ import (
"github.com/docker/docker/libnetwork/ipamapi"
"github.com/docker/docker/libnetwork/netlabel"
"github.com/docker/docker/libnetwork/options"
"github.com/docker/docker/libnetwork/scope"
"github.com/docker/docker/libnetwork/types"
)
@ -456,9 +457,10 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) {
}
}()
// Watch for service records
if !n.getController().isAgent() {
n.getController().watchSvcRecord(ep)
if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
n.updateSvcRecord(ep, true)
}
}
// Do not update hosts file with internal networks endpoint IP
@ -803,8 +805,9 @@ func (ep *Endpoint) Delete(force bool) error {
}
}()
// unwatch for service records
n.getController().unWatchSvcRecord(ep)
if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
n.updateSvcRecord(ep, false)
}
if err = ep.deleteEndpoint(force); err != nil && !force {
return err

View file

@ -1225,13 +1225,14 @@ func (n *Network) createEndpoint(name string, options ...EndpointOption) (*Endpo
return nil, err
}
// Watch for service records
n.getController().watchSvcRecord(ep)
defer func() {
if err != nil {
n.getController().unWatchSvcRecord(ep)
}
}()
if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
n.updateSvcRecord(ep, true)
defer func() {
if err != nil {
n.updateSvcRecord(ep, false)
}
}()
}
// Increment endpoint count to indicate completion of endpoint addition
if err = n.getEpCnt().IncEndpointCnt(); err != nil {

View file

@ -278,9 +278,11 @@ func (c *Controller) sandboxCleanup(activeSandboxes map[string]interface{}) erro
}
for _, ep := range sb.endpoints {
// Watch for service records
if !c.isAgent() {
c.watchSvcRecord(ep)
n := ep.getNetwork()
if !c.isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() {
n.updateSvcRecord(ep, true)
}
}
}
}

View file

@ -7,7 +7,6 @@ import (
"github.com/containerd/log"
"github.com/docker/docker/libnetwork/datastore"
"github.com/docker/docker/libnetwork/scope"
)
func (c *Controller) initStores() error {
@ -184,32 +183,6 @@ retry:
return nil
}
func (c *Controller) watchSvcRecord(ep *Endpoint) {
go c.processEndpointCreate(ep)
}
func (c *Controller) unWatchSvcRecord(ep *Endpoint) {
go c.processEndpointDelete(ep)
}
func (c *Controller) processEndpointCreate(ep *Endpoint) {
n := ep.getNetwork()
if c.isSwarmNode() && n.Scope() == scope.Swarm && n.driverIsMultihost() {
return
}
n.updateSvcRecord(ep, true)
}
func (c *Controller) processEndpointDelete(ep *Endpoint) {
n := ep.getNetwork()
if c.isSwarmNode() && n.Scope() == scope.Swarm && n.driverIsMultihost() {
return
}
n.updateSvcRecord(ep, false)
}
func (c *Controller) networkCleanup() {
for _, n := range c.getNetworksFromStore() {
if n.inDelete {