Skip to content

Commit 077b000

Browse files
Merge pull request #20995 from mheon/error_on_gvproxy_exit
Error on HyperV VM start when gvproxy has failed to start
2 parents fb9e9de + 5cc5b43 commit 077b000

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

pkg/machine/hyperv/machine.go

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/containers/podman/v4/pkg/util"
2828
"github.com/containers/podman/v4/utils"
2929
"github.com/containers/storage/pkg/lockfile"
30+
psutil "github.com/shirou/gopsutil/v3/process"
3031
"github.com/sirupsen/logrus"
3132
)
3233

@@ -578,7 +579,7 @@ func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
578579
if vm.State() != hypervctl.Disabled {
579580
return hypervctl.ErrMachineStateInvalid
580581
}
581-
_, _, err = m.startHostNetworking()
582+
gvproxyPid, _, _, err := m.startHostNetworking()
582583
if err != nil {
583584
return fmt.Errorf("unable to start host networking: %q", err)
584585
}
@@ -601,19 +602,34 @@ func (m *HyperVMachine) Start(name string, opts machine.StartOptions) error {
601602
// set starting back false now that we are running
602603
m.Starting = false
603604

604-
if err := m.startShares(); err != nil {
605-
return err
606-
}
607-
608605
if m.HostUser.Modified {
609606
if machine.UpdatePodmanDockerSockService(m, name, m.UID, m.Rootful) == nil {
610607
// Reset modification state if there are no errors, otherwise ignore errors
611608
// which are already logged
612609
m.HostUser.Modified = false
613610
}
614611
}
612+
615613
// Write the config with updated starting status and hostuser modification
616-
return m.writeConfig()
614+
if err := m.writeConfig(); err != nil {
615+
return err
616+
}
617+
618+
// Check if gvproxy is still running.
619+
// Do this *after* we write config, so we have still recorded that the
620+
// VM is actually running - to ensure that stopping the machine works as
621+
// expected.
622+
_, err = psutil.NewProcess(gvproxyPid)
623+
if err != nil {
624+
return fmt.Errorf("gvproxy appears to have stopped (PID %d): %w", gvproxyPid, err)
625+
}
626+
627+
// Finalize starting shares after we are confident gvproxy is still alive.
628+
if err := m.startShares(); err != nil {
629+
return err
630+
}
631+
632+
return nil
617633
}
618634

619635
func (m *HyperVMachine) State(_ bool) (define.Status, error) {
@@ -735,24 +751,24 @@ func (m *HyperVMachine) loadHyperVMachineFromJSON(fqConfigPath string) error {
735751
return json.Unmarshal(b, m)
736752
}
737753

738-
func (m *HyperVMachine) startHostNetworking() (string, machine.APIForwardingState, error) {
754+
func (m *HyperVMachine) startHostNetworking() (int32, string, machine.APIForwardingState, error) {
739755
var (
740756
forwardSock string
741757
state machine.APIForwardingState
742758
)
743759
cfg, err := config.Default()
744760
if err != nil {
745-
return "", machine.NoForwarding, err
761+
return -1, "", machine.NoForwarding, err
746762
}
747763

748764
executable, err := os.Executable()
749765
if err != nil {
750-
return "", 0, fmt.Errorf("unable to locate executable: %w", err)
766+
return -1, "", 0, fmt.Errorf("unable to locate executable: %w", err)
751767
}
752768

753769
gvproxyBinary, err := cfg.FindHelperBinary("gvproxy.exe", false)
754770
if err != nil {
755-
return "", 0, err
771+
return -1, "", 0, err
756772
}
757773

758774
cmd := gvproxy.NewGvproxyCommand()
@@ -769,20 +785,20 @@ func (m *HyperVMachine) startHostNetworking() (string, machine.APIForwardingStat
769785

770786
if logrus.IsLevelEnabled(logrus.DebugLevel) {
771787
if err := logCommandToFile(c, "gvproxy.log"); err != nil {
772-
return "", 0, err
788+
return -1, "", 0, err
773789
}
774790
}
775791

776792
logrus.Debugf("Starting gvproxy with command: %s %v", gvproxyBinary, c.Args)
777793

778794
if err := c.Start(); err != nil {
779-
return "", 0, fmt.Errorf("unable to execute: %s: %w", cmd.ToCmdline(), err)
795+
return -1, "", 0, fmt.Errorf("unable to execute: %s: %w", cmd.ToCmdline(), err)
780796
}
781797

782798
logrus.Debugf("Got gvproxy PID as %d", c.Process.Pid)
783799

784800
if len(m.MountVsocks) == 0 {
785-
return forwardSock, state, nil
801+
return int32(c.Process.Pid), forwardSock, state, nil
786802
}
787803

788804
// Start the 9p server in the background
@@ -807,17 +823,17 @@ func (m *HyperVMachine) startHostNetworking() (string, machine.APIForwardingStat
807823

808824
if logrus.IsLevelEnabled(logrus.DebugLevel) {
809825
if err := logCommandToFile(fsCmd, "podman-machine-server9.log"); err != nil {
810-
return "", 0, err
826+
return -1, "", 0, err
811827
}
812828
}
813829

814830
if err := fsCmd.Start(); err != nil {
815-
return "", 0, fmt.Errorf("unable to execute: %s %v: %w", executable, args, err)
831+
return -1, "", 0, fmt.Errorf("unable to execute: %s %v: %w", executable, args, err)
816832
}
817833

818834
logrus.Infof("Started podman 9p server as PID %d", fsCmd.Process.Pid)
819835

820-
return forwardSock, state, nil
836+
return int32(c.Process.Pid), forwardSock, state, nil
821837
}
822838

823839
func logCommandToFile(c *exec.Cmd, filename string) error {

0 commit comments

Comments
 (0)