Skip to content

Commit

Permalink
add support for limiting tmpfs size for systemd-specific mnts
Browse files Browse the repository at this point in the history
* add tests
* add documentation for --shm-size-systemd
* add support for both pod and standalone run

Signed-off-by: danishprakash <[email protected]>
  • Loading branch information
danishprakash committed Feb 14, 2023
1 parent 1e06c1a commit 0999991
Show file tree
Hide file tree
Showing 18 changed files with 118 additions and 3 deletions.
7 changes: 7 additions & 0 deletions cmd/podman/common/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,13 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(shmSizeFlagName, completion.AutocompleteNone)

shmSizeSystemdFlagName := "shm-size-systemd"
createFlags.String(
shmSizeSystemdFlagName, "",
"Size of systemd specific tmpfs mounts (/run, /run/lock) "+sizeWithUnitFormat,
)
_ = cmd.RegisterFlagCompletionFunc(shmSizeSystemdFlagName, completion.AutocompleteNone)

sysctlFlagName := "sysctl"
createFlags.StringSliceVar(
&cf.Sysctl,
Expand Down
3 changes: 3 additions & 0 deletions cmd/podman/containers/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
if c.Flag("shm-size").Changed {
vals.ShmSize = c.Flag("shm-size").Value.String()
}
if c.Flag("shm-size-systemd").Changed {
vals.ShmSizeSystemd = c.Flag("shm-size-systemd").Value.String()
}
if (c.Flag("dns").Changed || c.Flag("dns-option").Changed || c.Flag("dns-search").Changed) && vals.Net != nil && (vals.Net.Network.NSMode == specgen.NoNetwork || vals.Net.Network.IsContainer()) {
return vals, fmt.Errorf("conflicting options: dns and the network mode: " + string(vals.Net.Network.NSMode))
}
Expand Down
10 changes: 10 additions & 0 deletions docs/source/markdown/options/shm-size-systemd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
####> This option file is used in:
####> podman create, pod clone, pod create, run
####> If file is edited, make sure the changes
####> are applicable to all of those.
#### **--shm-size-systemd**=*number[unit]*

Size of systemd-specific tmpfs mounts such as /run, /run/lock, /var/log/journal and /tmp.
A _unit_ can be **b** (bytes), **k** (kibibytes), **m** (mebibytes), or **g** (gibibytes).
If the unit is omitted, the system uses bytes. If the size is omitted, the default is **64m**.
When _size_ is **0**, the usage is limited to 50% of the host's available memory.
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-create.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ Automatically remove the container when it exits. The default is *false*.

@@option shm-size

@@option shm-size-systemd

@@option stop-signal

@@option stop-timeout
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-pod-clone.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ Set a custom name for the cloned pod. The default if not specified is of the syn

@@option shm-size

@@option shm-size-systemd

#### **--start**

When set to true, this flag starts the newly created pod after the
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-pod-create.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ Note: This options conflict with **--share=cgroup** since that would set the pod

@@option shm-size

@@option shm-size-systemd

@@option subgidname

@@option subuidname
Expand Down
2 changes: 2 additions & 0 deletions docs/source/markdown/podman-run.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ container is using it. The default is *false*.

@@option shm-size

@@option shm-size-systemd

@@option sig-proxy

The default is **true**.
Expand Down
3 changes: 3 additions & 0 deletions libpod/container_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ type ContainerRootFSConfig struct {
// ShmSize is the size of the container's SHM. Only used if ShmDir was
// not set manually at time of creation.
ShmSize int64 `json:"shmSize"`
// ShmSizeSystemd is the size of systemd-specific tmpfs mounts
ShmSizeSystemd int64 `json:"shmSizeSystemd"`
// Static directory for container content that will persist across
// reboot.
// StaticDir is a persistent directory for Libpod files that will
Expand Down Expand Up @@ -443,6 +445,7 @@ type InfraInherit struct {
SelinuxOpts []string `json:"selinux_opts,omitempty"`
Volumes []*specgen.NamedVolume `json:"volumes,omitempty"`
ShmSize *int64 `json:"shm_size"`
ShmSizeSystemd *int64 `json:"shm_size_systemd"`
}

// IsDefaultShmSize determines if the user actually set the shm in the parent ctr or if it has been set to the default size
Expand Down
10 changes: 8 additions & 2 deletions libpod/container_internal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
if !containerUUIDSet {
g.AddProcessEnv("container_uuid", c.ID()[:32])
}
// limit systemd-specific tmpfs mounts if specified
// while creating a pod or ctr, if not, default back to 50%
var shmSizeSystemdMntOpt string
if c.config.ShmSizeSystemd != 0 {
shmSizeSystemdMntOpt = fmt.Sprintf("size=%d", c.config.ShmSizeSystemd)
}
options := []string{"rw", "rprivate", "nosuid", "nodev"}
for _, dest := range []string{"/run", "/run/lock"} {
if MountExists(mounts, dest) {
Expand All @@ -214,7 +220,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: dest,
Type: "tmpfs",
Source: "tmpfs",
Options: append(options, "tmpcopyup"),
Options: append(options, "tmpcopyup", shmSizeSystemdMntOpt),
}
g.AddMount(tmpfsMnt)
}
Expand All @@ -226,7 +232,7 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro
Destination: dest,
Type: "tmpfs",
Source: "tmpfs",
Options: append(options, "tmpcopyup"),
Options: append(options, "tmpcopyup", shmSizeSystemdMntOpt),
}
g.AddMount(tmpfsMnt)
}
Expand Down
17 changes: 17 additions & 0 deletions libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,23 @@ func WithShmSize(size int64) CtrCreateOption {
}
}

// WithShmSizeSystemd sets the size of systemd-specific mounts:
//
// /run
// /run/lock
// /var/log/journal
// /tmp
func WithShmSizeSystemd(size int64) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}

ctr.config.ShmSizeSystemd = size
return nil
}
}

// WithPrivileged sets the privileged flag in the container runtime.
func WithPrivileged(privileged bool) CtrCreateOption {
return func(ctr *Container) error {
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/entities/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ type ContainerCreateOptions struct {
SecurityOpt []string `json:"security_opt,omitempty"`
SdNotifyMode string
ShmSize string
ShmSizeSystemd string
SignaturePolicy string
StartupHCCmd string
StartupHCInterval string
Expand All @@ -269,8 +270,8 @@ type ContainerCreateOptions struct {
StopSignal string
StopTimeout uint
StorageOpts []string
SubUIDName string
SubGIDName string
SubUIDName string
Sysctl []string `json:"sysctl,omitempty"`
Systemd string
Timeout uint
Expand Down
1 change: 1 addition & 0 deletions pkg/specgen/generate/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, containerID
specg.HostDeviceList = conf.DeviceHostSrc
specg.Networks = conf.Networks
specg.ShmSize = &conf.ShmSize
specg.ShmSizeSystemd = &conf.ShmSizeSystemd

mapSecurityConfig(conf, specg)

Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/generate/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,9 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
if s.ShmSize != nil {
options = append(options, libpod.WithShmSize(*s.ShmSize))
}
if s.ShmSizeSystemd != nil {
options = append(options, libpod.WithShmSizeSystemd(*s.ShmSizeSystemd))
}
if s.Rootfs != "" {
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay, s.RootfsMapping))
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/specgen/podspecgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ type PodStorageConfig struct {
// Conflicts with ShmSize if IpcNS is not private.
// Optional.
ShmSize *int64 `json:"shm_size,omitempty"`
// ShmSizeSystemd is the size of systemd-specific tmpfs mounts
// specifically /run, /run/lock, /var/log/journal and /tmp.
// Optional
ShmSizeSystemd *int64 `json:"shm_size_systemd,omitempty"`
}

// PodCgroupConfig contains configuration options about a pod's cgroups.
Expand Down
4 changes: 4 additions & 0 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ type ContainerStorageConfig struct {
// Conflicts with ShmSize if IpcNS is not private.
// Optional.
ShmSize *int64 `json:"shm_size,omitempty"`
// ShmSizeSystemd is the size of systemd-specific tmpfs mounts
// specifically /run, /run/lock, /var/log/journal and /tmp.
// Optional
ShmSizeSystemd *int64 `json:"shm_size_systemd,omitempty"`
// WorkDir is the container's working directory.
// If unset, the default, /, will be used.
// Optional.
Expand Down
10 changes: 10 additions & 0 deletions pkg/specgenutil/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,16 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
s.ShmSize = &val
}

// SHM Size Systemd
if c.ShmSizeSystemd != "" {
val, err := units.RAMInBytes(c.ShmSizeSystemd)
if err != nil {
return fmt.Errorf("unable to translate --shm-size-systemd: %w", err)
}

s.ShmSizeSystemd = &val
}

if c.Net != nil {
s.Networks = c.Net.Networks
}
Expand Down
20 changes: 20 additions & 0 deletions test/e2e/pod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1193,4 +1193,24 @@ ENTRYPOINT ["sleep","99999"]
podJSON := podInspect.InspectPodToJSON()
Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns))
})

It("podman pod create --shm-size-systemd", func() {
podName := "testShmSizeSystemd"
session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--shm-size-systemd", "10mb"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

// add container to pod
ctrRun := podmanTest.Podman([]string{"run", "-d", "--pod", podName, SYSTEMD_IMAGE, "/sbin/init"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(Exit(0))

run := podmanTest.Podman([]string{"exec", ctrRun.OutputToString(), "mount"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
t, strings := run.GrepString("tmpfs on /run/lock")
Expect(t).To(BeTrue())
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
})

})
18 changes: 18 additions & 0 deletions test/e2e/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2053,4 +2053,22 @@ WORKDIR /madethis`, BB)
Expect(session).Should(Exit(0))
Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
})

It("podman run --shm-size-systemd", func() {
ctrName := "testShmSizeSystemd"
run := podmanTest.Podman([]string{"run", "--name", ctrName, "--shm-size-systemd", "10mb", "-d", SYSTEMD_IMAGE, "/sbin/init"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))

logs := podmanTest.Podman([]string{"logs", ctrName})
logs.WaitWithDefaultTimeout()
Expect(logs).Should(Exit(0))

mount := podmanTest.Podman([]string{"exec", ctrName, "mount"})
mount.WaitWithDefaultTimeout()
Expect(mount).Should(Exit(0))
t, strings := mount.GrepString("tmpfs on /run/lock")
Expect(t).To(BeTrue())
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
})
})

0 comments on commit 0999991

Please sign in to comment.