Chapter 12. System and Process Information

In this chapter, we look at ways of accessing a variety of system and process information. The primary focus of the chapter is a discussion of the /proc file system. We also describe the uname() system call, which is used to retrieve various system identifiers.

In older UNIX implementations, there was typically no easy way to introspectively analyze (or change) attributes of the kernel, to answer questions such as the following:

Some older UNIX implementations solved this problem by allowing privileged programs to delve into data structures in kernel memory. However, this approach suffered various problems. In particular, it required specialized knowledge of the kernel data structures, and these structures might change from one kernel version to the next, requiring programs that depended on them to be rewritten.

In order to provide easier access to kernel information, many modern UNIX implementations provide a /proc virtual file system. This file system resides under the /proc directory and contains various files that expose kernel information, allowing processes to conveniently read that information, and change it in some cases, using normal file I/O system calls. The /proc file system is said to be virtual because the files and subdirectories that it contains don’t reside on a disk. Instead, the kernel creates them “on the fly” as processes access them.

In this section, we present an overview of the /proc file system. In later chapters, we describe specific /proc files, as they relate to the topics of each chapter. Although many UNIX implementations provide a /proc file system, SUSv3 doesn’t specify this file system; the details described in this book are Linux-specific.

For each process on the system, the kernel provides a corresponding directory named /proc/PID, where PID is the ID of the process. Within this directory are various files and subdirectories containing information about that process. For example, we can obtain information about the init process, which always has the process ID 1, by looking at files under the directory /proc/1.

Among the files in each /proc/PID directory is one named status, which provides a range of information about the process:

$ cat /proc/1/status
Name:   init                            Name of command run by this process
State:  S (sleeping)                    State of this process
Tgid:   1                               Thread group ID (traditional PID, getpid())
Pid:    1                               Actually, thread ID (gettid())
PPid:   0                               Parent process ID
TracerPid:      0                       PID of tracing process (0 if not traced)
Uid:    0       0       0       0       Real, effective, saved set, and FS UIDs
Gid:    0       0       0       0       Real, effective, saved set, and FS GIDs
FDSize: 256
                             # of file descriptor slots currently allocated
Groups:                                 Supplementary group IDs
VmPeak:      852 kB                     Peak virtual memory size
VmSize:      724 kB                     Current virtual memory size
VmLck:         0 kB                     Locked memory
VmHWM:       288 kB                     Peak resident set size
VmRSS:       288 kB                     Current resident set size
VmData:      148 kB                     Data segment size
VmStk:        88 kB                     Stack size
VmExe:       484 kB                     Text (executable code) size
VmLib:         0 kB                     Shared library code size
VmPTE:        12 kB                     Size of page table (since 2.6.10)
Threads:        1                       # of threads in this thread's thread group
SigQ:   0/3067                          Current/max. queued signals (since 2.6.12)
SigPnd: 0000000000000000                Signals pending for thread
ShdPnd: 0000000000000000                Signals pending for process (since 2.6)
SigBlk: 0000000000000000                Blocked signals
SigIgn: fffffffe5770d8fc                Ignored signals
SigCgt: 00000000280b2603                Caught signals
CapInh: 0000000000000000                Inheritable capabilities
CapPrm: 00000000ffffffff                Permitted capabilities
CapEff: 00000000fffffeff                Effective capabilities
CapBnd: 00000000ffffffff                Capability bounding set (since 2.6.26)
Cpus_allowed:   1                       CPUs allowed, mask (since 2.6.24)
Cpus_allowed_list:      0               Same as above, list format (since 2.6.26)
Mems_allowed:   1                       Memory nodes allowed, mask (since 2.6.24)
Mems_allowed_list:      0               Same as above, list format (since 2.6.26)
voluntary_ctxt_switches:     6998       Voluntary context switches (since 2.6.23)
nonvoluntary_ctxt_switches:  107        Involuntary context switches (since 2.6.23)
Stack usage:    8 kB                    Stack usage high-water mark (since 2.6.32)

The above output is taken from kernel 2.6.32. As indicated by the since comments accompanying the file output, the format of this file has evolved over time, with new fields added (and in a few cases, removed) in various kernel versions. (Aside from the Linux 2.6 changes noted above, Linux 2.4 added the Tgid, TracerPid, FDSize, and Threads fields.)

The fact that the contents of this file have changed over time raises a general point about the use of /proc files: when these files consist of multiple entries, we should parse them defensively—in this case, looking for a match on a line containing a particular string (e.g., PPid:), rather than processing the file by (logical) line number.

Table 12-1 lists some of the other files found in each /proc/PID directory.

Files under /proc are often accessed using shell scripts (most /proc files that contain multiple values can be easily parsed with a scripting language such as Python or Perl). For example, we can modify and view the contents of a /proc file using shell commands as follows:

# echo 100000 > /proc/sys/kernel/pid_max
# cat /proc/sys/kernel/pid_max
100000

/proc files can also be accessed from a program using normal file I/O system calls. Some restrictions apply when accessing these files:

  • Some /proc files are read-only; that is, they exist only to display kernel information and can’t be used to modify that information. This applies to most files under the /proc/PID directories.

  • Some /proc files can be read only by the file owner (or by a privileged process). For example, all files under /proc/PID are owned by the user who owns the corresponding process, and on some of these files (e.g., /proc/PID/environ), read permission is granted only to the file owner.

  • Other than the files in the /proc/PID subdirectories, most files under /proc are owned by root, and the files that are modifiable can be modified only by root.