diff options
-rw-r--r-- | cmd/podman/system/service_abi.go | 3 | ||||
-rw-r--r-- | docs/source/markdown/podman-search.1.md | 11 | ||||
-rw-r--r-- | libpod/networking_slirp4netns.go | 3 | ||||
-rw-r--r-- | pkg/machine/qemu/machine.go | 22 | ||||
-rw-r--r-- | pkg/servicereaper/service.go | 64 |
5 files changed, 95 insertions, 8 deletions
diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go index d59a45564..e484db339 100644 --- a/cmd/podman/system/service_abi.go +++ b/cmd/podman/system/service_abi.go @@ -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 { diff --git a/docs/source/markdown/podman-search.1.md b/docs/source/markdown/podman-search.1.md index ec610d3ba..661ad6742 100644 --- a/docs/source/markdown/podman-search.1.md +++ b/docs/source/markdown/podman-search.1.md @@ -9,13 +9,18 @@ podman\-search - Search a registry for an image ## DESCRIPTION **podman search** searches a registry or a list of registries for a matching image. The user can specify which registry to search by prefixing the registry in the search term -(example **registry.fedoraproject.org/fedora**), default is the registries in the -**registries.search** table in the config file - **/etc/containers/registries.conf**. +(e.g., **registry.fedoraproject.org/fedora**). By default, all +unqualified-search registries in `containers-registries.conf(5)` are used. + The default number of results is 25. The number of results can be limited using the **--limit** flag. If more than one registry is being searched, the limit will be applied to each registry. The output can be filtered using the **--filter** flag. To get all available images in a registry without a specific search term, the user can just enter the registry name with a trailing "/" (example **registry.fedoraproject.org/**). -Note, searching without a search term will only work for registries that implement the v2 API. + +Note that **podman search** is not a reliable way to determine the presence or existence of an image. +The search behavior of the v1 and v2 Docker distribution API is specific to the implementation of each registry. +Some registries may not support searching at all. +Further note that searching without a search term will only work for registries that implement the v2 API. **podman [GLOBAL OPTIONS]** diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index 74d390d29..410b377ec 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -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) } diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 22fb78a5c..42ae23c43 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -15,9 +15,8 @@ import ( "strings" "time" - "github.com/containers/podman/v3/pkg/rootless" - "github.com/containers/podman/v3/pkg/machine" + "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/utils" "github.com/containers/storage/pkg/homedir" "github.com/digitalocean/go-qemu/qmp" @@ -248,7 +247,23 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { if err := v.startHostNetworking(); err != nil { return errors.Errorf("unable to start host networking: %q", err) } + + rtPath, err := getRuntimeDir() + if err != nil { + return err + } + + // If the temporary podman dir is not created, create it + podmanTempDir := filepath.Join(rtPath, "podman") + if _, err := os.Stat(podmanTempDir); os.IsNotExist(err) { + if mkdirErr := os.MkdirAll(podmanTempDir, 0755); mkdirErr != nil { + return err + } + } qemuSocketPath, _, err := v.getSocketandPid() + if err != nil { + return err + } for i := 0; i < 6; i++ { qemuSocketConn, err = net.Dial("unix", qemuSocketPath) @@ -258,9 +273,6 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { time.Sleep(wait) wait++ } - if err != nil { - return err - } fd, err := qemuSocketConn.(*net.UnixConn).File() if err != nil { diff --git a/pkg/servicereaper/service.go b/pkg/servicereaper/service.go new file mode 100644 index 000000000..e9c4fe908 --- /dev/null +++ b/pkg/servicereaper/service.go @@ -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() + } +} |