From bd5f61aae141c7b5acdba9f5a86e4873b70ad443 Mon Sep 17 00:00:00 2001 From: Steven Clark Date: Fri, 12 Apr 2024 08:51:44 -0400 Subject: [PATCH] During a seal reload through SIGHUP, only write updated seal barrier on an active node (#26381) * During a seal reload through SIGHUP, do not write updated seal barrier on non-active nodes * Add cl --- changelog/26381.txt | 3 +++ command/server.go | 27 ++++++++++++++++++++++----- vault/core.go | 28 ++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 changelog/26381.txt diff --git a/changelog/26381.txt b/changelog/26381.txt new file mode 100644 index 0000000000..c1d55e4781 --- /dev/null +++ b/changelog/26381.txt @@ -0,0 +1,3 @@ +```release-note:bug +core/seal: During a seal reload through SIGHUP, only write updated seal barrier on an active node +``` diff --git a/command/server.go b/command/server.go index 489176cc87..428d882b1f 100644 --- a/command/server.go +++ b/command/server.go @@ -3485,13 +3485,30 @@ func (c *ServerCommand) reloadSeals(ctx context.Context, grabStateLock bool, cor newGen := setSealResponse.barrierSeal.GetAccess().GetSealGenerationInfo() - err = core.SetSeals(ctx, grabStateLock, setSealResponse.barrierSeal, secureRandomReader, !newGen.IsRewrapped() || setSealResponse.hasPartiallyWrappedPaths) - if err != nil { - return false, fmt.Errorf("error setting seal: %s", err) + var standby, perf bool + if grabStateLock { + // If grabStateLock is false we know we are on a leader activation + standby, perf = core.StandbyStates() } + switch { + case !perf && !standby: + c.logger.Debug("persisting reloaded seals as we are the active node") + err = core.SetSeals(ctx, grabStateLock, setSealResponse.barrierSeal, secureRandomReader, !newGen.IsRewrapped() || setSealResponse.hasPartiallyWrappedPaths) + if err != nil { + return false, fmt.Errorf("error setting seal: %s", err) + } - if err := core.SetPhysicalSealGenInfo(ctx, newGen); err != nil { - c.logger.Warn("could not update seal information in storage", "err", err) + if err := core.SetPhysicalSealGenInfo(ctx, newGen); err != nil { + c.logger.Warn("could not update seal information in storage", "err", err) + } + case perf: + c.logger.Debug("updating reloaded seals in memory on perf standby") + err = core.SetSealsOnPerfStandby(ctx, grabStateLock, setSealResponse.barrierSeal, secureRandomReader) + if err != nil { + return false, fmt.Errorf("error setting seal on perf standby: %s", err) + } + default: + return false, errors.New("skipping seal reload as we are a standby") } // finalize the old seals and set the new seals as the current ones diff --git a/vault/core.go b/vault/core.go index 66950b091f..9800192c3c 100644 --- a/vault/core.go +++ b/vault/core.go @@ -4464,12 +4464,22 @@ func (c *Core) GetRaftAutopilotState(ctx context.Context) (*raft.AutopilotState, return raftBackend.GetAutopilotServerState(ctx) } -// Events returns a reference to the common event bus for sending and subscribint to events. +// Events returns a reference to the common event bus for sending and subscribing to events. func (c *Core) Events() *eventbus.EventBus { return c.events } func (c *Core) SetSeals(ctx context.Context, grabLock bool, barrierSeal Seal, secureRandomReader io.Reader, shouldRewrap bool) error { + return c.setSeals(ctx, grabLock, barrierSeal, secureRandomReader, shouldRewrap, true) +} + +// SetSealsOnPerfStandby sets the seal state within the core object without attempting to persist it to disk, +// normally SetSeals is what you should be calling. +func (c *Core) SetSealsOnPerfStandby(ctx context.Context, grabLock bool, barrierSeal Seal, secureRandomReader io.Reader) error { + return c.setSeals(ctx, grabLock, barrierSeal, secureRandomReader, false, false) +} + +func (c *Core) setSeals(ctx context.Context, grabLock bool, barrierSeal Seal, secureRandomReader io.Reader, shouldRewrap bool, performWrite bool) error { if grabLock { ctx, _ = c.GetContext() @@ -4497,14 +4507,16 @@ func (c *Core) SetSeals(ctx context.Context, grabLock bool, barrierSeal Seal, se } barrierConfigCopy.Type = barrierSeal.BarrierSealConfigType().String() - err = barrierSeal.SetBarrierConfig(ctx, barrierConfigCopy) - if err != nil { - return fmt.Errorf("error setting barrier config for new seal: %s", err) - } + if performWrite { + err = barrierSeal.SetBarrierConfig(ctx, barrierConfigCopy) + if err != nil { + return fmt.Errorf("error setting barrier config for new seal: %s", err) + } - err = barrierSeal.SetStoredKeys(ctx, rootKey) - if err != nil { - return fmt.Errorf("error setting root key in new seal: %s", err) + err = barrierSeal.SetStoredKeys(ctx, rootKey) + if err != nil { + return fmt.Errorf("error setting root key in new seal: %s", err) + } } c.seal = barrierSeal