mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Display the proper root path in mountinfo.
PiperOrigin-RevId: 492323370
This commit is contained in:
committed by
gVisor bot
parent
600066a9bb
commit
99cc6c2dea
@@ -920,7 +920,7 @@ func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDe
|
||||
if mnt == vfsroot.Mount() && &d.vfsd == vfsroot.Dentry() {
|
||||
return vfs.PrependPathAtVFSRootError{}
|
||||
}
|
||||
if &d.vfsd == mnt.Root() {
|
||||
if mnt != nil && &d.vfsd == mnt.Root() {
|
||||
return nil
|
||||
}
|
||||
if d.parent == nil {
|
||||
|
||||
+19
-11
@@ -1161,16 +1161,27 @@ func (vfs *VirtualFilesystem) GenerateProcMountInfo(ctx context.Context, taskRoo
|
||||
mount: mnt,
|
||||
dentry: mnt.root,
|
||||
}
|
||||
path, err := vfs.PathnameReachable(ctx, taskRootDir, mntRootVD)
|
||||
pathFromRoot, err := vfs.PathnameReachable(ctx, taskRootDir, mntRootVD)
|
||||
if err != nil {
|
||||
// For some reason we didn't get a path. Log a warning
|
||||
// and run with empty path.
|
||||
ctx.Warningf("VFS.GenerateProcMountInfo: error getting pathname for mount root %+v: %v", mnt.root, err)
|
||||
path = ""
|
||||
continue
|
||||
}
|
||||
if path == "" {
|
||||
// Either an error occurred, or path is not reachable
|
||||
// from root.
|
||||
if pathFromRoot == "" {
|
||||
// The path is not reachable from root.
|
||||
continue
|
||||
}
|
||||
var pathFromFS string
|
||||
pathFromFS, err = vfs.PathnameInFilesystem(ctx, mntRootVD)
|
||||
if err != nil {
|
||||
// For some reason we didn't get a path. Log a warning
|
||||
// and run with empty path.
|
||||
ctx.Warningf("VFS.GenerateProcMountInfo: error getting pathname for mount root %+v: %v", mnt.root, err)
|
||||
continue
|
||||
}
|
||||
if pathFromFS == "" {
|
||||
// The path is not reachable from root.
|
||||
continue
|
||||
}
|
||||
// Stat the mount root to get the major/minor device numbers.
|
||||
@@ -1208,13 +1219,10 @@ func (vfs *VirtualFilesystem) GenerateProcMountInfo(ctx context.Context, taskRoo
|
||||
|
||||
// (4) Root: the pathname of the directory in the filesystem
|
||||
// which forms the root of this mount.
|
||||
//
|
||||
// NOTE(b/78135857): This will always be "/" until we implement
|
||||
// bind mounts.
|
||||
fmt.Fprintf(buf, "/ ")
|
||||
fmt.Fprintf(buf, "%s ", manglePath(pathFromFS))
|
||||
|
||||
// (5) Mount point (relative to process root).
|
||||
fmt.Fprintf(buf, "%s ", manglePath(path))
|
||||
fmt.Fprintf(buf, "%s ", manglePath(pathFromRoot))
|
||||
|
||||
// (6) Mount options.
|
||||
opts := "rw"
|
||||
@@ -1241,7 +1249,7 @@ func (vfs *VirtualFilesystem) GenerateProcMountInfo(ctx context.Context, taskRoo
|
||||
fmt.Fprintf(buf, "none ")
|
||||
|
||||
// (11) Superblock options, and final newline.
|
||||
fmt.Fprintf(buf, "%s\n", superBlockOpts(path, mnt))
|
||||
fmt.Fprintf(buf, "%s\n", superBlockOpts(pathFromRoot, mnt))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,29 @@ loop:
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
// PathnameInFilesystem returns an absolute path to vd relative to vd's
|
||||
// Filesystem root. It also appends //deleted to for disowned entries. It is
|
||||
// equivalent to Linux's dentry_path().
|
||||
func (vfs *VirtualFilesystem) PathnameInFilesystem(ctx context.Context, vd VirtualDentry) (string, error) {
|
||||
b := getFSPathBuilder()
|
||||
defer putFSPathBuilder(b)
|
||||
if vd.dentry.IsDead() {
|
||||
b.PrependString("//deleted")
|
||||
}
|
||||
if err := vd.mount.fs.impl.PrependPath(ctx, VirtualDentry{}, VirtualDentry{dentry: vd.dentry}, b); err != nil {
|
||||
// PrependPath returns an error if it encounters a filesystem root before
|
||||
// the provided vfsroot. We don't provide a vfsroot, so encountering this
|
||||
// error is expected and can be ignored.
|
||||
switch err.(type) {
|
||||
case PrependPathAtNonMountRootError:
|
||||
default:
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
b.PrependByte('/')
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
// PathnameForGetcwd returns an absolute pathname to vd, consistent with
|
||||
// Linux's sys_getcwd().
|
||||
func (vfs *VirtualFilesystem) PathnameForGetcwd(ctx context.Context, vfsroot, vd VirtualDentry) (string, error) {
|
||||
|
||||
@@ -1397,6 +1397,26 @@ TEST(MountTest, BindParentToChild) {
|
||||
ASSERT_EQ(opt2, opt3);
|
||||
}
|
||||
|
||||
TEST(MountTest, MountInfoHasRoot) {
|
||||
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
|
||||
auto const parent = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
auto const mount = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
Mount("", parent.path(), "tmpfs", 0, "mode=0123", 0));
|
||||
auto const child =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDirIn(parent.path()));
|
||||
auto const bind_mount = Mount(child.path(), child.path(), "", MS_BIND, "", 0);
|
||||
std::vector<ProcMountInfoEntry> mounts =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(ProcSelfMountInfoEntries());
|
||||
for (const auto& e : mounts) {
|
||||
if (e.mount_point == child.path()) {
|
||||
ASSERT_EQ(e.root, JoinPath("/", Basename(child.path())));
|
||||
}
|
||||
if (e.mount_point == parent.path()) {
|
||||
ASSERT_EQ(e.root, "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
||||
|
||||
Reference in New Issue
Block a user