Plumb disabling caches through the policy store

This commit is contained in:
Jeff Mitchell 2016-04-21 13:52:42 +00:00
parent 6ef30efae6
commit 8572190b64
6 changed files with 70 additions and 21 deletions

View File

@ -26,6 +26,10 @@ type SystemView interface {
// when the stored CRL will be removed during the unmounting process
// anyways), we can ignore the errors to allow unmounting to complete.
Tainted() bool
// Returns true if caching is disabled. If true, no caches should be used,
// despite known slowdowns.
CacheDisabled() bool
}
type StaticSystemView struct {
@ -33,6 +37,7 @@ type StaticSystemView struct {
MaxLeaseTTLVal time.Duration
SudoPrivilegeVal bool
TaintedVal bool
CacheDisabledVal bool
}
func (d StaticSystemView) DefaultLeaseTTL() time.Duration {
@ -50,3 +55,7 @@ func (d StaticSystemView) SudoPrivilege(path string, token string) bool {
func (d StaticSystemView) Tainted() bool {
return d.TaintedVal
}
func (d StaticSystemView) CacheDisabled() bool {
return d.CacheDisabledVal
}

View File

@ -218,6 +218,9 @@ type Core struct {
maxLeaseTTL time.Duration
logger *log.Logger
// cacheDisabled indicates whether caches are disabled
cacheDisabled bool
}
// CoreConfig is used to parameterize a core
@ -315,6 +318,7 @@ func NewCore(conf *CoreConfig) (*Core, error) {
logger: conf.Logger,
defaultLeaseTTL: conf.DefaultLeaseTTL,
maxLeaseTTL: conf.MaxLeaseTTL,
cacheDisabled: conf.DisableCache,
}
// Setup the backends

View File

@ -69,3 +69,8 @@ func (d dynamicSystemView) fetchTTLs() (def, max time.Duration) {
func (d dynamicSystemView) Tainted() bool {
return d.mountEntry.Tainted
}
// CacheDisabled indicates whether to use caching behavior
func (d dynamicSystemView) CacheDisabled() bool {
return d.core.cacheDisabled
}

View File

@ -22,8 +22,9 @@ const (
// PolicyStore is used to provide durable storage of policy, and to
// manage ACLs associated with them.
type PolicyStore struct {
view *BarrierView
lru *lru.TwoQueueCache
view *BarrierView
lru *lru.TwoQueueCache
system logical.SystemView
}
// PolicyEntry is used to store a policy by name
@ -34,12 +35,16 @@ type PolicyEntry struct {
// NewPolicyStore creates a new PolicyStore that is backed
// using a given view. It used used to durable store and manage named policy.
func NewPolicyStore(view *BarrierView) *PolicyStore {
cache, _ := lru.New2Q(policyCacheSize)
func NewPolicyStore(view *BarrierView, system logical.SystemView) *PolicyStore {
p := &PolicyStore{
view: view,
lru: cache,
view: view,
system: system,
}
if !system.CacheDisabled() {
cache, _ := lru.New2Q(policyCacheSize)
p.lru = cache
}
return p
}
@ -50,7 +55,7 @@ func (c *Core) setupPolicyStore() error {
view := c.systemBarrierView.SubView(policySubPath)
// Create the policy store
c.policyStore = NewPolicyStore(view)
c.policyStore = NewPolicyStore(view, &dynamicSystemView{core: c})
// Ensure that the default policy exists, and if not, create it
policy, err := c.policyStore.GetPolicy("default")
@ -95,23 +100,29 @@ func (ps *PolicyStore) SetPolicy(p *Policy) error {
return fmt.Errorf("failed to persist policy: %v", err)
}
// Update the LRU cache
ps.lru.Add(p.Name, p)
if !ps.system.CacheDisabled() {
// Update the LRU cache
ps.lru.Add(p.Name, p)
}
return nil
}
// GetPolicy is used to fetch the named policy
func (ps *PolicyStore) GetPolicy(name string) (*Policy, error) {
defer metrics.MeasureSince([]string{"policy", "get_policy"}, time.Now())
// Check for cached policy
if raw, ok := ps.lru.Get(name); ok {
return raw.(*Policy), nil
if !ps.system.CacheDisabled() {
// Check for cached policy
if raw, ok := ps.lru.Get(name); ok {
return raw.(*Policy), nil
}
}
// Special case the root policy
if name == "root" {
p := &Policy{Name: "root"}
ps.lru.Add(p.Name, p)
if !ps.system.CacheDisabled() {
ps.lru.Add(p.Name, p)
}
return p, nil
}
@ -152,8 +163,11 @@ func (ps *PolicyStore) GetPolicy(name string) (*Policy, error) {
policy = p
}
// Update the LRU cache
ps.lru.Add(name, policy)
if !ps.system.CacheDisabled() {
// Update the LRU cache
ps.lru.Add(name, policy)
}
return policy, nil
}
@ -178,8 +192,10 @@ func (ps *PolicyStore) DeletePolicy(name string) error {
return fmt.Errorf("failed to delete policy: %v", err)
}
// Clear the cache
ps.lru.Remove(name)
if !ps.system.CacheDisabled() {
// Clear the cache
ps.lru.Remove(name)
}
return nil
}

View File

@ -10,7 +10,16 @@ import (
func mockPolicyStore(t *testing.T) *PolicyStore {
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "foo/")
p := NewPolicyStore(view)
p := NewPolicyStore(view, logical.TestSystemView())
return p
}
func mockPolicyStoreNoCache(t *testing.T) *PolicyStore {
sysView := logical.TestSystemView()
sysView.CacheDisabledVal = true
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "foo/")
p := NewPolicyStore(view, sysView)
return p
}
@ -44,7 +53,13 @@ func TestPolicyStore_Root(t *testing.T) {
func TestPolicyStore_CRUD(t *testing.T) {
ps := mockPolicyStore(t)
testPolicyStore_CRUD(t, ps)
ps = mockPolicyStoreNoCache(t)
testPolicyStore_CRUD(t, ps)
}
func testPolicyStore_CRUD(t *testing.T, ps *PolicyStore) {
// Get should return nothing
p, err := ps.GetPolicy("dev")
if err != nil {

View File

@ -50,9 +50,9 @@ sending a SIGHUP to the server process. These are denoted below.
"tcp" is currently the only option available. A full reference for the
inner syntax is below.
* `disable_cache` (optional) - A boolean. If true, this will disable the
read cache used by the physical storage subsystem. This will very
significantly impact performance.
* `disable_cache` (optional) - A boolean. If true, this will disable all caches
within Vault, including the read cache used by the physical storage
subsystem. This will very significantly impact performance.
* `disable_mlock` (optional) - A boolean. If true, this will disable the
server from executing the `mlock` syscall to prevent memory from being