Skip to content

Commit

Permalink
fix --init with /dev bind mount
Browse files Browse the repository at this point in the history
The init binary until now has been bind-mounted to /dev/init which
breaks when bind-mounting to /dev.  Instead mount the init to
/run/podman-init.  The reasoning for using /run is that it is already
used for other runtime data such as secrets.

Fixes: containers#14251
Signed-off-by: Valentin Rothberg <[email protected]>
  • Loading branch information
vrothberg authored and cdoern committed May 27, 2022
1 parent ec01504 commit 8ff7108
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 19 deletions.
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-create.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ content that disappears when the container is stopped.
#### **--init**

Run an init inside the container that forwards signals and reaps processes.
The container-init binary is mounted at `/run/podman-init`.
Mounting over `/run` will hence break container execution.

#### **--init-ctr**=*type* (pods only)

Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-run.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ content that disappears when the container is stopped.
#### **--init**

Run an init inside the container that forwards signals and reaps processes.
The container-init binary is mounted at `/run/podman-init`.
Mounting over `/run` will hence break container execution.

#### **--init-path**=*path*

Expand Down
2 changes: 2 additions & 0 deletions libpod/define/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ const (
// OneShotInitContainer is a container that only runs as init once
// and is then deleted.
OneShotInitContainer = "once"
// ContainerInitPath is the default path of the mounted container init.
ContainerInitPath = "/run/podman-init"
)
23 changes: 12 additions & 11 deletions libpod/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
)

var initInodes = map[string]bool{
"/dev": true,
"/etc/hostname": true,
"/etc/hosts": true,
"/etc/resolv.conf": true,
"/proc": true,
"/run": true,
"/run/notify": true,
"/run/.containerenv": true,
"/run/secrets": true,
"/sys": true,
"/etc/mtab": true,
"/dev": true,
"/etc/hostname": true,
"/etc/hosts": true,
"/etc/resolv.conf": true,
"/proc": true,
"/run": true,
"/run/notify": true,
"/run/.containerenv": true,
"/run/secrets": true,
define.ContainerInitPath: true,
"/sys": true,
"/etc/mtab": true,
}

// GetDiff returns the differences between the two images, layers, or containers
Expand Down
2 changes: 1 addition & 1 deletion pkg/specgen/generate/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData, rtc *c
if initPath == "" {
return nil, errors.Errorf("no path to init binary found but container requested an init")
}
finalCommand = append([]string{"/dev/init", "--"}, finalCommand...)
finalCommand = append([]string{define.ContainerInitPath, "--"}, finalCommand...)
}

return finalCommand, nil
Expand Down
6 changes: 2 additions & 4 deletions pkg/specgen/generate/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ import (
"github.com/sirupsen/logrus"
)

var (
errDuplicateDest = errors.Errorf("duplicate mount destination")
)
var errDuplicateDest = errors.Errorf("duplicate mount destination")

// Produce final mounts and named volumes for a container
func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, img *libimage.Image) ([]spec.Mount, []*specgen.NamedVolume, []*specgen.OverlayVolume, error) {
Expand Down Expand Up @@ -359,7 +357,7 @@ func getVolumesFrom(volumesFrom []string, runtime *libpod.Runtime) (map[string]s
// This does *NOT* modify the container command - that must be done elsewhere.
func addContainerInitBinary(s *specgen.SpecGenerator, path string) (spec.Mount, error) {
mount := spec.Mount{
Destination: "/dev/init",
Destination: define.ContainerInitPath,
Type: define.TypeBind,
Source: path,
Options: []string{define.TypeBind, "ro"},
Expand Down
8 changes: 5 additions & 3 deletions test/e2e/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/containers/common/pkg/cgroups"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
. "github.com/containers/podman/v4/test/utils"
"github.com/containers/storage/pkg/stringid"
Expand Down Expand Up @@ -286,19 +287,20 @@ var _ = Describe("Podman run", func() {
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
conData := result.InspectContainerToJSON()
Expect(conData[0]).To(HaveField("Path", "/dev/init"))
Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath))
Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE"))
})

It("podman run a container with --init and --init-path", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
// Also bind-mount /dev (#14251).
session := podmanTest.Podman([]string{"run", "-v", "/dev:/dev", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
conData := result.InspectContainerToJSON()
Expect(conData[0]).To(HaveField("Path", "/dev/init"))
Expect(conData[0]).To(HaveField("Path", define.ContainerInitPath))
Expect(conData[0].Config.Annotations).To(HaveKeyWithValue("io.podman.annotations.init", "TRUE"))
})

Expand Down

0 comments on commit 8ff7108

Please sign in to comment.