-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Fix signal handling during machine start on macOS #28991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c694574
37c8dea
2f3e645
f5d5159
12ea195
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ package machine | |
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "os" | ||
| "syscall" | ||
| "time" | ||
|
|
||
|
|
@@ -42,10 +43,10 @@ func backoffForProcess(p *psutil.Process) error { | |
| // double the time | ||
| sleepInterval += sleepInterval | ||
| } | ||
| return fmt.Errorf("process %d has not ended", p.Pid) | ||
| return fmt.Errorf("process has not ended (PID %d)", p.Pid) | ||
| } | ||
|
|
||
| // / waitOnProcess takes a pid and sends a sigterm to it. it then waits for the | ||
| // waitOnProcess takes a pid and sends a sigterm to it. it then waits for the | ||
| // process to not exist. if the sigterm does not end the process after an interval, | ||
| // then sigkill is sent. it also waits for the process to exit after the sigkill too. | ||
| func waitOnProcess(processID int) error { | ||
|
|
@@ -64,7 +65,35 @@ func waitOnProcess(processID int) error { | |
| return nil | ||
| } | ||
|
|
||
| if err := p.Kill(); err != nil { | ||
| // Start a goroutine that waits until the gvproxy process completes. | ||
| // This is necessary to reaps the process and so that Process.IsRunning() | ||
| // in backoffForProcess() returns false. Otherwise the process will | ||
| // be defunct and backoffForProcess fails because Process.IsRunning() | ||
| // returns true | ||
| go func() { | ||
| gv, err := os.FindProcess(processID) | ||
| if err != nil { | ||
| logrus.Errorf("failed to find process %d: %v", processID, err) | ||
| return | ||
| } | ||
| if _, err = gv.Wait(); err != nil { | ||
| logrus.Debugf("gvproxy exited: %v", err) | ||
| } | ||
| }() | ||
|
|
||
| if err = p.Terminate(); err != nil { | ||
| if errors.Is(err, syscall.ESRCH) { | ||
| logrus.Debugf("Gvproxy already dead, exiting cleanly") | ||
| return nil | ||
| } | ||
| return err | ||
| } | ||
|
|
||
| if err = backoffForProcess(p); err == nil { | ||
| return nil | ||
| } | ||
|
Comment on lines
+84
to
+94
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this? any reason why not just sigkill is enough? I don't thin gvpoxy has any state so I doubt it matters and I Rather safe the few lines of code.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trying with a sigterm and, if it fails, sending a sigkill seems cleaner. Especially because we are doing this for gvproxy, but we could (should?) reuse the cleanup code for other processes that are started as well. Also, the comment on this function already describes this behavior (the code was updated, but not the comment?), so I was trying to clean things up. |
||
|
|
||
| if err = p.Kill(); err != nil { | ||
| if errors.Is(err, syscall.ESRCH) { | ||
| logrus.Debugf("Gvproxy already dead, exiting cleanly") | ||
| return nil | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.