mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
ext: Add tests for root directory inode.
PiperOrigin-RevId: 259856442
This commit is contained in:
@@ -44,6 +44,7 @@ go_test(
|
||||
"//pkg/sentry/context",
|
||||
"//pkg/sentry/context/contexttest",
|
||||
"//pkg/sentry/fs/ext/disklayout",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/vfs",
|
||||
"//runsc/test/testutil",
|
||||
"@com_github_google_go-cmp//cmp:go_default_library",
|
||||
|
||||
@@ -31,6 +31,15 @@ type dentry struct {
|
||||
// Compiles only if dentry implements vfs.DentryImpl.
|
||||
var _ vfs.DentryImpl = (*dentry)(nil)
|
||||
|
||||
// newDentry is the dentry constructor.
|
||||
func newDentry(in *inode) *dentry {
|
||||
d := &dentry{
|
||||
inode: in,
|
||||
}
|
||||
d.vfsd.Init(d)
|
||||
return d
|
||||
}
|
||||
|
||||
// IncRef implements vfs.DentryImpl.IncRef.
|
||||
func (d *dentry) IncRef(vfsfs *vfs.Filesystem) {
|
||||
d.inode.incRef()
|
||||
|
||||
@@ -20,6 +20,12 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
)
|
||||
|
||||
// Special inodes. See https://www.kernel.org/doc/html/latest/filesystems/ext4/overview.html#special-inodes.
|
||||
const (
|
||||
// RootDirInode is the inode number of the root directory inode.
|
||||
RootDirInode = 2
|
||||
)
|
||||
|
||||
// The Inode interface must be implemented by structs representing ext inodes.
|
||||
// The inode stores all the metadata pertaining to the file (except for the
|
||||
// file name which is held by the directory entry). It does NOT expose all
|
||||
|
||||
@@ -131,7 +131,12 @@ func (fstype filesystemType) NewFilesystem(ctx context.Context, creds *auth.Cred
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &fs.vfsfs, nil, nil
|
||||
rootInode, err := fs.getOrCreateInode(disklayout.RootDirInode)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &fs.vfsfs, &newDentry(rootInode).vfsd, nil
|
||||
}
|
||||
|
||||
// getOrCreateInode gets the inode corresponding to the inode number passed in.
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/sentry/context"
|
||||
"gvisor.dev/gvisor/pkg/sentry/context/contexttest"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/ext/disklayout"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
|
||||
"gvisor.dev/gvisor/runsc/test/testutil"
|
||||
@@ -82,6 +83,90 @@ func setUp(t *testing.T, imagePath string) (context.Context, *vfs.Filesystem, *v
|
||||
return mockCtx, fs, d, tearDown, nil
|
||||
}
|
||||
|
||||
// TestRootDir tests that the root directory inode is correctly initialized and
|
||||
// returned from setUp.
|
||||
func TestRootDir(t *testing.T) {
|
||||
type inodeProps struct {
|
||||
Mode linux.FileMode
|
||||
UID auth.KUID
|
||||
GID auth.KGID
|
||||
Size uint64
|
||||
InodeSize uint16
|
||||
Links uint16
|
||||
Flags disklayout.InodeFlags
|
||||
}
|
||||
|
||||
type rootDirTest struct {
|
||||
name string
|
||||
image string
|
||||
wantInode inodeProps
|
||||
}
|
||||
|
||||
tests := []rootDirTest{
|
||||
{
|
||||
name: "ext4 root dir",
|
||||
image: ext4ImagePath,
|
||||
wantInode: inodeProps{
|
||||
Mode: linux.ModeDirectory | 0755,
|
||||
Size: 0x400,
|
||||
InodeSize: 0x80,
|
||||
Links: 3,
|
||||
Flags: disklayout.InodeFlags{Extents: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ext3 root dir",
|
||||
image: ext3ImagePath,
|
||||
wantInode: inodeProps{
|
||||
Mode: linux.ModeDirectory | 0755,
|
||||
Size: 0x400,
|
||||
InodeSize: 0x80,
|
||||
Links: 3,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ext2 root dir",
|
||||
image: ext2ImagePath,
|
||||
wantInode: inodeProps{
|
||||
Mode: linux.ModeDirectory | 0755,
|
||||
Size: 0x400,
|
||||
InodeSize: 0x80,
|
||||
Links: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, _, vfsd, tearDown, err := setUp(t, test.image)
|
||||
if err != nil {
|
||||
t.Fatalf("setUp failed: %v", err)
|
||||
}
|
||||
defer tearDown()
|
||||
|
||||
d, ok := vfsd.Impl().(*dentry)
|
||||
if !ok {
|
||||
t.Fatalf("ext dentry of incorrect type: %T", vfsd.Impl())
|
||||
}
|
||||
|
||||
// Offload inode contents into local structs for comparison.
|
||||
gotInode := inodeProps{
|
||||
Mode: d.inode.diskInode.Mode(),
|
||||
UID: d.inode.diskInode.UID(),
|
||||
GID: d.inode.diskInode.GID(),
|
||||
Size: d.inode.diskInode.Size(),
|
||||
InodeSize: d.inode.diskInode.InodeSize(),
|
||||
Links: d.inode.diskInode.LinksCount(),
|
||||
Flags: d.inode.diskInode.Flags(),
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(gotInode, test.wantInode); diff != "" {
|
||||
t.Errorf("inode mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestFilesystemInit tests that the filesystem superblock and block group
|
||||
// descriptors are correctly read in and initialized.
|
||||
func TestFilesystemInit(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user