Added integration tests for mounting tmpfs with size option enabled.
PiperOrigin-RevId: 444705540
This commit is contained in:
parent
bf251f1838
commit
ce91143bdc
|
@ -202,7 +202,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
|
||||||
var maxSizeInPages uint64
|
var maxSizeInPages uint64
|
||||||
if ok {
|
if ok {
|
||||||
delete(mopts, "size")
|
delete(mopts, "size")
|
||||||
maxSizeInBytes, err := strconv.ParseUint(maxSizeStr, 10, 64)
|
maxSizeInBytes, err := parseSize(maxSizeStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Warningf("tmpfs.FilesystemType.GetFilesystem: invalid size: %q", maxSizeStr)
|
ctx.Warningf("tmpfs.FilesystemType.GetFilesystem: invalid size: %q", maxSizeStr)
|
||||||
return nil, nil, linuxerr.EINVAL
|
return nil, nil, linuxerr.EINVAL
|
||||||
|
@ -944,3 +944,33 @@ func (fd *fileDescription) RemoveXattr(ctx context.Context, name string) error {
|
||||||
func (*fileDescription) Sync(context.Context) error {
|
func (*fileDescription) Sync(context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseSize converts size in string to an integer bytes.
|
||||||
|
// Supported suffixes in string are:K, M, G, T, P, E.
|
||||||
|
func parseSize(s string) (uint64, error) {
|
||||||
|
suffix := s[len(s)-1]
|
||||||
|
count := 1
|
||||||
|
switch suffix {
|
||||||
|
case 'e', 'E':
|
||||||
|
count = count << 10
|
||||||
|
fallthrough
|
||||||
|
case 'p', 'P':
|
||||||
|
count = count << 10
|
||||||
|
fallthrough
|
||||||
|
case 't', 'T':
|
||||||
|
count = count << 10
|
||||||
|
fallthrough
|
||||||
|
case 'g', 'G':
|
||||||
|
count = count << 10
|
||||||
|
fallthrough
|
||||||
|
case 'm', 'M':
|
||||||
|
count = count << 10
|
||||||
|
fallthrough
|
||||||
|
case 'k', 'K':
|
||||||
|
count = count << 10
|
||||||
|
s = s[:len(s)-1]
|
||||||
|
}
|
||||||
|
bytes, err := strconv.ParseUint(s, 10, 64)
|
||||||
|
bytes = bytes * uint64(count)
|
||||||
|
return bytes, err
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ package tmpfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||||
"gvisor.dev/gvisor/pkg/atomicbitops"
|
"gvisor.dev/gvisor/pkg/atomicbitops"
|
||||||
|
@ -155,3 +156,37 @@ func newPipeFD(ctx context.Context, mode linux.FileMode) (*vfs.FileDescription,
|
||||||
|
|
||||||
return fd, cleanup, nil
|
return fd, cleanup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseSize(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
s string
|
||||||
|
want uint64
|
||||||
|
wantError bool
|
||||||
|
}{
|
||||||
|
{"500", 500, false},
|
||||||
|
{"5k", (5 * 1024), false},
|
||||||
|
{"5m", (5 * 1024 * 1024), false},
|
||||||
|
{"5G", (5 * 1024 * 1024 * 1024), false},
|
||||||
|
{"5t", (5 * 1024 * 1024 * 1024 * 1024), false},
|
||||||
|
{"5P", (5 * 1024 * 1024 * 1024 * 1024 * 1024), false},
|
||||||
|
{"5e", (5 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024), false},
|
||||||
|
{"5e3", 0, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
testname := fmt.Sprintf("%s", tt.s)
|
||||||
|
t.Run(testname, func(t *testing.T) {
|
||||||
|
size, err := parseSize(tt.s)
|
||||||
|
if tt.wantError && err == nil {
|
||||||
|
t.Errorf("Invalid input: %v parsed", tt.s)
|
||||||
|
}
|
||||||
|
if !tt.wantError {
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Couldn't parse size, Error: %v", err)
|
||||||
|
}
|
||||||
|
if size != tt.want {
|
||||||
|
t.Errorf("got: %v, want %v", size, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// tmpfs has some extra supported options that we must pass through.
|
// tmpfs has some extra supported options that we must pass through.
|
||||||
var tmpfsAllowedData = []string{"mode", "uid", "gid"}
|
var tmpfsAllowedData = []string{"mode", "size", "uid", "gid"}
|
||||||
|
|
||||||
func addOverlay(ctx context.Context, lower *fs.Inode, name string, lowerFlags fs.MountSourceFlags) (*fs.Inode, error) {
|
func addOverlay(ctx context.Context, lower *fs.Inode, name string, lowerFlags fs.MountSourceFlags) (*fs.Inode, error) {
|
||||||
// Upper layer uses the same flags as lower, but it must be read-write.
|
// Upper layer uses the same flags as lower, but it must be read-write.
|
||||||
|
|
|
@ -911,3 +911,42 @@ func TestRevalidateSymlinkChain(t *testing.T) {
|
||||||
t.Fatalf("Read wrong file, want: %q, got: %q", want, got)
|
t.Fatalf("Read wrong file, want: %q, got: %q", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestTmpMountWithSize checks when 'tmpfs' is mounted
|
||||||
|
// with size option the limit is not exceeded.
|
||||||
|
func TestTmpMountWithSize(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
d := dockerutil.MakeContainer(ctx, t)
|
||||||
|
defer d.CleanUp(ctx)
|
||||||
|
|
||||||
|
opts := dockerutil.RunOpts{
|
||||||
|
Image: "basic/alpine",
|
||||||
|
Mounts: []mount.Mount{
|
||||||
|
{
|
||||||
|
Type: mount.TypeTmpfs,
|
||||||
|
Target: "/tmp/foo",
|
||||||
|
TmpfsOptions: &mount.TmpfsOptions{
|
||||||
|
SizeBytes: 4096,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := d.Create(ctx, opts, "sleep", "1000"); err != nil {
|
||||||
|
t.Fatalf("docker create failed: %v", err)
|
||||||
|
}
|
||||||
|
if err := d.Start(ctx); err != nil {
|
||||||
|
t.Fatalf("docker start failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "echo hello > /tmp/foo/test1.txt"); err != nil {
|
||||||
|
t.Fatalf("docker exec failed: %v", err)
|
||||||
|
}
|
||||||
|
echoOutput, err := d.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", "echo world > /tmp/foo/test2.txt")
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("docker exec size check failed: %v", err)
|
||||||
|
}
|
||||||
|
wantErr := "No space left on device"
|
||||||
|
if !strings.Contains(echoOutput, wantErr) {
|
||||||
|
t.Errorf("unexpected echo error:Expected: %v, Got: %v", wantErr, echoOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue