Merge pull request #10851 from Luap99/service-reaper

podman service reaper
This commit is contained in:
OpenShift Merge Robot 2021-07-02 20:16:03 -04:00 committed by GitHub
commit 878a2231f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 0 deletions

View File

@ -12,6 +12,7 @@ import (
api "github.com/containers/podman/v3/pkg/api/server"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra"
"github.com/containers/podman/v3/pkg/servicereaper"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -71,6 +72,8 @@ func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entiti
return err
}
servicereaper.Start()
infra.StartWatcher(rt)
server, err := api.NewServerWithSettings(rt, listener, api.Options{Timeout: opts.Timeout, CorsHeaders: opts.CorsHeaders})
if err != nil {

View File

@ -18,6 +18,7 @@ import (
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootlessport"
"github.com/containers/podman/v3/pkg/servicereaper"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@ -299,6 +300,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
return errors.Wrapf(err, "failed to start slirp4netns process")
}
defer func() {
servicereaper.AddPID(cmd.Process.Pid)
if err := cmd.Process.Release(); err != nil {
logrus.Errorf("unable to release command process: %q", err)
}
@ -514,6 +516,7 @@ outer:
return errors.Wrapf(err, "failed to start rootlessport process")
}
defer func() {
servicereaper.AddPID(cmd.Process.Pid)
if err := cmd.Process.Release(); err != nil {
logrus.Errorf("unable to release rootlessport process: %q", err)
}

View File

@ -0,0 +1,64 @@
//+build linux
package servicereaper
import (
"os"
"os/signal"
"sync"
"syscall"
"github.com/sirupsen/logrus"
)
type service struct {
pidMap map[int]bool
mutex *sync.Mutex
}
var s = service{
pidMap: map[int]bool{},
mutex: &sync.Mutex{},
}
func AddPID(pid int) {
s.mutex.Lock()
s.pidMap[pid] = true
s.mutex.Unlock()
}
func Start() {
// create signal channel and only wait for SIGCHLD
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGCHLD)
// wait and reap in an extra goroutine
go reaper(sigc)
}
func reaper(sigc chan os.Signal) {
for {
// block until we receive SIGCHLD
<-sigc
s.mutex.Lock()
for pid := range s.pidMap {
var status syscall.WaitStatus
waitpid, err := syscall.Wait4(pid, &status, syscall.WNOHANG, nil)
if err != nil {
// do not log error for ECHILD
if err != syscall.ECHILD {
logrus.Warnf("wait for pid %d failed: %v ", pid, err)
}
delete(s.pidMap, pid)
continue
}
// if pid == 0 nothing happened
if waitpid == 0 {
continue
}
if status.Exited() {
delete(s.pidMap, pid)
}
}
s.mutex.Unlock()
}
}