Skip to content

Commit

Permalink
go/runtime/host: Ignore stale abort requests
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed May 24, 2024
1 parent 7c21149 commit 661fc60
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions go/runtime/host/sandbox/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"sync"
"sync/atomic"
"time"

"github.com/cenkalti/backoff/v4"
Expand Down Expand Up @@ -110,8 +111,9 @@ func (p *provisioner) Name() string {
// abortRequest is a request to the runtime manager goroutine to abort the runtime.
// In case of failures or if force flag is set, the runtime is restarted.
type abortRequest struct {
ch chan<- error
force bool
generation uint64
ch chan<- error
force bool
}

type sandboxedRuntime struct {
Expand All @@ -126,6 +128,10 @@ type sandboxedRuntime struct {
stopCh chan struct{}
ctrlCh chan interface{}

// generation is the generation number of the underlying process. It gets incremented by one on
// each restart and is used to avoid stale abort requests from propagating to the wrong process.
generation atomic.Uint64

process process.Process
conn protocol.Connection
notifier *pubsub.Broker
Expand Down Expand Up @@ -237,10 +243,14 @@ func (r *sandboxedRuntime) Start() {

// Implements host.Runtime.
func (r *sandboxedRuntime) Abort(ctx context.Context, force bool) error {
// Load current generation to make sure the abort request will not propagate to the wrong
// process in case the process gets restarted while the abort request is queued.
generation := r.generation.Load()

// Send internal request to the manager goroutine.
ch := make(chan error, 1)
select {
case r.ctrlCh <- &abortRequest{ch: ch, force: force}:
case r.ctrlCh <- &abortRequest{generation: generation, ch: ch, force: force}:
case <-ctx.Done():
return ctx.Err()
}
Expand All @@ -267,6 +277,9 @@ func (r *sandboxedRuntime) EmitEvent(ev *host.Event) {
}

func (r *sandboxedRuntime) startProcess() (err error) {
// Update process generation.
r.generation.Add(1)

// Create a temporary directory.
runtimeDir, err := os.MkdirTemp("", "oasis-runtime")
if err != nil {
Expand Down Expand Up @@ -449,6 +462,11 @@ func (r *sandboxedRuntime) startProcess() (err error) {
}

func (r *sandboxedRuntime) handleAbortRequest(rq *abortRequest) error {
// Make sure that the abort request is not stale (e.g. from a previous generation).
if rq.generation != r.generation.Load() {
return nil
}

r.logger.Warn("interrupting runtime")

// First attempt to gracefully interrupt the runtime by sending a request.
Expand Down

0 comments on commit 661fc60

Please sign in to comment.