MCPcopy
hub / github.com/cilium/cilium / lockedAllocate

Method lockedAllocate

pkg/allocator/allocator.go:530–662  ·  view source on GitHub ↗

Return values: 1. allocated ID 2. whether the ID is newly allocated from kvstore 3. whether this is the first owner that holds a reference to the key in localkeys store 4. error in case of failure

(ctx context.Context, key AllocatorKey)

Source from the content-addressed store, hash-verified

528// localkeys store
529// 4. error in case of failure
530func (a *Allocator) lockedAllocate(ctx context.Context, key AllocatorKey) (idpool.ID, bool, bool, error) {
531 var firstUse bool
532
533 kvstore.Trace(a.logger, "Allocating key in kvstore", fieldKey, key)
534
535 k := key.GetKey()
536 lock, err := a.backend.Lock(ctx, key)
537 if err != nil {
538 return 0, false, false, err
539 }
540
541 defer lock.Unlock(context.Background())
542
543 // fetch first key that matches /value/<key>
544 value, err := a.GetIfLocked(ctx, key, lock)
545 if err != nil {
546 return 0, false, false, err
547 }
548
549 kvstore.Trace(a.logger, "kvstore state is: ", fieldID, value)
550
551 a.slaveKeysMutex.Lock()
552 defer a.slaveKeysMutex.Unlock()
553
554 // We shouldn't assume the fact the master key does not exist in the kvstore
555 // that localKeys does not have it. The KVStore might have lost all of its
556 // data but the local agent still holds a reference for the given master key.
557 if value == 0 {
558 value = a.localKeys.lookupKey(k)
559 if value != 0 {
560 // re-create master key
561 if err := a.backend.UpdateKeyIfLocked(ctx, value, key, true, lock); err != nil {
562 return 0, false, false, fmt.Errorf("unable to re-create missing master key '%s': %s while allocating ID: %w", key, value, err)
563 }
564 }
565 } else {
566 _, firstUse, err = a.localKeys.allocate(k, key, value)
567 if err != nil {
568 return 0, false, false, fmt.Errorf("unable to reserve local key '%s': %w", k, err)
569 }
570
571 if firstUse {
572 a.logger.Debug("Reserved new local key", logfields.Key, k)
573 } else {
574 a.logger.Debug("Reusing existing local key", logfields.Key, k)
575 }
576 }
577
578 if value != 0 {
579 a.logger.Debug("Reusing existing global key", logfields.Key, k)
580
581 if err = a.backend.AcquireReference(ctx, value, key, lock); err != nil {
582 a.localKeys.release(k)
583 return 0, false, false, fmt.Errorf("unable to create secondary key '%s': %w", k, err)
584 }
585
586 // mark the key as verified in the local cache
587 if err := a.localKeys.verify(k); err != nil {

Callers 1

AllocateMethod · 0.95

Calls 15

GetIfLockedMethod · 0.95
selectAvailableIDMethod · 0.95
GetNoCacheMethod · 0.95
TraceFunction · 0.92
lookupKeyMethod · 0.80
UseMethod · 0.80
GetKeyMethod · 0.65
LockMethod · 0.65
UnlockMethod · 0.65
UpdateKeyIfLockedMethod · 0.65
DebugMethod · 0.65
AcquireReferenceMethod · 0.65

Tested by

no test coverage detected