Skip to content

Commit

Permalink
Remove os.Exit in favor of more graceful shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaMahany committed Nov 28, 2023
1 parent dc7816c commit e43c36b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
16 changes: 12 additions & 4 deletions cmd/launcher/svc_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main

import (
"context"
"errors"
"fmt"
"log/slog"
"os"
Expand Down Expand Up @@ -195,22 +196,22 @@ func (w *winSvc) Execute(args []string, r <-chan svc.ChangeRequest, changes chan

ctx = ctxlog.NewContext(ctx, w.logger)

runLauncherErrs := make(chan error)

go func() {
err := runLauncher(ctx, cancel, w.slogger, w.systemSlogger, w.opts)
if err != nil {
level.Info(w.logger).Log("msg", "runLauncher exited", "err", err)
level.Debug(w.logger).Log("msg", "runLauncher exited", "err", err, "stack", fmt.Sprintf("%+v", err))
changes <- svc.Status{State: svc.Stopped, Accepts: cmdsAccepted}
os.Exit(1)
runLauncherErrs <- fmt.Errorf("runLauncher exited with error: %w", err)
}

// If we get here, it means runLauncher returned nil. If we do
// nothing, the service is left running, but with no
// functionality. Instead, signal that as a stop to the service
// manager, and exit. We rely on the service manager to restart.
level.Info(w.logger).Log("msg", "runLauncher exited cleanly")
changes <- svc.Status{State: svc.Stopped, Accepts: cmdsAccepted}
os.Exit(0)
runLauncherErrs <- errors.New("runLauncher exited cleanly")
}()

for {
Expand All @@ -232,6 +233,13 @@ func (w *winSvc) Execute(args []string, r <-chan svc.ChangeRequest, changes chan
default:
level.Info(w.logger).Log("msg", "unexpected change request", "change_request", fmt.Sprintf("%+v", c))
}
case e := <-runLauncherErrs:
level.Info(w.logger).Log("msg", "received notice of runLauncher termination, marking service as stopped", "err", e)
changes <- svc.Status{State: svc.StopPending}
cancel()
time.Sleep(2 * time.Second) // give rungroups enough time to shut down
changes <- svc.Status{State: svc.Stopped, Accepts: cmdsAccepted}
return ssec, errno
}
}
}
11 changes: 5 additions & 6 deletions pkg/execwrapper/exec_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package execwrapper

import (
"context"
"errors"
"fmt"
"os"
"os/exec"
Expand All @@ -32,24 +31,24 @@ func Exec(ctx context.Context, argv0 string, argv []string, envv []string) error
)

// Now run it. This is faking exec, we need to distinguish
// between a failure to execute, and a failure in in the called program.
// between a failure to execute, and a failure in the called program.
// I think https://github.com/golang/go/issues/26539 adds this functionality.
err := cmd.Run()

if cmd.ProcessState.ExitCode() == -1 {
if err == nil {
return fmt.Errorf("Unknown error trying to exec %s (and nil err)", strings.Join(cmd.Args, " "))
return fmt.Errorf("unknown error trying to exec %s (and nil err)", strings.Join(cmd.Args, " "))
}
return fmt.Errorf("Unknown error trying to exec %s: %w", strings.Join(cmd.Args, " "), err)
return fmt.Errorf("unknown error trying to exec %s: %w", strings.Join(cmd.Args, " "), err)
}

if err != nil {
level.Info(logger).Log(
"msg", "got error on exec",
"err", err,
"exit_code", cmd.ProcessState.ExitCode(),
)
}
os.Exit(cmd.ProcessState.ExitCode())
return errors.New("Exec shouldn't have gotten here.")

return fmt.Errorf("error trying to exec %s: exit code %d: %w", strings.Join(cmd.Args, " "), cmd.ProcessState.ExitCode(), err)
}
11 changes: 9 additions & 2 deletions pkg/osquery/runtime/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,17 @@ func (r *Runner) Start() error {
}
if err := r.launchOsqueryInstance(); err != nil {
level.Info(r.instance.logger).Log(
"msg", "fatal error restarting instance",
"msg", "fatal error restarting instance, shutting down",
"err", err,
)
os.Exit(1)
r.instanceLock.Unlock()
if err := r.Shutdown(); err != nil {
level.Error(r.instance.logger).Log(
"msg", "could not perform shutdown",
"err", err,
)
}
return
}

r.instanceLock.Unlock()
Expand Down

0 comments on commit e43c36b

Please sign in to comment.