VFS — tmpfs devtmpfs cgroupfs
Linux exposes much more than ordinary disk-backed filesystems. You’ve already seen /proc and /sys, where the kernel exposes information through filesystem-like trees. There are a few other virtual filesystems worth recognizing because you’ll encounter them regularly on a running Linux system.
This chapter focuses on three of them: tmpfs, devtmpfs, and cgroupfs. You don’t need to manage all three directly at this point; the goal is to understand what they are, why they exist, and how to recognize them when inspecting a system.
tmpfs: A Filesystem Backed By Memory
tmpfs is a filesystem whose contents are kept in memory rather than permanently stored on a disk.
You can see it on a normal Debian system with:
df -h -t tmpfsTypical output may look like:
Filesystem Size Used Avail Use% Mounted on
tmpfs 794M 2.0M 792M 1% /run
tmpfs 3.9G 0 3.9G 0% /dev/shmThe exact sizes depend on the machine, but the important part is the filesystem type: tmpfs and the mount points.
Unlike an ordinary filesystem such as ext4, tmpfs does not represent persistent disk storage. Its contents disappear when the system is rebooted.
That makes it useful for data that needs normal filesystem semantics but does not need to survive a reboot.
Why Does tmpfs Exist?
Programs often need temporary files, sockets, runtime state, or shared-memory objects. Putting all of that on a physical disk would be unnecessary in many cases.
With tmpfs:
Application
│
▼
tmpfs file
│
▼
memoryThe application still sees ordinary files and directories. The underlying storage behavior is different.
This is one of the useful ideas behind virtual filesystems: the filesystem interface can stay the same even though the underlying storage is not a traditional disk filesystem.
tmpfs Is Not Simply “RAM Disk”
Calling tmpfs a RAM disk is convenient, but slightly misleading. tmpfs uses memory resources and can also make use of swap. It is dynamically sized rather than being a fixed block of RAM reserved permanently when mounted.
For example, if a tmpfs mount has a maximum size of 1G, that does not mean 1 GiB of physical RAM is immediately consumed. Memory is used as files are actually created and populated.
/run: Runtime System State
One of the most important tmpfs mounts is:
/runInspect it:
findmnt /runYou may see:
TARGET SOURCE FSTYPE OPTIONS
/run tmpfs tmpfs rw,nosuid,nodev,noexec,.../run contains runtime state created since the system booted: PID files, sockets, service state, and other information that does not need to survive a reboot.
For example, system services may place Unix sockets under /run/.
Because /run is temporary runtime state, losing its contents during reboot is expected. The directory itself is recreated during the next boot.
/dev/shm: Shared Memory
Another common tmpfs mount is:
/dev/shmCheck it:
findmnt /dev/shmIt is commonly used for POSIX shared-memory objects.
You can think of it as a memory-backed filesystem exposed through an ordinary directory:
/dev/shm
│
▼
tmpfs
│
▼
memoryApplications that need to exchange data through shared memory can use this interface without treating the data as persistent disk storage.
Creating A tmpfs Mount
You can create your own temporary filesystem to see the idea directly.
First create a mount point:
sudo mkdir /mnt/temporaryThen mount a 100 MiB tmpfs:
sudo mount -t tmpfs -o size=100M tmpfs /mnt/temporaryCheck it:
df -h /mnt/temporaryYou should see something similar to:
Filesystem Size Used Avail Use% Mounted on
tmpfs 100M 0 100M 0% /mnt/temporaryNow create a file:
sudo sh -c 'echo "temporary data" > /mnt/temporary/example.txt'The file behaves like a normal file:
cat /mnt/temporary/example.txtBut the storage is provided by tmpfs, not by an ext4 filesystem on a disk.
Unmount it:
sudo umount /mnt/temporaryThe file disappears because the filesystem that contained it no longer exists.
You can then remove the empty mount point:
sudo rmdir /mnt/temporaryNote
This example is intentionally temporary. If you add a tmpfs entry to /etc/fstab, it can be mounted automatically at boot, but that is unnecessary for understanding the concept here.
devtmpfs: Where /dev Comes From
You’ve already used paths such as:
/dev/sda
/dev/null
/dev/ttyIt is easy to think of /dev as simply a directory containing special files that were created permanently on disk. Modern Linux systems are more dynamic than that.
The /dev hierarchy is normally backed by devtmpfs, a kernel-managed virtual filesystem containing device nodes.
Check it:
findmnt /devOn a typical system you may see:
TARGET SOURCE FSTYPE OPTIONS
/dev devtmpfs devtmpfs rw,nosuid,...The important part is:
FSTYPE
devtmpfsThe kernel creates device nodes in this filesystem as devices become known to it.
So the relationship is roughly:
Hardware / kernel device
│
▼
devtmpfs
│
▼
/dev
│
├── /dev/sda
├── /dev/tty
└── /dev/nullThe exact devices present depend on the machine.
Why Does Linux Need /dev?
Programs need a filesystem-visible way to interact with devices.
For example:
/dev/sdarepresents a block device.
/dev/ttyrepresents a terminal device.
/dev/nullis a special character device that discards data written to it.
These are not ordinary files containing the device’s data. They are device nodes that provide an interface through which programs can interact with kernel-managed devices.
That is why commands can use paths such as:
cat /dev/nullor:
sudo fdisk /dev/sdaThe path looks like a normal filesystem path, but the object ultimately represents a kernel device.
devtmpfs And udev
There are two related pieces here that are easy to confuse.
devtmpfs provides the basic device nodes managed by the kernel. udev operates in userspace and manages device events and additional device-node handling, including permissions and useful names or symlinks.
Conceptually:
Kernel detects device
│
▼
devtmpfs
│
▼
/dev node
│
▼
udev
userspace managementYou don’t need to turn this into a full udev lesson here. The useful distinction is simply:
devtmpfsis the kernel-side virtual filesystem behind the basic/devdevice nodes;udevis the userspace device-management system that works around those nodes.
cgroupfs: A Filesystem Interface To Control Groups
The third filesystem is different in purpose.
Linux control groups, or cgroups, provide mechanisms for grouping processes and controlling or accounting for their resource usage.
You’ve already encountered cgroups conceptually in the Docker material, but here the important point is how Linux exposes them.
Cgroups are represented through a filesystem interface commonly mounted as:
/sys/fs/cgroupCheck it:
findmnt /sys/fs/cgroupOn a modern Debian system using cgroup v2, you may see:
TARGET SOURCE FSTYPE OPTIONS
/sys/fs/cgroup cgroup cgroup2 rw,nosuid,nodev,noexec,...The filesystem type may therefore appear as cgroup2 rather than the older cgroup.
The important idea is that cgroups are represented as a filesystem tree that the kernel understands.
What Does A Cgroup Filesystem Look Like?
A simplified cgroup v2 tree might look like:
/sys/fs/cgroup/
├── cgroup.controllers
├── cgroup.procs
├── cpu.max
├── memory.current
├── memory.max
└── ...These files are not ordinary configuration files stored on disk. They are kernel interfaces.
Reading one can expose current state:
cat /sys/fs/cgroup/memory.currentWriting an appropriate value can change the configuration of that cgroup.
For example, a cgroup may expose:
memory.maxwhich controls the memory limit for processes belonging to that cgroup.
The exact files and behavior depend on the cgroup version and configuration, which is why you should treat this tree as a kernel interface, not as an ordinary directory of files.
Why Use A Filesystem Interface For Cgroups?
The filesystem interface gives administrators and programs a familiar way to interact with kernel functionality.
Instead of inventing an entirely separate mechanism for every operation, Linux can expose state and controls through files:
read file
↓
ask kernel for state
write file
↓
request a kernel changeThis is the same broad idea you’ve already seen with /proc/sys and sysctl.
The important difference is what the filesystem represents:
/proc
→ process and kernel information
/sys
→ devices, drivers, and kernel objects
/sys/fs/cgroup
→ process groups and resource controlsThe Three Filesystems Side By Side
| Filesystem | Common Location | Main Purpose | Persistence |
|---|---|---|---|
tmpfs | /run, /dev/shm | Memory-backed temporary files | Lost on reboot |
devtmpfs | /dev | Kernel-managed device nodes | Recreated dynamically |
cgroup2 | /sys/fs/cgroup | Process grouping and resource control | Kernel-managed state |
The key difference is that these filesystems exist for very different reasons.
tmpfs
→ temporary storage
devtmpfs
→ device interface
cgroupfs / cgroup2
→ process/resource controlThey all look like filesystems because Linux gives them a filesystem interface, but none should be confused with an ordinary disk filesystem such as ext4.
How To Recognize Them On A Real System
When investigating an unfamiliar machine, findmnt is a useful way to see what filesystem is behind a path:
findmnt /run
findmnt /dev
findmnt /sys/fs/cgroupYou can also inspect the filesystem type with:
df -T /run /dev /sys/fs/cgroupThe exact output varies by distribution and system configuration, but you should recognize entries such as:
tmpfs
devtmpfs
cgroup2This is useful because a path ending in a familiar directory name doesn’t tell you what is actually providing it.
For example:
/run
↓
tmpfs
/dev
↓
devtmpfs
/sys/fs/cgroup
↓
cgroup2The mount table is what tells you the underlying filesystem type.
One Mental Model For Virtual Filesystems
At this point, the different virtual filesystems can be viewed as different interfaces exposed through the same general filesystem model:
Linux VFS
│
┌──────────────┼──────────────┐
│ │ │
procfs sysfs tmpfs
│ │ │
processes & devices & temporary
kernel state drivers storage
│
└──────────────┐
│
/proc/sys
│
sysctl
/dev
│
devtmpfs
│
device nodes
/sys/fs/cgroup
│
cgroup2
│
process/resource controlThe important concept isn’t memorizing every filesystem type. It is recognizing that Linux can expose kernel state, hardware, runtime storage, and resource-control mechanisms through filesystem interfaces that ordinary tools can inspect.
What You Should Remember
tmpfs gives you temporary filesystem storage backed primarily by memory. /run and /dev/shm are common examples, and their contents are not intended to survive a reboot.
devtmpfs provides the basic device nodes under /dev, giving programs filesystem paths through which they can interact with kernel-managed devices.
cgroup2 provides a filesystem interface for Linux control groups, exposing process grouping and resource-control state through paths such as /sys/fs/cgroup.
The common thread is:
They look like filesystems
↓
but they do not represent ordinary persistent disk dataThat distinction becomes very useful when you’re inspecting a Linux system and encounter a directory whose contents clearly don’t behave like normal files on disk.