Skip to content

Commit 233c0ff

Browse files
committed
vfkit: More robust Stop()
If setting vfkit state to "Stop" fails, we used to return an error. Retrying the operation may never succeed. Fix by falling back to terminating vfkit using a signal. This terminates vfkit immediately similar to HardStop[1]. We can still fail if the pidfile is corrupted but this is unlikely and requires manual cleanup. In the case when we are sure the vfkit process does not exist, we remove the pidfile immediately, avoiding leftover pidfile if the caller does not call GetState() after Stop(). [1] crc-org/vfkit#284
1 parent a51c3fe commit 233c0ff

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

pkg/drivers/vfkit/vfkit.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,29 @@ func isBootpdError(err error) bool {
297297

298298
func (d *Driver) Stop() error {
299299
if err := d.SetVFKitState("Stop"); err != nil {
300-
return err
300+
// vfkit may be already stopped, shutting down, or not listening.
301+
// We don't fallback to "HardStop" since it typically fails due to
302+
// https://github.com/crc-org/vfkit/issues/277.
303+
log.Debugf("Failed to set vfkit state to 'Stop': %s", err)
304+
pidfile := d.pidfilePath()
305+
pid, err := process.ReadPidfile(pidfile)
306+
if err != nil {
307+
if !errors.Is(err, os.ErrNotExist) {
308+
return err
309+
}
310+
// No pidfile.
311+
return nil
312+
}
313+
if err := process.Terminate(pid, "vfkit"); err != nil {
314+
if err != os.ErrProcessDone {
315+
return err
316+
}
317+
// No process, stale pidfile.
318+
if err := os.Remove(pidfile); err != nil {
319+
log.Debugf("failed to remove %q: %s", pidfile, err)
320+
}
321+
return nil
322+
}
301323
}
302324
return nil
303325
}

0 commit comments

Comments
 (0)