Skip to content

Commit 1390765

Browse files
committed
Option --overlay-size
1 parent d30c58e commit 1390765

File tree

4 files changed

+90
-5
lines changed

4 files changed

+90
-5
lines changed

runsc/boot/vfs.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,12 @@ func (c *containerMounter) configureOverlay(ctx context.Context, conf *config.Co
585585
// filesystem specific options.
586586
upperOpts := *lowerOpts
587587
upperOpts.GetFilesystemOptions = vfs.GetFilesystemOptions{InternalMount: true}
588+
if conf.GetOverlay2().Size() != "" {
589+
if upperOpts.GetFilesystemOptions.Data != "" {
590+
upperOpts.GetFilesystemOptions.Data += ","
591+
}
592+
upperOpts.GetFilesystemOptions.Data += "size=" + conf.GetOverlay2().Size()
593+
}
588594

589595
overlayOpts := *lowerOpts
590596
overlayOpts.GetFilesystemOptions = vfs.GetFilesystemOptions{InternalMount: true}

runsc/config/config.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -906,24 +906,42 @@ type Overlay2 struct {
906906
rootMount bool
907907
subMounts bool
908908
medium OverlayMedium
909+
// Size of overlay upper layer.
910+
// Passed as is to tmpfs mount, as `size={size}`.
911+
// Empty means use default.
912+
// Size is applied to each overlay independently and not shared by overlays.
913+
size string
909914
}
910915

911916
func defaultOverlay2() *Overlay2 {
912917
// Rootfs overlay is enabled by default and backed by a file in rootfs itself.
913918
return &Overlay2{rootMount: true, subMounts: false, medium: SelfOverlay}
914919
}
915920

921+
func setOverlay2Err(v string) error {
922+
return fmt.Errorf("expected format is --overlay2={mount}:{medium}[,size={size}], got %q", v)
923+
}
924+
925+
// `--overlay2=...` param `size=`.
926+
const overlay2SizeEq = "size="
927+
916928
// Set implements flag.Value. Set(String()) should be idempotent.
917929
func (o *Overlay2) Set(v string) error {
918930
if v == "none" {
919931
o.rootMount = false
920932
o.subMounts = false
921933
o.medium = NoOverlay
934+
o.size = ""
922935
return nil
923936
}
924-
vs := strings.Split(v, ":")
937+
parts := strings.Split(v, ",")
938+
if len(parts) < 1 {
939+
return setOverlay2Err(v)
940+
}
941+
942+
vs := strings.Split(parts[0], ":")
925943
if len(vs) != 2 {
926-
return fmt.Errorf("expected format is --overlay2={mount}:{medium}, got %q", v)
944+
return setOverlay2Err(v)
927945
}
928946

929947
switch mount := vs[0]; mount {
@@ -936,7 +954,24 @@ func (o *Overlay2) Set(v string) error {
936954
return fmt.Errorf("unexpected mount specifier for --overlay2: %q", mount)
937955
}
938956

939-
return o.medium.Set(vs[1])
957+
err := o.medium.Set(vs[1])
958+
if err != nil {
959+
return err
960+
}
961+
962+
if len(parts) == 1 {
963+
o.size = ""
964+
} else if len(parts) == 2 {
965+
sizeArg := parts[1]
966+
if !strings.HasPrefix(sizeArg, overlay2SizeEq) {
967+
return setOverlay2Err(v)
968+
}
969+
o.size = strings.TrimPrefix(sizeArg, overlay2SizeEq)
970+
} else {
971+
return setOverlay2Err(v)
972+
}
973+
974+
return nil
940975
}
941976

942977
// Get implements flag.Value.
@@ -958,7 +993,13 @@ func (o Overlay2) String() string {
958993
default:
959994
panic("invalid state of subMounts = true and rootMount = false")
960995
}
961-
return res + ":" + o.medium.String()
996+
997+
var sizeSuffix string
998+
if o.size != "" {
999+
sizeSuffix = fmt.Sprintf(":%s%s", overlay2SizeEq, o.size)
1000+
}
1001+
1002+
return res + ":" + o.medium.String() + sizeSuffix
9621003
}
9631004

9641005
// Enabled returns true if the overlay option is enabled for any mounts.
@@ -987,6 +1028,11 @@ func (o Overlay2) Medium() OverlayMedium {
9871028
return o.medium
9881029
}
9891030

1031+
// Size returns the overlay upper layer size, or empty string if default should be used.
1032+
func (o Overlay2) Size() string {
1033+
return o.size
1034+
}
1035+
9901036
// HostSettingsPolicy dictates how host settings should be handled.
9911037
type HostSettingsPolicy int
9921038

runsc/config/config_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ func TestInvalidFlags(t *testing.T) {
231231
value: "root:dir=tmp",
232232
error: "overlay host file directory should be an absolute path, got \"tmp\"",
233233
},
234+
{
235+
name: "overlay2",
236+
value: "root:memory,sz=sdg",
237+
error: "expected format is --overlay2",
238+
},
234239
} {
235240
t.Run(tc.name, func(t *testing.T) {
236241
testFlags := flag.NewFlagSet("test", flag.ContinueOnError)
@@ -781,3 +786,26 @@ root = "%s"
781786
}
782787

783788
}
789+
790+
func TestParseOverlay2(t *testing.T) {
791+
t.Run("Parse without size", func(t *testing.T) {
792+
o := Overlay2{}
793+
err := o.Set("all:memory")
794+
if err != nil {
795+
t.Fatalf("Set failed: %v", err)
796+
}
797+
if o.Size() != "" {
798+
t.Fatalf("Size mismatch, expecting empty string, got %q", o.Size())
799+
}
800+
})
801+
t.Run("Parse with size", func(t *testing.T) {
802+
o := Overlay2{}
803+
err := o.Set("all:memory,size=1g")
804+
if err != nil {
805+
t.Fatalf("Set failed: %v", err)
806+
}
807+
if o.Size() != "1g" {
808+
t.Fatalf("Size mismatch, expecting 1g, got %q", o.Size())
809+
}
810+
})
811+
}

runsc/config/flags.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,12 @@ func RegisterFlags(flagSet *flag.FlagSet) {
116116
flagSet.Var(fileAccessTypePtr(FileAccessExclusive), "file-access", "specifies which filesystem validation to use for the root mount: exclusive (default), shared.")
117117
flagSet.Var(fileAccessTypePtr(FileAccessShared), "file-access-mounts", "specifies which filesystem validation to use for volumes other than the root mount: shared (default), exclusive.")
118118
flagSet.Bool("overlay", false, "DEPRECATED: use --overlay2=all:memory to achieve the same effect")
119-
flagSet.Var(defaultOverlay2(), flagOverlay2, "wrap mounts with overlayfs. Format is {mount}:{medium}, where 'mount' can be 'root' or 'all' and medium can be 'memory', 'self' or 'dir=/abs/dir/path' in which filestore will be created. 'none' will turn overlay mode off.")
119+
flagSet.Var(defaultOverlay2(), flagOverlay2, "wrap mounts with overlayfs. Format is\n"+
120+
"* 'none' to turn overlay mode off\n"+
121+
"* {mount}:{medium}[,size={size}], where\n"+
122+
" 'mount' can be 'root' or 'all'\n"+
123+
" 'medium' can be 'memory', 'self' or 'dir=/abs/dir/path' in which filestore will be created\n"+
124+
" 'size' optional parameter overrides default overlay upper layer size\n")
120125
flagSet.Bool("fsgofer-host-uds", false, "DEPRECATED: use host-uds=all")
121126
flagSet.Var(hostUDSPtr(HostUDSNone), flagHostUDS, "controls permission to access host Unix-domain sockets. Values: none|open|create|all, default: none")
122127
flagSet.Var(hostFifoPtr(HostFifoNone), "host-fifo", "controls permission to access host FIFOs (or named pipes). Values: none|open, default: none")

0 commit comments

Comments
 (0)