oci: fix WithDevShmSize

Signed-off-by: Iceber Gu <wei.cai-nat@daocloud.io>
This commit is contained in:
Iceber Gu 2021-02-23 13:09:20 +08:00
parent a5d17eb507
commit b592a4c1ec
No known key found for this signature in database
GPG Key ID: F1632F7124070DD4
2 changed files with 87 additions and 39 deletions

View File

@ -1228,16 +1228,16 @@ var ErrNoShmMount = errors.New("no /dev/shm mount specified")
// //
// The size value is specified in kb, kilobytes. // The size value is specified in kb, kilobytes.
func WithDevShmSize(kb int64) SpecOpts { func WithDevShmSize(kb int64) SpecOpts {
return func(ctx context.Context, _ Client, c *containers.Container, s *Spec) error { return func(ctx context.Context, _ Client, _ *containers.Container, s *Spec) error {
for _, m := range s.Mounts { for i, m := range s.Mounts {
if m.Source == "shm" && m.Type == "tmpfs" { if filepath.Clean(m.Destination) == "/dev/shm" && m.Source == "shm" && m.Type == "tmpfs" {
for i, o := range m.Options { for i := 0; i < len(m.Options); i++ {
if strings.HasPrefix(o, "size=") { if strings.HasPrefix(m.Options[i], "size=") {
m.Options[i] = fmt.Sprintf("size=%dk", kb) m.Options = append(m.Options[:i], m.Options[i+1:]...)
return nil i--
} }
} }
m.Options = append(m.Options, fmt.Sprintf("size=%dk", kb)) s.Mounts[i].Options = append(m.Options, fmt.Sprintf("size=%dk", kb))
return nil return nil
} }
} }

View File

@ -25,6 +25,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"strings" "strings"
@ -551,53 +552,100 @@ func TestWithImageConfigArgs(t *testing.T) {
func TestDevShmSize(t *testing.T) { func TestDevShmSize(t *testing.T) {
t.Parallel() t.Parallel()
var (
s Spec
c = containers.Container{ID: t.Name()}
ctx = namespaces.WithNamespace(context.Background(), "test")
)
err := populateDefaultUnixSpec(ctx, &s, c.ID) ss := []Spec{
if err != nil { {
t.Fatal(err) Mounts: []specs.Mount{
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777"},
},
},
},
{
Mounts: []specs.Mount{
{
Destination: "/test/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
},
},
},
{
Mounts: []specs.Mount{
{
Destination: "/test/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
},
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k", "size=131072k"},
},
},
},
} }
expected := "1024k" expected := "1024k"
if err := WithDevShmSize(1024)(nil, nil, nil, &s); err != nil { for _, s := range ss {
t.Fatal(err) if err := WithDevShmSize(1024)(nil, nil, nil, &s); err != nil {
} if err != ErrNoShmMount {
m := getShmMount(&s) t.Fatal(err)
if m == nil { }
t.Fatal("no shm mount found")
} if getDevShmMount(&s) == nil {
o := getShmSize(m.Options) continue
if o == "" { }
t.Fatal("shm size not specified") t.Fatal("excepted nil /dev/shm mount")
} }
parts := strings.Split(o, "=")
if len(parts) != 2 { m := getDevShmMount(&s)
t.Fatal("invalid size format") if m == nil {
} t.Fatal("no shm mount found")
size := parts[1] }
if size != expected { size, err := getShmSize(m.Options)
t.Fatalf("size %s not equal %s", size, expected) if err != nil {
t.Fatal(err)
}
if size != expected {
t.Fatalf("size %s not equal %s", size, expected)
}
} }
} }
func getShmMount(s *Spec) *specs.Mount { func getDevShmMount(s *Spec) *specs.Mount {
for _, m := range s.Mounts { for _, m := range s.Mounts {
if m.Source == "shm" && m.Type == "tmpfs" { if filepath.Clean(m.Destination) == "/dev/shm" && m.Source == "shm" && m.Type == "tmpfs" {
return &m return &m
} }
} }
return nil return nil
} }
func getShmSize(opts []string) string { func getShmSize(opts []string) (string, error) {
// linux will use the last size option
var so string
for _, o := range opts { for _, o := range opts {
if strings.HasPrefix(o, "size=") { if strings.HasPrefix(o, "size=") {
return o if so != "" {
return "", errors.New("contains multiple size options")
}
so = o
} }
} }
return "" if so == "" {
return "", errors.New("shm size not specified")
}
parts := strings.Split(so, "=")
if len(parts) != 2 {
return "", errors.New("invalid size format")
}
return parts[1], nil
} }