mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Implement /proc/cmdline
This change implements /proc/cmdline with a basic faux command line "BOOT_IMAGE=/vmlinuz-[version]-gvisor quiet" so apps that may expect it do not receive errors. Also tests for the existence of /proc/cmdline as part of the system call test suite PiperOrigin-RevId: 372462070
This commit is contained in:
@@ -65,6 +65,7 @@ var _ kernfs.Inode = (*tasksInode)(nil)
|
||||
func (fs *filesystem) newTasksInode(ctx context.Context, k *kernel.Kernel, pidns *kernel.PIDNamespace, fakeCgroupControllers map[string]string) *tasksInode {
|
||||
root := auth.NewRootCredentials(pidns.UserNamespace())
|
||||
contents := map[string]kernfs.Inode{
|
||||
"cmdline": fs.newInode(ctx, root, 0444, &cmdLineData{}),
|
||||
"cpuinfo": fs.newInode(ctx, root, 0444, newStaticFileSetStat(cpuInfoData(k))),
|
||||
"filesystems": fs.newInode(ctx, root, 0444, &filesystemsData{}),
|
||||
"loadavg": fs.newInode(ctx, root, 0444, &loadavgData{}),
|
||||
|
||||
@@ -336,15 +336,6 @@ var _ dynamicInode = (*versionData)(nil)
|
||||
|
||||
// Generate implements vfs.DynamicBytesSource.Generate.
|
||||
func (*versionData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
k := kernel.KernelFromContext(ctx)
|
||||
init := k.GlobalInit()
|
||||
if init == nil {
|
||||
// Attempted to read before the init Task is created. This can
|
||||
// only occur during startup, which should never need to read
|
||||
// this file.
|
||||
panic("Attempted to read version before initial Task is available")
|
||||
}
|
||||
|
||||
// /proc/version takes the form:
|
||||
//
|
||||
// "SYSNAME version RELEASE (COMPILE_USER@COMPILE_HOST)
|
||||
@@ -364,7 +355,7 @@ func (*versionData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
// FIXME(mpratt): Using Version from the init task SyscallTable
|
||||
// disregards the different version a task may have (e.g., in a uts
|
||||
// namespace).
|
||||
ver := init.Leader().SyscallTable().Version
|
||||
ver := kernelVersion(ctx)
|
||||
fmt.Fprintf(buf, "%s version %s %s\n", ver.Sysname, ver.Release, ver.Version)
|
||||
return nil
|
||||
}
|
||||
@@ -400,3 +391,31 @@ func (*cgroupsData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
r.GenerateProcCgroups(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// cmdLineData backs /proc/cmdline.
|
||||
//
|
||||
// +stateify savable
|
||||
type cmdLineData struct {
|
||||
dynamicBytesFileSetAttr
|
||||
}
|
||||
|
||||
var _ dynamicInode = (*cmdLineData)(nil)
|
||||
|
||||
// Generate implements vfs.DynamicByteSource.Generate.
|
||||
func (*cmdLineData) Generate(ctx context.Context, buf *bytes.Buffer) error {
|
||||
fmt.Fprintf(buf, "BOOT_IMAGE=/vmlinuz-%s-gvisor quiet\n", kernelVersion(ctx).Release)
|
||||
return nil
|
||||
}
|
||||
|
||||
// kernelVersion returns the kernel version.
|
||||
func kernelVersion(ctx context.Context) kernel.Version {
|
||||
k := kernel.KernelFromContext(ctx)
|
||||
init := k.GlobalInit()
|
||||
if init == nil {
|
||||
// Attempted to read before the init Task is created. This can
|
||||
// only occur during startup, which should never need to read
|
||||
// this file.
|
||||
panic("Attempted to read version before initial Task is available")
|
||||
}
|
||||
return init.Leader().SyscallTable().Version
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ var (
|
||||
|
||||
var (
|
||||
tasksStaticFiles = map[string]testutil.DirentType{
|
||||
"cmdline": linux.DT_REG,
|
||||
"cpuinfo": linux.DT_REG,
|
||||
"filesystems": linux.DT_REG,
|
||||
"loadavg": linux.DT_REG,
|
||||
|
||||
@@ -1201,6 +1201,15 @@ TEST(ProcSelfCwd, Absolute) {
|
||||
EXPECT_EQ(exe[0], '/');
|
||||
}
|
||||
|
||||
// Sanity check that /proc/cmdline is present.
|
||||
TEST(ProcCmdline, IsPresent) {
|
||||
SKIP_IF(IsRunningWithVFS1());
|
||||
|
||||
std::string proc_cmdline =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/cmdline"));
|
||||
ASSERT_FALSE(proc_cmdline.empty());
|
||||
}
|
||||
|
||||
// Sanity check for /proc/cpuinfo fields that must be present.
|
||||
TEST(ProcCpuinfo, RequiredFieldsArePresent) {
|
||||
std::string proc_cpuinfo =
|
||||
|
||||
Reference in New Issue
Block a user