diff --git a/ipam/claim.go b/ipam/claim.go index c4a5529e..02ba251e 100644 --- a/ipam/claim.go +++ b/ipam/claim.go @@ -12,6 +12,7 @@ import ( type claim struct { resultChan chan<- error + tryCount int ident string // a container ID, something like "weave:expose", or api.NoContainerID cidr address.CIDR // single address being claimed isContainer bool // true if ident is a container ID @@ -19,6 +20,8 @@ type claim struct { hasBeenCancelled func() bool } +const maxTryCount = 5 + // Send an error (or nil for success) back to caller listening on resultChan func (c *claim) sendResult(result error) { // Make sure we only send a result once, since listener stops listening after that @@ -40,6 +43,8 @@ func (c *claim) Try(alloc *Allocator) bool { return true } + c.tryCount++ + addOwned := func() { if c.ident == api.NoContainerID { alloc.addOwned(c.cidr.Addr.String(), c.cidr, c.isContainer) @@ -90,8 +95,10 @@ func (c *claim) Try(alloc *Allocator) bool { if c.noErrorOnUnknown { alloc.infof("Claim %s for %s: %s; will try later.", c.cidr, c.ident, err) c.sendResult(nil) - } else { // just tell the user they can't do this. - c.deniedBy(alloc, owner) + } else if c.tryCount > maxTryCount { + // give up, tell the user they can't do this + c.deniedBy(alloc, owner, err) + return true } } return false