4 Device Management
WARNING:
Oracle Linux 7 is now in Extended Support. See Oracle Linux Extended Support and Oracle Open Source Support Policies for more information.
Migrate applications and data to Oracle Linux 8 or Oracle Linux 9 as soon as possible.
This chapter describes how the system uses device files and how the udev device manager dynamically creates or removes device node files.
About Device Files
The /dev
directory contains device
files (also sometimes known as device special
files and device nodes) that
provide access to peripheral devices such as hard disks, to
resources on peripheral devices such as disk partitions, and
pseudo devices such as a random number generator.
The /dev
directory has several subdirectory
hierarchies, each of which holds device files that relate to a
certain type of device. For example, the
/dev/disk/id-by-uuid
directory contains device
files for hard disks named according to the universally unique
identifier (UUID) for the disk. The device files in subdirectories
such as these are actually implemented as symbolic links to device
files in /dev
. You can access the same device
using the file in /dev
or the corresponding
link to the file listed in
/dev/disk/id-by-uuid
.
If you use the ls -l command to list the files
under /dev
, you see that some device files are
shown as being either type b
for
block or type c
for
character. These devices have a pair of
numbers associated with them instead of a file size. These
major and minor numbers
identify the device to the system.
ls -l /dev
total 0 crw-rw----. 1 root root 10, 56 Mar 17 08:17 autofs drwxr-xr-x. 2 root root 640 Mar 17 08:17 block drwxr-xr-x. 2 root root 80 Mar 17 08:16 bsg drwxr-xr-x. 3 root root 60 Mar 17 08:16 bus lrwxrwxrwx. 1 root root 3 Mar 17 08:17 cdrom -> sr0 drwxr-xr-x. 2 root root 2880 Mar 17 08:17 char crw-------. 1 root root 5, 1 Mar 17 08:17 console lrwxrwxrwx. 1 root root 11 Mar 17 08:17 core -> /proc/kcore drwxr-xr-x. 4 root root 100 Mar 17 08:17 cpu crw-rw----. 1 root root 10, 61 Mar 17 08:17 cpu_dma_latency drwxr-xr-x. 6 root root 120 Mar 17 08:16 disk brw-rw----. 1 root disk 253, 0 Mar 17 08:17 dm-0 brw-rw----. 1 root disk 253, 1 Mar 17 08:17 dm-1 ... crw-rw-rw-. 1 root root 1, 3 Mar 17 08:17 /dev/null ... drwxr-xr-x. 2 root root 0 Mar 17 08:16 pts ... crw-rw-rw-. 1 root root 1, 8 Mar 17 08:17 random ... brw-rw----. 1 root disk 8, 0 Mar 17 08:17 sda brw-rw----. 1 root disk 8, 1 Mar 17 08:17 sda1 brw-rw----. 1 root disk 8, 2 Mar 17 08:17 sda2 ... lrwxrwxrwx. 1 root root 15 Mar 17 08:17 stderr -> /proc/self/fd/2 lrwxrwxrwx. 1 root root 15 Mar 17 08:17 stdin -> /proc/self/fd/0 lrwxrwxrwx. 1 root root 15 Mar 17 08:17 stdout -> /proc/self/fd/1 ... crw--w----. 1 root tty 4, 0 Mar 17 08:17 tty0 crw--w----. 1 root tty 4, 1 Mar 17 08:17 tty1 ... crw-rw-rw-. 1 root root 1, 9 Mar 17 08:17 urandom ... crw-rw-rw-. 1 root root 1, 5 Mar 17 08:17 zero
Block devices support random access to data, seeking media for
data, and usually allow data to be buffered while it is being
written or read. Examples of block devices include hard disks,
CD-ROM drives, flash memory, and other addressable memory devices.
The kernel writes data to or reads data from a block device in
blocks of a certain number of bytes. In the sample output,
sda
is the block device file that corresponds
to the hard disk, and it has a major number of 8 and a minor
number of 0. sda1
and sda2
are partitions of this disk, and they have the same major number
as sda
(8), but their minor numbers are 1 and
2.
Character devices support streaming of data to or from a device,
and data is not usually buffered nor is random access permitted to
data on a device. The kernel writes data to or reads data from a
character device one byte at a time. Examples of character devices
include keyboards, mice, terminals, pseudo-terminals, and tape
drives. tty0
and tty1
are
character device files that correspond to terminal devices that
allow users to log in from serial terminals or terminal emulators.
These files have major number 4 and minor numbers 0 and 1.
Pseudo-terminals worker or secondary (slave) devices emulate real terminal devices to
interact with software. For example, a user might log in on a terminal device such as
/dev/tty1
, which then uses the pseudo-terminal primary (master) device
/dev/pts/ptmx
to interact with an underlying pseudo-terminal device. The
character device files for worker and primary pseudo-terminals are located in the
/dev/pts
directory:
ls -l /dev/pts
total 0 crw--w----. 1 guest tty 136, 0 Mar 17 10:11 0 crw--w----. 1 guest tty 136, 1 Mar 17 10:53 1 crw--w----. 1 guest tty 136, 2 Mar 17 10:11 2 c---------. 1 root root 5, 2 Mar 17 08:16 ptmx
stdin
for the standard input, are symbolically
linked via the self
subdirectory of the proc
file system.
The pseudo-terminal device file to which they actually point depends on the context of the
process. ls -l /proc/self/fd/[012]
total 0 lrwx------. 1 root root 64 Mar 17 10:02 0 -> /dev/pts/1 lrwx------. 1 root root 64 Mar 17 10:02 1 -> /dev/pts/1 lrwx------. 1 root root 64 Mar 17 10:02 2 -> /dev/pts/1
Character devices such as null
,
random
, urandom
, and
zero
are examples of pseudo-devices that
provide access to virtual functionality implemented in software
rather than to physical hardware.
/dev/null
is a data sink. Data that you write
to /dev/null
effectively disappears but the
write operation succeeds. Reading from
/dev/null
returns EOF
(end-of-file).
/dev/zero
is a data source of an unlimited
number of zero-value bytes.
/dev/random
and /dev/urandom
are data sources of streams of pseudo-random bytes. To maintain
high-entropy output, /dev/random
blocks if its
entropy pool does not contains sufficient bits of noise.
/dev/urandom
does not block and, as a result,
the entropy of its output might not be as consistently high as
that of /dev/random
. However, neither
/dev/random
nor /dev/urandom
are considered to be truly random enough for the purposes of
secure cryptography such as military-grade encryption.
You can find out the size of the entropy pool and the entropy
value for /dev/random
from virtual files under
/proc/sys/kernel/random
:
cat /proc/sys/kernel/random/poolsize
4096
cat /proc/sys/kernel/random/entropy_avail
3467
For more information, see the null(4)
,
pts(4)
, and random(4)
manual
pages.
About the Udev Device Manager
The udev device manager dynamically creates or removes device node
files at boot time or if you add a device to or remove a device
from the system with a 2.6 version kernel or later. When creating
a device node, udev reads the device’s /sys
directory for attributes such as the label, serial number, and bus
device number.
Udev can use persistent device names to guarantee consistent naming of devices across reboots, regardless of their order of discovery. Persistent device names are especially important when using external storage devices.
The configuration file for udev is /etc/udev/udev.conf
. The file contains
the variable udev_log
which indicates the logging priority. The variable can
be set to err
, info
and debug
. The default
value is err
.
For more information, see the udev(7)
manual
page.
About Udev Rules
Udev uses rules files that determine how it identifies devices and
creates device names. The udev service
(systemd-udevd
) reads the rules files at system
startup and stores the rules in memory. If the kernel discovers a
new device or an existing device goes offline, the kernel sends an
event action (uevent) notification to udev,
which matches the in-memory rules against the device attributes in
/sys
to identify the device. As part of device
event handling, rules can specify additional programs that should
run to configure a device. Rules files, which have the file
extension .rules
, are located in the following
directories:
-
/lib/udev/rules.d
-
Contains default rules files. Do not edit these files.
-
/etc/udev/rules.d/*.rules
-
Contains customized rules files. You can modify these files.
-
/dev/.udev/rules.d/*.rules
-
Contains temporary rules files. Do not edit these files.
Udev processes the rules files in lexical order, regardless of
which directory they are located. Rules files in
/etc/udev/rules.d
override files of the same
name in /lib/udev/rules.d
.
The following rules are extracted from the file
/lib/udev/rules.d/50-udev- default.rules
and
illustrate the syntax of udev rules.
# do not edit this file, it will be overwritten on update SUBSYSTEM=="block", SYMLINK{unique}+="block/%M:%m" SUBSYSTEM!="block", SYMLINK{unique}+="char/%M:%m" KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660" KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660" ... # mem KERNEL=="null|zero|full|random|urandom", MODE="0666" KERNEL=="mem|kmem|port|nvram", GROUP="kmem", MODE="0640" ... # block SUBSYSTEM=="block", GROUP="disk" ... # network KERNEL=="tun", MODE="0666" KERNEL=="rfkill", MODE="0644" # CPU KERNEL=="cpu[0-9]*", MODE="0444" ... # do not delete static device nodes ACTION=="remove", NAME=="", TEST=="/lib/udev/devices/%k", \ OPTIONS+="ignore_remove" ACTION=="remove", NAME=="?*", TEST=="/lib/udev/devices/$name", \ OPTIONS+="ignore_remove"
Comment lines begin with a #
character. All other non-blank lines define a
rule, which is a list of one or more comma-separated key-value pairs. A rule either assigns a
value to a key or it tries to find a match for a key by comparing its current value with the
specified value. The following list shows the assignment and comparison operators that you can
use:
-
=
: Assign a value to a key, overwriting any previous value. -
+=
: Assign a value by appending it to the key's current list of values. -
:=
: Assign a value to a key. This value cannot be changed by any further rules. -
==
: Match the key's current value against the specified value for equality. -
!=
: Match the key's current value against the specified value for equality.
You can use the following shell-style pattern matching characters in values:
-
?
: Matches a single character. -
*
: Matches any number of characters, including zero. -
[]
: Matches any single character or character from a range of characters specified within the brackets. For example,tty[sS][0-9]
would matchttys7
orttyS7
.
The following list shows commonly used match keys in rules.
-
ACTION
Matches the name of the action that led to an event. For example,
ACTION="add"
orACTION="remove"
. -
ENV{key}
Matches a value for the device property key. For example,
ENV{DEVTYPE}=="disk"
. -
KERNEL
Matches the name of the device that is affected by an event. For example,
KERNEL=="dm-*"
for disk media. -
NAME
Matches the name of a device file or network interface. For example,
NAME="?*"
for any name that consists of one or more characters. -
SUBSYSTEM
Matches the subsystem of the device that is affected by an event. For example,
SUBSYSTEM=="tty"
. -
TEST
Tests if the specified file or path exists. For example,
TEST=="/lib/udev/devices/$name"
, where$name
is the name of the currently matched device file.
Other match keys include
ATTR{filename}
,
ATTRS{filename}
,
DEVPATH
, DRIVER
,
DRIVERS
, KERNELS
,
PROGRAM
, RESULT
,
SUBSYSTEMS
, and SYMLINK
.
The following list shows commonly used assignment keys in rules.
-
ENV{key}
Specifies a value for the device property key. For example,
GROUP="disk"
. -
GROUP
Specifies the group for a device file. For example,
GROUP="disk"
. -
IMPORT{type}
:Specifies a set of variables for the device property, depending on type:
-
cmdline
: Import a single property from the bootkernel
command line. For simple flags, udev sets the value of the property to 1. For example,IMPORT{cmdline}="nodmraid"
. -
db
: Interpret the specified value as an index into the device database and import a single property, which must have already been set by an earlier event. For example,IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG"
. -
file
: Interpret the specified value as the name of a text file and import its contents, which must be in environmental key format. For example,IMPORT{file}="keyfile"
. -
parent
: Interpret the specified value as a key-name filter and import the stored keys from the database entry for the parent device. For exampleIMPORT{parent}="ID_*"
. -
program
: Run the specified value as an external program and imports its result, which must be in environmental key format. For exampleIMPORT{program}="usb_id --export %p"
.
-
-
MODE
Specifies the permissions for a device file. For example,
MODE="0640"
. -
NAME
Specifies the name of a device file. For example,
NAME="em1"
. -
OPTIONS
Specifies rule and device options. For example,
OPTIONS+="ignore_remove"
, which means that the device file is not removed if the device is removed. -
OWNER
Specifies the owner for a device file. For example,
GROUP="root"
. -
RUN
Specifies a command to be run after the device file has been created. For example,
RUN+="/usr/bin/eject $kernel"
, where$kernel
is the kernel name of the device. -
SYMLINK
Specifies the name of a symbolic link to a device file. For example,
SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
, where$env{}
is substituted with the specified device property.
Other assignment keys include
ATTR{key}
,
GOTO
, LABEL
,
RUN
, and WAIT_FOR
.
The following list shows string substitutions that are commonly used with the
GROUP
, MODE
, NAME
,
OWNER
, PROGRAM
, RUN
, and
SYMLINK
keys:
-
$attr{file}
or%s{file}
Specifies the value of a device attribute from a file under
/sys
. For example,ENV{MATCHADDR}="$attr{address}"
. -
$devpath
or%p
The device path of the device in the
sysfs
file system under/sys
. For example,RUN+="keyboard-force-release.sh $devpath common-volume-keys"
. -
$env{key}
or%E{key}
Specifies the value of a device property. For example,
SYMLINK+="disk/by-id/md-name-$env{MD_NAME}-part%n"
. -
$kernel
or%k
The kernel name for the device.
-
$major
or%M
Specifies the major number of a device. For example,
IMPORT{program}="udisks-dm-export %M %m"
. -
$minor
or%m
Specifies the minor number of a device. For example,
RUN+="$env{LVM_SBIN_PATH}/lvm pvscan --cache --major $major --minor $minor"
. -
$name
Specifies the device file of the current device. For example,
TEST=="/lib/udev/devices/$name"
.
Udev expands the strings specified for RUN
immediately before its program is executed, which is after udev
has finished processing all other rules for the device. For the
other keys, udev expands the strings while it is processing the
rules.
For more information, see the udev(7)
manual
page.
Querying Udev and Sysfs
You can use the udevadm command to query the
udev database and sysfs
.
For example, to query the sysfs
device path
relative to /sys
that corresponds to the device
file /dev/sda
:
sudo udevadm info --query=path --name=/dev/sda
/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0/block/sda
To query the symbolic links that point to
/dev/sda
:
sudo udevadm info --query=symlink --name=/dev/sda
block/8:0 disk/by-id/ata-VBOX_HARDDISK_VB6ad0115d-356e4c09 disk/by-id/scsi-SATA_VBOX_HARDDISK_VB6ad0115d-356e4c09 disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0
To query the properties of /dev/sda
:
sudo udevadm info --query=property --name=/dev/sda
UDEV_LOG=3 DEVPATH=/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0/block/sda MAJOR=8 MINOR=0 DEVNAME=/dev/sda DEVTYPE=disk SUBSYSTEM=block ID_ATA=1 ID_TYPE=disk ID_BUS=ata ID_MODEL=VBOX_HARDDISK ID_MODEL_ENC=VBOX\x20HARDDISK\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20... ID_REVISION=1.0 ID_SERIAL=VBOX_HARDDISK_VB579a85b0-bf6debae ID_SERIAL_SHORT=VB579a85b0-bf6debae ID_ATA_WRITE_CACHE=1 ID_ATA_WRITE_CACHE_ENABLED=1 ID_ATA_FEATURE_SET_PM=1 ID_ATA_FEATURE_SET_PM_ENABLED=1 ID_ATA_SATA=1 ID_ATA_SATA_SIGNAL_RATE_GEN2=1 ID_SCSI_COMPAT=SATA_VBOX_HARDDISK_VB579a85b0-bf6debae ID_PATH=pci-0000:00:0d.0-scsi-0:0:0:0 ID_PART_TABLE_TYPE=dos LVM_SBIN_PATH=/sbin UDISKS_PRESENTATION_NOPOLICY=0 UDISKS_PARTITION_TABLE=1 UDISKS_PARTITION_TABLE_SCHEME=mbr UDISKS_PARTITION_TABLE_COUNT=2 UDISKS_ATA_SMART_IS_AVAILABLE=0 DEVLINKS=/dev/block/8:0 /dev/disk/by-id/ata-VBOX_HARDDISK_VB579a85b0-bf6debae ...
To query all information for /dev/sda
:
sudo udevadm info --query=all --name=/dev/sda
P: /devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0/block/sda N: sda W: 37 S: block/8:0 S: disk/by-id/ata-VBOX_HARDDISK_VB579a85b0-bf6debae S: disk/by-id/scsi-SATA_VBOX_HARDDISK_VB579a85b0-bf6debae S: disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0 E: UDEV_LOG=3 E: DEVPATH=/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0/block/sda E: MAJOR=8 E: MINOR=0 E: DEVNAME=/dev/sda E: DEVTYPE=disk E: SUBSYSTEM=block E: ID_ATA=1 E: ID_TYPE=disk E: ID_BUS=ata E: ID_MODEL=VBOX_HARDDISK E: ID_MODEL_ENC=VBOX\x20HARDDISK\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20... E: ID_SERIAL=VBOX_HARDDISK_VB579a85b0-bf6debae E: ID_SERIAL_SHORT=VB579a85b0-bf6debae E: ID_ATA_WRITE_CACHE=1 E: ID_ATA_WRITE_CACHE_ENABLED=1 E: ID_ATA_FEATURE_SET_PM=1 E: ID_ATA_FEATURE_SET_PM_ENABLED=1 E: ID_ATA_SATA=1 E: ID_ATA_SATA_SIGNAL_RATE_GEN2=1 E: ID_SCSI_COMPAT=SATA_VBOX_HARDDISK_VB579a85b0-bf6debae E: ID_PATH=pci-0000:00:0d.0-scsi-0:0:0:0 E: ID_PART_TABLE_TYPE=dos E: LVM_SBIN_PATH=/sbin E: UDISKS_PRESENTATION_NOPOLICY=0 E: UDISKS_PARTITION_TABLE=1 E: UDISKS_PARTITION_TABLE_SCHEME=mbr E: UDISKS_PARTITION_TABLE_COUNT=2 E: UDISKS_ATA_SMART_IS_AVAILABLE=0 E: DEVLINKS=/dev/block/8:0 /dev/disk/by-id/ata-VBOX_HARDDISK_VB579a85b0-bf6debae ...
To display all properties of /dev/sda
and its
parent devices that udev has found in /sys
:
sudo udevadm info --attribute-walk --name=/dev/sda
... looking at device '/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0/block/sda': KERNEL=="sda" SUBSYSTEM=="block" DRIVER=="" ATTR{range}=="16" ATTR{ext_range}=="256" ATTR{removable}=="0" ATTR{ro}=="0" ATTR{size}=="83886080" ATTR{alignment_offset}=="0" ATTR{capability}=="52" ATTR{stat}==" 20884 15437 1254282 338919 5743 8644 103994 109005 ... ATTR{inflight}==" 0 0" looking at parent device '/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0': KERNELS=="0:0:0:0" SUBSYSTEMS=="scsi" DRIVERS=="sd" ATTRS{device_blocked}=="0" ATTRS{type}=="0" ATTRS{scsi_level}=="6" ATTRS{vendor}=="ATA " ATTRS{model}=="VBOX HARDDISK " ATTRS{rev}=="1.0 " ATTRS{state}=="running" ATTRS{timeout}=="30" ATTRS{iocounterbits}=="32" ATTRS{iorequest_cnt}=="0x6830" ATTRS{iodone_cnt}=="0x6826" ATTRS{ioerr_cnt}=="0x3" ATTRS{modalias}=="scsi:t-0x00" ATTRS{evt_media_change}=="0" ATTRS{dh_state}=="detached" ATTRS{queue_depth}=="31" ATTRS{queue_ramp_up_period}=="120000" ATTRS{queue_type}=="simple" looking at parent device '/devices/pci0000:00/0000:00:0d.0/host0/target0:0:0': KERNELS=="target0:0:0" SUBSYSTEMS=="scsi" DRIVERS=="" looking at parent device '/devices/pci0000:00/0000:00:0d.0/host0': KERNELS=="host0" SUBSYSTEMS=="scsi" DRIVERS=="" looking at parent device '/devices/pci0000:00/0000:00:0d.0': KERNELS=="0000:00:0d.0" SUBSYSTEMS=="pci" DRIVERS=="ahci" ATTRS{vendor}=="0x8086" ATTRS{device}=="0x2829" ATTRS{subsystem_vendor}=="0x0000" ATTRS{subsystem_device}=="0x0000" ATTRS{class}=="0x010601" ATTRS{irq}=="21" ATTRS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000003" ATTRS{local_cpulist}=="0-1" ATTRS{modalias}=="pci:v00008086d00002829sv00000000sd00000000bc01sc06i01" ATTRS{numa_node}=="-1" ATTRS{enable}=="1" ATTRS{broken_parity_status}=="0" ATTRS{msi_bus}=="" ATTRS{msi_irqs}=="" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS==""
The command starts at the device specified by its device path and walks up the chain of parent devices. For every device that it finds, it displays all possible attributes for the device and its parent devices in the match key format for udev rules.
For more information, see the udevadm(8)
manual page.
Modifying Udev Rules
The order in which rules are evaluated is important. Udev processes rules in lexical order. If you want to add your own rules, you need udev to find and evaluate these rules before the default rules.
The following example illustrates how to implement a udev rules
file that adds a symbolic link to the disk device
/dev/sdb
.
-
Create a rule file under
/etc/udev/rules.d
with a file name such as10-local.rules
that udev will read before any other rules file.For example, the following rule in
10-local.rules
creates the symbolic link/dev/my_disk
, which points to/dev/sdb
:KERNEL=="sdb", ACTION=="add", SYMLINK="my_disk"
Listing the device files in
/dev
shows that udev has not yet applied the rule:sudo ls /dev/sd* /dev/my_disk
ls: cannot access /dev/my_disk: No such file or directory /dev/sda /dev/sda1 /dev/sda2 /dev/sdb
-
To simulate how udev applies its rules to create a device, you can use the udevadm test command with the device path of
sdb
listed under the/sys/class/block
hierarchy, for example:sudo udevadm test /sys/class/block/sdb
calling: test version ... This program is for debugging only, it does not run any program specified by a RUN key. It may show incorrect results, because some values may be different, or not available at a simulation run. ... LINK 'my_disk' /etc/udev/rules.d/10-local.rules:1 ... creating link '/dev/my_disk' to '/dev/sdb' creating symlink '/dev/my_disk' to 'sdb ... ACTION=add DEVLINKS=/dev/disk/by-id/ata-VBOX_HARDDISK_VB186e4ce2-f80f170d /dev/disk/by-uuid/a7dc508d-5bcc-4112-b96e-f40b19e369fe /dev/my_disk ...
-
Restart the
systemd-udevd
service:sudo systemctl restart systemd-udevd
After udev processes the rules files, the symbolic link
/dev/my_disk
has been added:sudo ls -F /dev/sd* /dev/my_disk
/dev/my_disk@ /dev/sda /dev/sda1 /dev/sda2 /dev/sdb
To undo the changes, remove
/etc/udev/rules.d/10-local.rules
and
/dev/my_disk
and run systemctl restart
systemd-udevd again.