From 838da8e1c9d9f64e0fa44db03723e992b3557538 Mon Sep 17 00:00:00 2001 From: Carlos Nihelton Date: Tue, 18 Jun 2024 15:43:51 -0300 Subject: [PATCH] Sets some best-effort timeouts Those functions used the background context. When wslservice.exe hangs/crashes, wsl.exe commands might hang for very long. We're setting some generous timeouts to couple with a variety of hardware. In the happy paths, 1/100th to 1/10th of those timeouts should be enough. --- internal/backend/windows/wslexe_windows.go | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/internal/backend/windows/wslexe_windows.go b/internal/backend/windows/wslexe_windows.go index a4adb31..f61a68d 100644 --- a/internal/backend/windows/wslexe_windows.go +++ b/internal/backend/windows/wslexe_windows.go @@ -6,10 +6,12 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "os" "os/exec" "strings" + "time" "github.com/ubuntu/gowsl/internal/state" ) @@ -19,8 +21,13 @@ import ( // It is analogous to // // `wsl.exe --Shutdown +var ErrWslTimeout = errors.New("wsl.exe did not respond: consider restarting wslservice.exe") + func (Backend) Shutdown() error { - _, err := wslExe(context.Background(), "--shutdown") + ctx, cancel := context.WithTimeoutCause(context.Background(), 10*time.Second, ErrWslTimeout) + defer cancel() + + _, err := wslExe(ctx, "--shutdown") if err != nil { return fmt.Errorf("could not shut WSL down: %w", err) } @@ -33,7 +40,10 @@ func (Backend) Shutdown() error { // // `wsl.exe --Terminate ` func (Backend) Terminate(distroName string) error { - _, err := wslExe(context.Background(), "--terminate", distroName) + ctx, cancel := context.WithTimeoutCause(context.Background(), 3*time.Second, ErrWslTimeout) + defer cancel() + + _, err := wslExe(ctx, "--terminate", distroName) if err != nil { return fmt.Errorf("could not terminate distro %q: %w", distroName, err) } @@ -46,7 +56,10 @@ func (Backend) Terminate(distroName string) error { // // `wsl.exe --set-default ` func (Backend) SetAsDefault(distroName string) error { - _, err := wslExe(context.Background(), "--set-default", distroName) + ctx, cancel := context.WithTimeoutCause(context.Background(), 1*time.Second, ErrWslTimeout) + defer cancel() + + _, err := wslExe(ctx, "--set-default", distroName) if err != nil { return fmt.Errorf("could not set %q as default: %w", distroName, err) } @@ -55,7 +68,10 @@ func (Backend) SetAsDefault(distroName string) error { // State returns the state of a particular distro as seen in `wsl.exe -l -v`. func (Backend) State(distributionName string) (s state.State, err error) { - out, err := wslExe(context.Background(), "--list", "--all", "--verbose") + ctx, cancel := context.WithTimeoutCause(context.Background(), 1*time.Second, ErrWslTimeout) + defer cancel() + + out, err := wslExe(ctx, "--list", "--all", "--verbose") if err != nil { return s, fmt.Errorf("could not get states of distros: %w", err) }