Some confused concept: ptmx and tty

tty

All the following commands run in my debian terminal.

ls /dev |grep ptmx
/dev/ptmx

ls  /dev/pts
0  1  ptmx 

What is the difference between /dev/ptmx and /dev/pts/ptmx?

ls  /dev/tty* |sort
/dev/tty
/dev/tty0
/dev/tty1
/dev/tty10

Is there a relation between /dev/tty and /dev/tty0 (/dev/tty1….) ?
/dev/tty control all other /dev/tty[number] ?

Best Answer

/dev/ptmx is the standard one, /dev/pts/ptmx is added for software containers (Docker etc.) and other cases when you need multiple instances of the devpts filesystem.

The nature of device nodes

You should realize that the "magic" of a device node is not in its name, but in the major & minor device numbers it's created to embody.

For example, if you have the appropriate privilege, you can use mknod to create a character device node with major 1 and minor 3 with any name, in any Unix-style filesystem, and - unless the filesystem has the nodev mount option - it will behave exactly like /dev/null, because for all intents and purposes, it will be another realization of /dev/null.

Likewise, both /dev/pts/ptmx and /dev/ptmx are character devices with major number 5 and minor number 2. So they will provide access to the exact same functionality within the kernel.

$ ls -l /dev/ptmx /dev/pts/ptmx
crw-rw-rw- 1 root tty  5, 2 Jun 12 20:14 /dev/ptmx
c--------- 1 root root 5, 2 Jun 12 12:26 /dev/pts/ptmx

The type of the device node (character or block) and the major & minor device numbers together define which kernel device driver that device node interfaces with. The kernel doesn't care about names - it provides default names for udev, but you're free to completely redesign the device naming scheme if you feel like it. You can create device nodes outside /dev, if you need to.

In Debian 9, the /dev/pts/ptmx has permissions set to 000 by default, so it is not expected to be used. Likewise in RHEL 7.5.

The comment in 4.17 kernel source says:

/*
 * ptmx is a new node in /dev/pts and will be unused in legacy (single-
 * instance) mode. To prevent surprises in user space, set permissions of
 * ptmx to 0. Use 'chmod' or remount with '-o ptmxmode' to set meaningful
 * permissions.
 */

"single-instance mode" refers to usage as a system conforming to UNIX98 and Single Unix Specification v1 standards. So it's pretty important backwards compatibility.

The multi-instance capability for devpts was developed for container support. This can be confirmed by reading the old versions of <Linux kernel source>/Documentation/filesystems/devpts.txt from year 2009 or so:

To support containers, we now allow multiple instances of devpts filesystem, such that indices of ptys allocated in one instance are independent of indices allocated in other instances of devpts.

To preserve backward compatibility, this support for multiple instances is enabled only if:

  • CONFIG_DEVPTS_MULTIPLE_INSTANCES=y, and
  • '-o newinstance' mount option is specified while mounting devpts

IOW, devpts now supports both single-instance and multi-instance semantics.

When containers are in use, they will typically initialize an entirely new namespace for pseudo-TTYs, and may mount another instance of the devpts filesystem within the container (this could even be omitted if pseudo-TTY support within the container is not needed). The presence of a ptmx entry within the devpts filesystem may be useful in minimizing the work needed to initialize the in-container environment.