Remove a lot of deferred functions in the request path. (#4733)
* Remove a lot of deferred functions in the request path. There is an interesting benchmark at https://www.reddit.com/r/golang/comments/3h21nk/simple_micro_benchmark_to_measure_the_overhead_of/ It shows that defer actually adds quite a lot of overhead -- maybe 100ns per call but we defer a *lot* of functions in the request path. So this removes some of the ones in request handling, ha, barrier, router, and physical cache. One meta-note: nearly every metrics function is in a defer which means every metrics call we add could add a non-trivial amount of time, e.g. for every 10 extra metrics statements we add 1ms to a request. I don't know how to solve this right now without doing what I did in some of these cases and putting that call into a simple function call that then goes before each return. * Simplify barrier defer cleanup
This commit is contained in:
parent
be6827feaa
commit
0c2d2226c4
|
@ -119,12 +119,13 @@ func (c *Cache) Put(ctx context.Context, entry *Entry) error {
|
||||||
|
|
||||||
lock := locksutil.LockForKey(c.locks, entry.Key)
|
lock := locksutil.LockForKey(c.locks, entry.Key)
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
err := c.backend.Put(ctx, entry)
|
err := c.backend.Put(ctx, entry)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.lru.Add(entry.Key, entry)
|
c.lru.Add(entry.Key, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,19 +136,21 @@ func (c *Cache) Get(ctx context.Context, key string) (*Entry, error) {
|
||||||
|
|
||||||
lock := locksutil.LockForKey(c.locks, key)
|
lock := locksutil.LockForKey(c.locks, key)
|
||||||
lock.RLock()
|
lock.RLock()
|
||||||
defer lock.RUnlock()
|
|
||||||
|
|
||||||
// Check the LRU first
|
// Check the LRU first
|
||||||
if raw, ok := c.lru.Get(key); ok {
|
if raw, ok := c.lru.Get(key); ok {
|
||||||
if raw == nil {
|
if raw == nil {
|
||||||
|
lock.RUnlock()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
lock.RUnlock()
|
||||||
return raw.(*Entry), nil
|
return raw.(*Entry), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from the underlying backend
|
// Read from the underlying backend
|
||||||
ent, err := c.backend.Get(ctx, key)
|
ent, err := c.backend.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
lock.RUnlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +159,7 @@ func (c *Cache) Get(ctx context.Context, key string) (*Entry, error) {
|
||||||
c.lru.Add(key, ent)
|
c.lru.Add(key, ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.RUnlock()
|
||||||
return ent, nil
|
return ent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,12 +170,13 @@ func (c *Cache) Delete(ctx context.Context, key string) error {
|
||||||
|
|
||||||
lock := locksutil.LockForKey(c.locks, key)
|
lock := locksutil.LockForKey(c.locks, key)
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
err := c.backend.Delete(ctx, key)
|
err := c.backend.Delete(ctx, key)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.lru.Remove(key)
|
c.lru.Remove(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,10 +201,16 @@ func (c *TransactionalCache) Transaction(ctx context.Context, txns []*TxnEntry)
|
||||||
// Lock the keys
|
// Lock the keys
|
||||||
for _, l := range locksutil.LocksForKeys(c.locks, keys) {
|
for _, l := range locksutil.LocksForKeys(c.locks, keys) {
|
||||||
l.Lock()
|
l.Lock()
|
||||||
defer l.Unlock()
|
}
|
||||||
|
|
||||||
|
unlockFunc := func() {
|
||||||
|
for _, l := range locksutil.LocksForKeys(c.locks, keys) {
|
||||||
|
l.Unlock()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Transactional.Transaction(ctx, txns); err != nil {
|
if err := c.Transactional.Transaction(ctx, txns); err != nil {
|
||||||
|
unlockFunc()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,5 +227,6 @@ func (c *TransactionalCache) Transaction(ctx context.Context, txns []*TxnEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlockFunc()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,8 +213,9 @@ func (b *AESGCMBarrier) KeyLength() (int, int) {
|
||||||
// is not expected to be able to perform any CRUD until it is unsealed.
|
// is not expected to be able to perform any CRUD until it is unsealed.
|
||||||
func (b *AESGCMBarrier) Sealed() (bool, error) {
|
func (b *AESGCMBarrier) Sealed() (bool, error) {
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
sealed := b.sealed
|
||||||
return b.sealed, nil
|
b.l.RUnlock()
|
||||||
|
return sealed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyMaster is used to check if the given key matches the master key
|
// VerifyMaster is used to check if the given key matches the master key
|
||||||
|
@ -636,14 +637,16 @@ func (b *AESGCMBarrier) updateMasterKeyCommon(key []byte) (*Keyring, error) {
|
||||||
func (b *AESGCMBarrier) Put(ctx context.Context, entry *Entry) error {
|
func (b *AESGCMBarrier) Put(ctx context.Context, entry *Entry) error {
|
||||||
defer metrics.MeasureSince([]string{"barrier", "put"}, time.Now())
|
defer metrics.MeasureSince([]string{"barrier", "put"}, time.Now())
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return ErrBarrierSealed
|
return ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
term := b.keyring.ActiveTerm()
|
term := b.keyring.ActiveTerm()
|
||||||
primary, err := b.aeadForTerm(term)
|
primary, err := b.aeadForTerm(term)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,29 +655,37 @@ func (b *AESGCMBarrier) Put(ctx context.Context, entry *Entry) error {
|
||||||
Value: b.encrypt(entry.Key, term, primary, entry.Value),
|
Value: b.encrypt(entry.Key, term, primary, entry.Value),
|
||||||
SealWrap: entry.SealWrap,
|
SealWrap: entry.SealWrap,
|
||||||
}
|
}
|
||||||
return b.backend.Put(ctx, pe)
|
|
||||||
|
err = b.backend.Put(ctx, pe)
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get is used to fetch an entry
|
// Get is used to fetch an entry
|
||||||
func (b *AESGCMBarrier) Get(ctx context.Context, key string) (*Entry, error) {
|
func (b *AESGCMBarrier) Get(ctx context.Context, key string) (*Entry, error) {
|
||||||
defer metrics.MeasureSince([]string{"barrier", "get"}, time.Now())
|
defer metrics.MeasureSince([]string{"barrier", "get"}, time.Now())
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, ErrBarrierSealed
|
return nil, ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the key from the backend
|
// Read the key from the backend
|
||||||
pe, err := b.backend.Get(ctx, key)
|
pe, err := b.backend.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if pe == nil {
|
} else if pe == nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the ciphertext
|
// Decrypt the ciphertext
|
||||||
plain, err := b.decryptKeyring(key, pe.Value)
|
plain, err := b.decryptKeyring(key, pe.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
|
return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,6 +695,8 @@ func (b *AESGCMBarrier) Get(ctx context.Context, key string) (*Entry, error) {
|
||||||
Value: plain,
|
Value: plain,
|
||||||
SealWrap: pe.SealWrap,
|
SealWrap: pe.SealWrap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,12 +704,16 @@ func (b *AESGCMBarrier) Get(ctx context.Context, key string) (*Entry, error) {
|
||||||
func (b *AESGCMBarrier) Delete(ctx context.Context, key string) error {
|
func (b *AESGCMBarrier) Delete(ctx context.Context, key string) error {
|
||||||
defer metrics.MeasureSince([]string{"barrier", "delete"}, time.Now())
|
defer metrics.MeasureSince([]string{"barrier", "delete"}, time.Now())
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return ErrBarrierSealed
|
return ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.backend.Delete(ctx, key)
|
err := b.backend.Delete(ctx, key)
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// List is used ot list all the keys under a given
|
// List is used ot list all the keys under a given
|
||||||
|
@ -704,12 +721,16 @@ func (b *AESGCMBarrier) Delete(ctx context.Context, key string) error {
|
||||||
func (b *AESGCMBarrier) List(ctx context.Context, prefix string) ([]string, error) {
|
func (b *AESGCMBarrier) List(ctx context.Context, prefix string) ([]string, error) {
|
||||||
defer metrics.MeasureSince([]string{"barrier", "list"}, time.Now())
|
defer metrics.MeasureSince([]string{"barrier", "list"}, time.Now())
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, ErrBarrierSealed
|
return nil, ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.backend.List(ctx, prefix)
|
keys, err := b.backend.List(ctx, prefix)
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
|
return keys, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// aeadForTerm returns the AES-GCM AEAD for the given term
|
// aeadForTerm returns the AES-GCM AEAD for the given term
|
||||||
|
@ -852,34 +873,42 @@ func (b *AESGCMBarrier) decryptKeyring(path string, cipher []byte) ([]byte, erro
|
||||||
// Encrypt is used to encrypt in-memory for the BarrierEncryptor interface
|
// Encrypt is used to encrypt in-memory for the BarrierEncryptor interface
|
||||||
func (b *AESGCMBarrier) Encrypt(ctx context.Context, key string, plaintext []byte) ([]byte, error) {
|
func (b *AESGCMBarrier) Encrypt(ctx context.Context, key string, plaintext []byte) ([]byte, error) {
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, ErrBarrierSealed
|
return nil, ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
term := b.keyring.ActiveTerm()
|
term := b.keyring.ActiveTerm()
|
||||||
primary, err := b.aeadForTerm(term)
|
primary, err := b.aeadForTerm(term)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ciphertext := b.encrypt(key, term, primary, plaintext)
|
ciphertext := b.encrypt(key, term, primary, plaintext)
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt is used to decrypt in-memory for the BarrierEncryptor interface
|
// Decrypt is used to decrypt in-memory for the BarrierEncryptor interface
|
||||||
func (b *AESGCMBarrier) Decrypt(ctx context.Context, key string, ciphertext []byte) ([]byte, error) {
|
func (b *AESGCMBarrier) Decrypt(ctx context.Context, key string, ciphertext []byte) ([]byte, error) {
|
||||||
b.l.RLock()
|
b.l.RLock()
|
||||||
defer b.l.RUnlock()
|
|
||||||
if b.sealed {
|
if b.sealed {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, ErrBarrierSealed
|
return nil, ErrBarrierSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the ciphertext
|
// Decrypt the ciphertext
|
||||||
plain, err := b.decryptKeyring(key, ciphertext)
|
plain, err := b.decryptKeyring(key, ciphertext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
b.l.RUnlock()
|
||||||
return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
|
return nil, errwrap.Wrapf("decryption failed: {{err}}", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.l.RUnlock()
|
||||||
return plain, nil
|
return plain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
vault/ha.go
13
vault/ha.go
|
@ -23,8 +23,9 @@ import (
|
||||||
// Standby checks if the Vault is in standby mode
|
// Standby checks if the Vault is in standby mode
|
||||||
func (c *Core) Standby() (bool, error) {
|
func (c *Core) Standby() (bool, error) {
|
||||||
c.stateLock.RLock()
|
c.stateLock.RLock()
|
||||||
defer c.stateLock.RUnlock()
|
standby := c.standby
|
||||||
return c.standby, nil
|
c.stateLock.RUnlock()
|
||||||
|
return standby, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leader is used to get the current active leader
|
// Leader is used to get the current active leader
|
||||||
|
@ -36,30 +37,34 @@ func (c *Core) Leader() (isLeader bool, leaderAddr, clusterAddr string, err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
c.stateLock.RLock()
|
c.stateLock.RLock()
|
||||||
defer c.stateLock.RUnlock()
|
|
||||||
|
|
||||||
// Check if sealed
|
// Check if sealed
|
||||||
if c.sealed {
|
if c.sealed {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return false, "", "", consts.ErrSealed
|
return false, "", "", consts.ErrSealed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are the leader
|
// Check if we are the leader
|
||||||
if !c.standby {
|
if !c.standby {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return true, c.redirectAddr, c.clusterAddr, nil
|
return true, c.redirectAddr, c.clusterAddr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a lock
|
// Initialize a lock
|
||||||
lock, err := c.ha.LockWith(coreLockPath, "read")
|
lock, err := c.ha.LockWith(coreLockPath, "read")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return false, "", "", err
|
return false, "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the value
|
// Read the value
|
||||||
held, leaderUUID, err := lock.Value()
|
held, leaderUUID, err := lock.Value()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return false, "", "", err
|
return false, "", "", err
|
||||||
}
|
}
|
||||||
if !held {
|
if !held {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return false, "", "", nil
|
return false, "", "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,11 +77,13 @@ func (c *Core) Leader() (isLeader bool, leaderAddr, clusterAddr string, err erro
|
||||||
// If the leader hasn't changed, return the cached value; nothing changes
|
// If the leader hasn't changed, return the cached value; nothing changes
|
||||||
// mid-leadership, and the barrier caches anyways
|
// mid-leadership, and the barrier caches anyways
|
||||||
if leaderUUID == localLeaderUUID && localRedirAddr != "" {
|
if leaderUUID == localLeaderUUID && localRedirAddr != "" {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return false, localRedirAddr, localClusterAddr, nil
|
return false, localRedirAddr, localClusterAddr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
c.logger.Trace("found new active node information, refreshing")
|
c.logger.Trace("found new active node information, refreshing")
|
||||||
|
|
||||||
|
defer c.stateLock.RUnlock()
|
||||||
c.clusterLeaderParamsLock.Lock()
|
c.clusterLeaderParamsLock.Lock()
|
||||||
defer c.clusterLeaderParamsLock.Unlock()
|
defer c.clusterLeaderParamsLock.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -252,16 +252,17 @@ func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool
|
||||||
// HandleRequest is used to handle a new incoming request
|
// HandleRequest is used to handle a new incoming request
|
||||||
func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err error) {
|
func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err error) {
|
||||||
c.stateLock.RLock()
|
c.stateLock.RLock()
|
||||||
defer c.stateLock.RUnlock()
|
|
||||||
if c.sealed {
|
if c.sealed {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return nil, consts.ErrSealed
|
return nil, consts.ErrSealed
|
||||||
}
|
}
|
||||||
if c.standby {
|
if c.standby {
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return nil, consts.ErrStandby
|
return nil, consts.ErrStandby
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(c.activeContext)
|
ctx, cancel := context.WithCancel(c.activeContext)
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Allowing writing to a path ending in / makes it extremely difficult to
|
// Allowing writing to a path ending in / makes it extremely difficult to
|
||||||
// understand user intent for the filesystem-like backends (kv,
|
// understand user intent for the filesystem-like backends (kv,
|
||||||
|
@ -272,6 +273,8 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err
|
||||||
if strings.HasSuffix(req.Path, "/") &&
|
if strings.HasSuffix(req.Path, "/") &&
|
||||||
(req.Operation == logical.UpdateOperation ||
|
(req.Operation == logical.UpdateOperation ||
|
||||||
req.Operation == logical.CreateOperation) {
|
req.Operation == logical.CreateOperation) {
|
||||||
|
cancel()
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return logical.ErrorResponse("cannot write to a path ending in '/'"), nil
|
return logical.ErrorResponse("cannot write to a path ending in '/'"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +341,8 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err
|
||||||
err := jsonutil.DecodeJSON(resp.Data[logical.HTTPRawBody].([]byte), httpResp)
|
err := jsonutil.DecodeJSON(resp.Data[logical.HTTPRawBody].([]byte), httpResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("failed to unmarshal wrapped HTTP response for audit logging", "error", err)
|
c.logger.Error("failed to unmarshal wrapped HTTP response for audit logging", "error", err)
|
||||||
|
cancel()
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return nil, ErrInternalError
|
return nil, ErrInternalError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,9 +378,13 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err
|
||||||
}
|
}
|
||||||
if auditErr := c.auditBroker.LogResponse(ctx, logInput, c.auditedHeaders); auditErr != nil {
|
if auditErr := c.auditBroker.LogResponse(ctx, logInput, c.auditedHeaders); auditErr != nil {
|
||||||
c.logger.Error("failed to audit response", "request_path", req.Path, "error", auditErr)
|
c.logger.Error("failed to audit response", "request_path", req.Path, "error", auditErr)
|
||||||
|
cancel()
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return nil, ErrInternalError
|
return nil, ErrInternalError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
c.stateLock.RUnlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,9 +209,9 @@ func (r *Router) MatchingMountByUUID(mountID string) *MountEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.l.RLock()
|
r.l.RLock()
|
||||||
defer r.l.RUnlock()
|
|
||||||
|
|
||||||
_, raw, ok := r.mountUUIDCache.LongestPrefix(mountID)
|
_, raw, ok := r.mountUUIDCache.LongestPrefix(mountID)
|
||||||
|
r.l.RUnlock()
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -226,9 +226,9 @@ func (r *Router) MatchingMountByAccessor(mountAccessor string) *MountEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.l.RLock()
|
r.l.RLock()
|
||||||
defer r.l.RUnlock()
|
|
||||||
|
|
||||||
_, raw, ok := r.mountAccessorCache.LongestPrefix(mountAccessor)
|
_, raw, ok := r.mountAccessorCache.LongestPrefix(mountAccessor)
|
||||||
|
r.l.RUnlock()
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -239,8 +239,8 @@ func (r *Router) MatchingMountByAccessor(mountAccessor string) *MountEntry {
|
||||||
// MatchingMount returns the mount prefix that would be used for a path
|
// MatchingMount returns the mount prefix that would be used for a path
|
||||||
func (r *Router) MatchingMount(path string) string {
|
func (r *Router) MatchingMount(path string) string {
|
||||||
r.l.RLock()
|
r.l.RLock()
|
||||||
defer r.l.RUnlock()
|
mount := r.matchingMountInternal(path)
|
||||||
var mount = r.matchingMountInternal(path)
|
r.l.RUnlock()
|
||||||
return mount
|
return mount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,10 +406,10 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
// Grab a read lock on the route entry, this protects against the backend
|
// Grab a read lock on the route entry, this protects against the backend
|
||||||
// being reloaded during a request.
|
// being reloaded during a request.
|
||||||
re.l.RLock()
|
re.l.RLock()
|
||||||
defer re.l.RUnlock()
|
|
||||||
|
|
||||||
// Filtered mounts will have a nil backend
|
// Filtered mounts will have a nil backend
|
||||||
if re.backend == nil {
|
if re.backend == nil {
|
||||||
|
re.l.RUnlock()
|
||||||
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,6 +419,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
switch req.Operation {
|
switch req.Operation {
|
||||||
case logical.RevokeOperation, logical.RollbackOperation:
|
case logical.RevokeOperation, logical.RollbackOperation:
|
||||||
default:
|
default:
|
||||||
|
re.l.RUnlock()
|
||||||
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +449,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
// salted ID, so we double-salt what's going to the cubbyhole backend
|
// salted ID, so we double-salt what's going to the cubbyhole backend
|
||||||
salt, err := r.tokenStoreSaltFunc(ctx)
|
salt, err := r.tokenStoreSaltFunc(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
re.l.RUnlock()
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
req.ClientToken = re.SaltID(salt.SaltID(req.ClientToken))
|
req.ClientToken = re.SaltID(salt.SaltID(req.ClientToken))
|
||||||
|
@ -489,7 +491,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
req.SetTokenEntry(nil)
|
req.SetTokenEntry(nil)
|
||||||
|
|
||||||
// Reset the request before returning
|
// Reset the request before returning
|
||||||
defer func() {
|
resetFunc := func() {
|
||||||
req.Path = originalPath
|
req.Path = originalPath
|
||||||
req.MountPoint = mount
|
req.MountPoint = mount
|
||||||
req.MountType = re.mountEntry.Type
|
req.MountType = re.mountEntry.Type
|
||||||
|
@ -511,11 +513,13 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
req.EntityID = originalEntityID
|
req.EntityID = originalEntityID
|
||||||
|
|
||||||
req.SetTokenEntry(reqTokenEntry)
|
req.SetTokenEntry(reqTokenEntry)
|
||||||
}()
|
}
|
||||||
|
|
||||||
// Invoke the backend
|
// Invoke the backend
|
||||||
if existenceCheck {
|
if existenceCheck {
|
||||||
ok, exists, err := re.backend.HandleExistenceCheck(ctx, req)
|
ok, exists, err := re.backend.HandleExistenceCheck(ctx, req)
|
||||||
|
resetFunc()
|
||||||
|
re.l.RUnlock()
|
||||||
return nil, ok, exists, err
|
return nil, ok, exists, err
|
||||||
} else {
|
} else {
|
||||||
resp, err := re.backend.HandleRequest(ctx, req)
|
resp, err := re.backend.HandleRequest(ctx, req)
|
||||||
|
@ -540,6 +544,8 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
||||||
alias.MountAccessor = re.mountEntry.Accessor
|
alias.MountAccessor = re.mountEntry.Accessor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resetFunc()
|
||||||
|
re.l.RUnlock()
|
||||||
return resp, false, false, err
|
return resp, false, false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue