mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #43260 from thockin/nodeport-allocation-rand-seed
Automatic merge from submit-queue (batch tested with PRs 42379, 42668, 42876, 41473, 43260) Don't use global rand for nodeport and IP allocs Seed it at construction.
This commit is contained in:
commit
223ac9f8b0
@ -21,6 +21,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AllocationBitmap is a contiguous block of resources that can be allocated atomically.
|
// AllocationBitmap is a contiguous block of resources that can be allocated atomically.
|
||||||
@ -33,8 +34,8 @@ import (
|
|||||||
//
|
//
|
||||||
// TODO: use RLE and compact the allocator to minimize space.
|
// TODO: use RLE and compact the allocator to minimize space.
|
||||||
type AllocationBitmap struct {
|
type AllocationBitmap struct {
|
||||||
// strategy is the strategy for choosing the next available item out of the range
|
// strategy carries the details of how to choose the next available item out of the range
|
||||||
strategy allocateStrategy
|
strategy bitAllocator
|
||||||
// max is the maximum size of the usable items in the range
|
// max is the maximum size of the usable items in the range
|
||||||
max int
|
max int
|
||||||
// rangeSpec is the range specifier, matching RangeAllocation.Range
|
// rangeSpec is the range specifier, matching RangeAllocation.Range
|
||||||
@ -52,13 +53,17 @@ type AllocationBitmap struct {
|
|||||||
var _ Interface = &AllocationBitmap{}
|
var _ Interface = &AllocationBitmap{}
|
||||||
var _ Snapshottable = &AllocationBitmap{}
|
var _ Snapshottable = &AllocationBitmap{}
|
||||||
|
|
||||||
// allocateStrategy is a search strategy in the allocation map for a valid item.
|
// bitAllocator represents a search strategy in the allocation map for a valid item.
|
||||||
type allocateStrategy func(allocated *big.Int, max, count int) (int, bool)
|
type bitAllocator interface {
|
||||||
|
AllocateBit(allocated *big.Int, max, count int) (int, bool)
|
||||||
|
}
|
||||||
|
|
||||||
// NewAllocationMap creates an allocation bitmap using the random scan strategy.
|
// NewAllocationMap creates an allocation bitmap using the random scan strategy.
|
||||||
func NewAllocationMap(max int, rangeSpec string) *AllocationBitmap {
|
func NewAllocationMap(max int, rangeSpec string) *AllocationBitmap {
|
||||||
a := AllocationBitmap{
|
a := AllocationBitmap{
|
||||||
strategy: randomScanStrategy,
|
strategy: randomScanStrategy{
|
||||||
|
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||||
|
},
|
||||||
allocated: big.NewInt(0),
|
allocated: big.NewInt(0),
|
||||||
count: 0,
|
count: 0,
|
||||||
max: max,
|
max: max,
|
||||||
@ -70,7 +75,7 @@ func NewAllocationMap(max int, rangeSpec string) *AllocationBitmap {
|
|||||||
// NewContiguousAllocationMap creates an allocation bitmap using the contiguous scan strategy.
|
// NewContiguousAllocationMap creates an allocation bitmap using the contiguous scan strategy.
|
||||||
func NewContiguousAllocationMap(max int, rangeSpec string) *AllocationBitmap {
|
func NewContiguousAllocationMap(max int, rangeSpec string) *AllocationBitmap {
|
||||||
a := AllocationBitmap{
|
a := AllocationBitmap{
|
||||||
strategy: contiguousScanStrategy,
|
strategy: contiguousScanStrategy{},
|
||||||
allocated: big.NewInt(0),
|
allocated: big.NewInt(0),
|
||||||
count: 0,
|
count: 0,
|
||||||
max: max,
|
max: max,
|
||||||
@ -99,7 +104,7 @@ func (r *AllocationBitmap) AllocateNext() (int, bool, error) {
|
|||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
next, ok := r.strategy(r.allocated, r.max, r.count)
|
next, ok := r.strategy.AllocateBit(r.allocated, r.max, r.count)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, false, nil
|
return 0, false, nil
|
||||||
}
|
}
|
||||||
@ -193,11 +198,15 @@ func (r *AllocationBitmap) Restore(rangeSpec string, data []byte) error {
|
|||||||
// randomScanStrategy chooses a random address from the provided big.Int, and then
|
// randomScanStrategy chooses a random address from the provided big.Int, and then
|
||||||
// scans forward looking for the next available address (it will wrap the range if
|
// scans forward looking for the next available address (it will wrap the range if
|
||||||
// necessary).
|
// necessary).
|
||||||
func randomScanStrategy(allocated *big.Int, max, count int) (int, bool) {
|
type randomScanStrategy struct {
|
||||||
|
rand *rand.Rand
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rss randomScanStrategy) AllocateBit(allocated *big.Int, max, count int) (int, bool) {
|
||||||
if count >= max {
|
if count >= max {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
offset := rand.Intn(max)
|
offset := rss.rand.Intn(max)
|
||||||
for i := 0; i < max; i++ {
|
for i := 0; i < max; i++ {
|
||||||
at := (offset + i) % max
|
at := (offset + i) % max
|
||||||
if allocated.Bit(at) == 0 {
|
if allocated.Bit(at) == 0 {
|
||||||
@ -207,8 +216,12 @@ func randomScanStrategy(allocated *big.Int, max, count int) (int, bool) {
|
|||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ bitAllocator = randomScanStrategy{}
|
||||||
|
|
||||||
// contiguousScanStrategy tries to allocate starting at 0 and filling in any gaps
|
// contiguousScanStrategy tries to allocate starting at 0 and filling in any gaps
|
||||||
func contiguousScanStrategy(allocated *big.Int, max, count int) (int, bool) {
|
type contiguousScanStrategy struct{}
|
||||||
|
|
||||||
|
func (contiguousScanStrategy) AllocateBit(allocated *big.Int, max, count int) (int, bool) {
|
||||||
if count >= max {
|
if count >= max {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
@ -219,3 +232,5 @@ func contiguousScanStrategy(allocated *big.Int, max, count int) (int, bool) {
|
|||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ bitAllocator = contiguousScanStrategy{}
|
||||||
|
Loading…
Reference in New Issue
Block a user