Browse code

Update libnetwork with fixes for duplicate IP addresses

This updates libnetwork to 8892d7537c67232591f1f3af60587e3e77e61d41 to bring in
IPAM fixes for duplicate IP addresses.

- IPAM tests (libnetwork PR 2104) (no changes in vendored files)
- Fix for Duplicate IP issues (libnetwork PR 2105)

Also bump golang/x/sync to match libnetwork (no code-changes, other
than the README being updated)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2018/03/14 20:44:22
Showing 7 changed files
... ...
@@ -3,7 +3,7 @@
3 3
 # LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
4 4
 # updating the binary version, consider updating github.com/docker/libnetwork
5 5
 # in vendor.conf accordingly
6
-LIBNETWORK_COMMIT=ed2130d117c11c542327b4d5216a5db36770bc65
6
+LIBNETWORK_COMMIT=8892d7537c67232591f1f3af60587e3e77e61d41
7 7
 
8 8
 install_proxy() {
9 9
 	case "$1" in
... ...
@@ -26,7 +26,7 @@ github.com/google/go-cmp v0.1.0
26 26
 
27 27
 github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5
28 28
 github.com/imdario/mergo 0.2.1
29
-golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0
29
+golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
30 30
 
31 31
 github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8
32 32
 github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
... ...
@@ -34,7 +34,7 @@ github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
34 34
 #get libnetwork packages
35 35
 
36 36
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
37
-github.com/docker/libnetwork 3aca383eb555510f3f17696f9505f7bfbd25f0e5
37
+github.com/docker/libnetwork 8892d7537c67232591f1f3af60587e3e77e61d41
38 38
 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
39 39
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
40 40
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -108,6 +108,12 @@ func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
108 108
 		bitSel >>= 1
109 109
 		bits++
110 110
 	}
111
+	// Check if the loop exited because it could not
112
+	// find any available bit int block  starting from
113
+	// "from". Return invalid pos in that case.
114
+	if bitSel == 0 {
115
+		return invalidPos, invalidPos, ErrNoBitAvailable
116
+	}
111 117
 	return bits / 8, bits % 8, nil
112 118
 }
113 119
 
... ...
@@ -313,14 +319,14 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
313 313
 		curr := uint64(0)
314 314
 		h.Lock()
315 315
 		store = h.store
316
-		h.Unlock()
317 316
 		if store != nil {
317
+			h.Unlock() // The lock is acquired in the GetObject
318 318
 			if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
319 319
 				return ret, err
320 320
 			}
321
+			h.Lock() // Acquire the lock back
321 322
 		}
322
-
323
-		h.Lock()
323
+		logrus.Debugf("Received set for ordinal %v, start %v, end %v, any %t, release %t, serial:%v curr:%d \n", ordinal, start, end, any, release, serial, h.curr)
324 324
 		if serial {
325 325
 			curr = h.curr
326 326
 		}
... ...
@@ -346,7 +352,6 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
346 346
 
347 347
 		// Create a private copy of h and work on it
348 348
 		nh := h.getCopy()
349
-		h.Unlock()
350 349
 
351 350
 		nh.head = pushReservation(bytePos, bitPos, nh.head, release)
352 351
 		if release {
... ...
@@ -355,22 +360,25 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
355 355
 			nh.unselected--
356 356
 		}
357 357
 
358
-		// Attempt to write private copy to store
359
-		if err := nh.writeToStore(); err != nil {
360
-			if _, ok := err.(types.RetryError); !ok {
361
-				return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
358
+		if h.store != nil {
359
+			h.Unlock()
360
+			// Attempt to write private copy to store
361
+			if err := nh.writeToStore(); err != nil {
362
+				if _, ok := err.(types.RetryError); !ok {
363
+					return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
364
+				}
365
+				// Retry
366
+				continue
362 367
 			}
363
-			// Retry
364
-			continue
368
+			h.Lock()
365 369
 		}
366 370
 
367 371
 		// Previous atomic push was succesfull. Save private copy to local copy
368
-		h.Lock()
369
-		defer h.Unlock()
370 372
 		h.unselected = nh.unselected
371 373
 		h.head = nh.head
372 374
 		h.dbExists = nh.dbExists
373 375
 		h.dbIndex = nh.dbIndex
376
+		h.Unlock()
374 377
 		return ret, nil
375 378
 	}
376 379
 }
... ...
@@ -498,24 +506,40 @@ func (h *Handle) UnmarshalJSON(data []byte) error {
498 498
 func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
499 499
 	// Find sequence which contains the start bit
500 500
 	byteStart, bitStart := ordinalToPos(start)
501
-	current, _, _, inBlockBytePos := findSequence(head, byteStart)
502
-
501
+	current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
503 502
 	// Derive the this sequence offsets
504 503
 	byteOffset := byteStart - inBlockBytePos
505 504
 	bitOffset := inBlockBytePos*8 + bitStart
506
-	var firstOffset uint64
507
-	if current == head {
508
-		firstOffset = byteOffset
509
-	}
510 505
 	for current != nil {
511 506
 		if current.block != blockMAX {
507
+			// If the current block is not full, check if there is any bit
508
+			// from the current bit in the current block. If not, before proceeding to the
509
+			// next block node, make sure we check for available bit in the next
510
+			// instance of the same block. Due to RLE same block signature will be
511
+			// compressed.
512
+		retry:
512 513
 			bytePos, bitPos, err := current.getAvailableBit(bitOffset)
514
+			if err != nil && precBlocks == current.count-1 {
515
+				// This is the last instance in the same block node,
516
+				// so move to the next block.
517
+				goto next
518
+			}
519
+			if err != nil {
520
+				// There are some more instances of the same block, so add the offset
521
+				// and be optimistic that you will find the available bit in the next
522
+				// instance of the same block.
523
+				bitOffset = 0
524
+				byteOffset += blockBytes
525
+				precBlocks++
526
+				goto retry
527
+			}
513 528
 			return byteOffset + bytePos, bitPos, err
514 529
 		}
515 530
 		// Moving to next block: Reset bit offset.
531
+	next:
516 532
 		bitOffset = 0
517
-		byteOffset += (current.count * blockBytes) - firstOffset
518
-		firstOffset = 0
533
+		byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
534
+		precBlocks = 0
519 535
 		current = current.next
520 536
 	}
521 537
 	return invalidPos, invalidPos, ErrNoBitAvailable
... ...
@@ -526,19 +550,20 @@ func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
526 526
 // This can be further optimized to check from start till curr in case of a rollover
527 527
 func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
528 528
 	var bytePos, bitPos uint64
529
+	var err error
529 530
 	if curr != 0 && curr > start {
530
-		bytePos, bitPos, _ = getFirstAvailable(head, curr)
531
+		bytePos, bitPos, err = getFirstAvailable(head, curr)
531 532
 		ret := posToOrdinal(bytePos, bitPos)
532
-		if end < ret {
533
+		if end < ret || err != nil {
533 534
 			goto begin
534 535
 		}
535 536
 		return bytePos, bitPos, nil
536 537
 	}
537 538
 
538 539
 begin:
539
-	bytePos, bitPos, _ = getFirstAvailable(head, start)
540
+	bytePos, bitPos, err = getFirstAvailable(head, start)
540 541
 	ret := posToOrdinal(bytePos, bitPos)
541
-	if end < ret {
542
+	if end < ret || err != nil {
542 543
 		return invalidPos, invalidPos, ErrNoBitAvailable
543 544
 	}
544 545
 	return bytePos, bitPos, nil
... ...
@@ -402,15 +402,15 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error)
402 402
 			continue
403 403
 		}
404 404
 		aSpace.Lock()
405
-		_, ok := aSpace.subnets[SubnetKey{AddressSpace: as, Subnet: nw.String()}]
406
-		aSpace.Unlock()
407
-		if ok {
405
+		if _, ok := aSpace.subnets[SubnetKey{AddressSpace: as, Subnet: nw.String()}]; ok {
406
+			aSpace.Unlock()
408 407
 			continue
409 408
 		}
410
-
411 409
 		if !aSpace.contains(as, nw) {
410
+			aSpace.Unlock()
412 411
 			return nw, nil
413 412
 		}
413
+		aSpace.Unlock()
414 414
 	}
415 415
 
416 416
 	return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v)
... ...
@@ -50,5 +50,6 @@ github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
50 50
 golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
51 51
 golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
52 52
 golang.org/x/sys 07c182904dbd53199946ba614a412c61d3c548f5
53
+golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
53 54
 github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
54 55
 github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
55 56
deleted file mode 100644
... ...
@@ -1,2 +0,0 @@
1
-This repository provides Go concurrency primitives in addition to the
2
-ones provided by the language and "sync" and "sync/atomic" packages.
3 1
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+# Go Sync
1
+
2
+This repository provides Go concurrency primitives in addition to the
3
+ones provided by the language and "sync" and "sync/atomic" packages.
4
+
5
+## Download/Install
6
+
7
+The easiest way to install is to run `go get -u golang.org/x/sync`. You can
8
+also manually git clone the repository to `$GOPATH/src/golang.org/x/sync`.
9
+
10
+## Report Issues / Send Patches
11
+
12
+This repository uses Gerrit for code changes. To learn how to submit changes to
13
+this repository, see https://golang.org/doc/contribute.html.
14
+
15
+The main issue tracker for the sync repository is located at
16
+https://github.com/golang/go/issues. Prefix your issue with "x/sync:" in the
17
+subject line, so it is easy to find.