From 3e660a74f2a7613c11a379daaf485092795874c2 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Fri, 25 Mar 2022 09:45:45 -0400 Subject: [PATCH 2/2] Add support for Sharable Signed-off-by: Daniel J Walsh --- pkg/namespaces/namespaces.go | 2 +- pkg/specgen/container_validate.go | 6 ++--- pkg/specgen/generate/namespaces.go | 2 +- pkg/specgen/namespaces.go | 37 +++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index a7736aee0..a264a5a0f 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -254,7 +254,7 @@ func (n IpcMode) IsHost() bool { return n == hostType } -// IsShareable indicates whether the container's ipc namespace can be shared with another container. +// IsShareable indicates whether the container uses its own shareable ipc namespace which can be shared. func (n IpcMode) IsShareable() bool { return n == shareableType } diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go index a279b8a62..e71eafb75 100644 --- a/pkg/specgen/container_validate.go +++ b/pkg/specgen/container_validate.go @@ -76,8 +76,8 @@ func (s *SpecGenerator) Validate() error { s.ContainerStorageConfig.ImageVolumeMode, strings.Join(ImageVolumeModeValues, ",")) } // shmsize conflicts with IPC namespace - if s.ContainerStorageConfig.ShmSize != nil && !s.ContainerStorageConfig.IpcNS.IsPrivate() { - return errors.New("cannot set shmsize when running in the host IPC Namespace") + if s.ContainerStorageConfig.ShmSize != nil && (s.ContainerStorageConfig.IpcNS.IsHost() || s.ContainerStorageConfig.IpcNS.IsNone()) { + return errors.Errorf("cannot set shmsize when running in the %s IPC Namespace", s.ContainerStorageConfig.IpcNS) } // @@ -166,7 +166,7 @@ func (s *SpecGenerator) Validate() error { if err := s.UtsNS.validate(); err != nil { return err } - if err := s.IpcNS.validate(); err != nil { + if err := validateIPCNS(&s.IpcNS); err != nil { return err } if err := s.PidNS.validate(); err != nil { diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 3f77cbe76..9ce45aaf0 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -59,7 +59,7 @@ func GetDefaultNamespaceMode(nsType string, cfg *config.Config, pod *libpod.Pod) case "pid": return specgen.ParseNamespace(cfg.Containers.PidNS) case "ipc": - return specgen.ParseNamespace(cfg.Containers.IPCNS) + return specgen.ParseIPCNamespace(cfg.Containers.IPCNS) case "uts": return specgen.ParseNamespace(cfg.Containers.UTSNS) case "user": diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index e672bc65f..4412eff29 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -35,6 +35,10 @@ const ( FromPod NamespaceMode = "pod" // Private indicates the namespace is private Private NamespaceMode = "private" + // Shareable indicates the namespace is shareable + Shareable NamespaceMode = "shareable" + // None indicates the IPC namespace is created without mounting /dev/shm + None NamespaceMode = "none" // NoNetwork indicates no network namespace should // be joined. loopback should still exists. // Only used with the network namespace, invalid otherwise. @@ -77,6 +81,11 @@ func (n *Namespace) IsHost() bool { return n.NSMode == Host } +// IsNone returns a bool if the namespace is set to none +func (n *Namespace) IsNone() bool { + return n.NSMode == None +} + // IsBridge returns a bool if the namespace is a Bridge func (n *Namespace) IsBridge() bool { return n.NSMode == Bridge @@ -158,6 +167,17 @@ func validateNetNS(n *Namespace) error { return nil } +func validateIPCNS(n *Namespace) error { + if n == nil { + return nil + } + switch n.NSMode { + case Shareable, None: + return nil + } + return n.validate() +} + // Validate perform simple validation on the namespace to make sure it is not // invalid from the get-go func (n *Namespace) validate() error { @@ -237,7 +257,7 @@ func ParseCgroupNamespace(ns string) (Namespace, error) { case "private", "": toReturn.NSMode = Private default: - return toReturn, errors.Errorf("unrecognized namespace mode %s passed", ns) + return toReturn, errors.Errorf("unrecognized cgroup namespace mode %s passed", ns) } } else { toReturn.NSMode = Host @@ -245,6 +265,21 @@ func ParseCgroupNamespace(ns string) (Namespace, error) { return toReturn, nil } +// ParseIPCNamespace parses a ipc namespace specification in string +// form. +func ParseIPCNamespace(ns string) (Namespace, error) { + toReturn := Namespace{} + switch { + case ns == "shareable", ns == "": + toReturn.NSMode = Shareable + return toReturn, nil + case ns == "none": + toReturn.NSMode = None + return toReturn, nil + } + return ParseNamespace(ns) +} + // ParseUserNamespace parses a user namespace specification in string // form. func ParseUserNamespace(ns string) (Namespace, error) { -- 2.35.1