Merge pull request #10851 from Luap99/service-reaper
podman service reaper
This commit is contained in:
commit
878a2231f9
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue