From 24267452e61f9694590766a498275b1f29348284 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Tue, 8 Apr 2025 11:56:21 -0400 Subject: [PATCH] Handle signal preventing Start from completing In the instance where the user sends a signal, such as SIGINT (Ctl-c) when a Podman Machine is in the middle of starting, make sure the state doesn't get stuck in the "Currently Starting" status. Resolves: #24416 Signed-off-by: Jake Correnti --- pkg/machine/shim/host.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pkg/machine/shim/host.go b/pkg/machine/shim/host.go index ad1d9ff4bf..3b368b4a87 100644 --- a/pkg/machine/shim/host.go +++ b/pkg/machine/shim/host.go @@ -6,10 +6,12 @@ import ( "fmt" "io" "os" + "os/signal" "path" "path/filepath" "runtime" "strings" + "syscall" "time" "github.com/containers/podman/v5/pkg/machine" @@ -440,6 +442,7 @@ func stopLocked(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *mach func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDefine.MachineDirs, opts machine.StartOptions) error { defaultBackoff := 500 * time.Millisecond maxBackoffs := 6 + signalChanClosed := false mc.Lock() defer mc.Unlock() @@ -471,17 +474,41 @@ func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDe } } + // if the machine cannot continue starting due to a signal, ensure the state + // reflects the machine is no longer starting + signalChan := make(chan os.Signal, 1) + signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) + go func() { + sig, ok := <-signalChan + if ok { + mc.Starting = false + logrus.Error("signal received when starting the machine: ", sig) + + if err := mc.Write(); err != nil { + logrus.Error(err) + } + + os.Exit(1) + } + }() + // Set starting to true mc.Starting = true if err := mc.Write(); err != nil { logrus.Error(err) } + // Set starting to false on exit defer func() { mc.Starting = false if err := mc.Write(); err != nil { logrus.Error(err) } + + if !signalChanClosed { + signal.Stop(signalChan) + close(signalChan) + } }() gvproxyPidFile, err := dirs.RuntimeDir.AppendToNewVMFile("gvproxy.pid", nil) @@ -557,6 +584,11 @@ func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, dirs *machineDe return errors.New(msg) } + // now that the machine has transitioned into the running state, we don't need a goroutine listening for SIGINT or SIGTERM to handle state + signal.Stop(signalChan) + close(signalChan) + signalChanClosed = true + if err := proxyenv.ApplyProxies(mc); err != nil { return err }