Repository navigation
eudev 3.3.0 (2026-11-03)
This release completes the sync with systemd-udev at systemd a446e8ff2c (v262+) that 3.2.15 started.
3.2.15 brought the hardware database, the rules, the builtins and the helper programs to that level;
this release does the same for udevd, udevadm, the rules engine and libudev. A few later systemd
changes are included too: hwdb data, the caller information of triggered uevents and the fixes of
systemd v262.1 that apply to eudev. The main additions are systemd's network interface naming
schemes and alternative interface names, sticky tags, the reworked device node symlink handling,
postponing the events of locked block devices, ID_PROCESSING, trace logging, udev.conf drop-ins,
systemd's log settings ($SYSTEMD_LOG_LEVEL and the like), the udevadm verify, cat, wait and
lock commands, the systemd-hwdb tool, the tpm2_id and factory_reset builtins and GPT root
partition discovery. The rules parser is now as strict as systemd's, so please read "Before
upgrading" first.
UDEV_VERSION is now 262. The libudev ABI is unchanged: no symbol was added or removed, and the
soname stays libudev.so.1. The library file becomes libudev.so.1.7.15, the same version as
systemd v262's libudev: 3.2.14 added udev_device_has_current_tag() and
udev_device_get_current_tags_list_entry() without raising the library version.
In the notes below, "(deviation: ...)" marks a place where eudev deliberately differs from
systemd a446e8ff2c.
The complete release notes are in NEWS.md, which is also in
the release tarball. This page has the introduction, "Changes that may need attention" and
"Before upgrading"; the sections that they refer to (udevd, Rules, udevadm, Logging,
Builtins and helper programs, hwdb, libudev, Build and configuration, Documentation and
Fixes) are in NEWS.md.
Changes that may need attention
The list names the changes that most often need an adjustment; "Before upgrading" and the sections
after it have the details.
- Workers are named "(udev-worker)", the child that re-reads a partition table "(udev-synth)" and the
processes of the programs that rules run "(spawn)", as in systemd: the messages of the workers and
of that child in the kernel log and syslog are tagged "(udev-worker)" and "(udev-synth)" instead of
"udevd", so log filters that match "udevd" miss them. $<NAME>_PATHin udevd's environment, e.g.$SCSI_ID_PATH, replaces the program of the same name
that a rule runs, as in systemd.IMPORT{program},IMPORT{file},IMPORT{db},IMPORT{cmdline},IMPORT{parent}and hwdb
entries no longer set the properties thatENV{}cannot set (DEVNAME,ACTION,DEVPATH,
...): e.g.IMPORT{db}=="DEVNAME"is now always false, andudevadm verifywarns about such
names and fails (deviation).- Device names, paths and the arguments of udevadm are escaped in messages (control characters and
invalid UTF-8 as\xNN; deviation); the data thatudevadm info,monitorandtrigger --verboseprint is unchanged. udevadm triggerandinfocheck their match options like systemd, andtrigger,control,
settleandmonitorcheck all their options before they look for a chroot, so--help,
--versionand invalid options work in a chroot (deviation: systemd'striggerandcontrol
look for the chroot first).--attr-match=and--attr-nomatch=ofudevadm triggerandinfotake attribute paths
relative to the device, also with.., e.g.queue/rotational(deviation).udevadm test -Dfails for a directory that does not exist; invalid tag names are refused by
udevadm trigger/info --tag-match=andudev_enumerate_add_match_tag().- The release tarball no longer contains the generated
rules/64-btrfs.rulesand
rule_generator/write_net_rules(GitHub #301), andmake checkdoes not change the timestamps
of the build machine's device nodes. - New configure option
--with-net-ifnames-default=yes|nofor what happens withoutnet.ifnames=
on the kernel command line. - Builds with
--enable-rule-generatorno longer write rules for interfaces that the kernel did not
name by enumeration, for the interfaces of more virtual machines, for User-mode Linux and mac80211
monitor interfaces, or for an interface without a MAC address or bus id (also with
INTERFACE_NAME), and udevd no longer moves an interface without a new name of its own to a
temporary name such aseth126(see "Rule generator"). /run/udev/queueis created once when events are queued and removed when the queue is empty, as in
systemd: when something else removes it while events are queued, udevd does not create it again
until the queue has emptied, soudevadm settlereturns early then.- With the default
hwdb_format=1, it is undefined which value a device gets when several hwdb
records set the same key, as before; hwdb(7) now says so, and some entries, e.g. the new one for the
lid keys of the HP Pavilion Gaming 15-dk0, work only withhwdb_format=2in udev.conf (see "hwdb"). - The library file is
libudev.so.1.7.15(the soname stayslibudev.so.1).
Before upgrading
Packagers
-
Create the groups that the shipped rules use: audio, cdrom, clock, dialout, disk, input, kmem,
kvm, lp, render, sgx, tape, tty and video. AGROUP=(orOWNER=) that names a group (or user)
that does not exist is now ignored with an error such as "Failed to resolve group 'clock',
ignoring: Unknown group" every time the rules are loaded, and the device node keeps its group; the
rest of the rule line (MODE=,SYMLINK+=, ...) still applies. Before, eudev used root instead. -
New
clockgroup: rtc devices getGROUP="clock", MODE="0660"and ptp devices
GROUP="clock", MODE="0664"(systemd af96ccfc24 and 1e6854e112), so that e.g. linuxptp can open
them without root. Read access to/dev/ptp*for everybody relies on the PTP file mode checks of
Linux b4e53b15c04e, which was backported to the maintained stable kernels. Nothing creates the
clockgroup on systems without systemd-sysusers (e.g. Alpine, Gentoo, Void). -
$(sbindir)/udevadmis gone:make installno longer creates the/sbin/udevadm(or
/usr/sbin/udevadm) compatibility symlink that existed since 2013. Packages and scripts that call
udevadm by that path must provide the link themselves. -
The shipped hwdb files moved to
$(udevlibexecdir)/hwdb.d(e.g./usr/lib/udev/hwdb.d), as in
systemd;$(sysconfdir)/udev/hwdb.dis left to the administrator, and its files override shipped
files of the same name. Remove copies of the shipped hwdb files that an older package left in
/etc/udev/hwdb.d, or they override the new data with stale data.hwdb.binis still written to
$(sysconfdir)/udev/hwdb.bin, which now really follows--sysconfdir(it was hard-coded to
/etc/udev). Builds with--disable-programsinstall no hwdb files and no man pages. The hwdb
READMEis installed next to the hwdb files, like in systemd. -
udev.his no longer installed;libudev.his the only public header. udev.h was an internal
header that included private ones.udev_device_read_db()is removed fromlibudev.h; it was never
exported, so no program could have linked against it. -
UDEV_VERSIONis 262 inudevadm --version,udevd --version, the helpers'--version,
udev.pcandlibudev.pc(3.2.15 still reported 251). It says that the rules syntax, the hwdb, the
builtins, the helpers and the libudev API match systemd-udev v262. It does not mean feature parity:
eudev has, for example, no Varlink interface, no sd-device API, noCONST{}key, no
dissect_image,net_setup_linkoruaccessbuiltin and noudevadm control --load-credentials.
Scripts should test for a feature (e.g.udevadm lock --help) rather than compare numbers.
Distributions that hard-code the number must update it (Void:_UDEV_VERSION="251"). The package
version is shown next to it, e.g. in udevd's start line "starting eudev-3.3.0 (udev 262)". -
New configure options that packagers may want to set:
--with-nobody-group=(Debian and Devuan:
nogroup),--with-system-uid-max=/--with-system-gid-max=,--with-foreign-uid-base=,
--with-net-ifnames-default=(see "Network interface names"),--disable-tpm2,
--disable-systemd-hwdb(systemd-hwdbis installed by default and clashes with systemd's own
/usr/bin/systemd-hwdbwhere both packages can be installed),--with-bashcompletiondir=,
--with-zshcompletiondir=and--enable-smack. See "Build and configuration". -
udev.conf is looked up like in systemd: the main file is the first
udev.conffound in
$(sysconfdir)/udev,/run/udev,/usr/local/lib/udevand$(udevlibexecdir)(with split-usr also
/lib/udevand/usr/lib/udev), andudev.conf.d/*.confdrop-ins in the same directories are read
after it (see "udevd"). An empty file or a symlink to/dev/nullmasks a file of the same name in
the later directories. The shipped udev.conf lists the new keys as comments and writes
#udev_log=infowithout quotes, so packages that patch it must be adjusted. -
Release tarball and
make check: the tarball no longer contains the generated
rules/64-btrfs.rulesandrule_generator/write_net_rules, only their.insources, from which
the build makes them for its own directories (GitHub #301);rule_generator.functionsis made the
same way, for--with-rootrundir=. The installed files do not change, apart from the paths in the
rule generator's scripts (see "Fixes"). The tarball now also containsautogen.sh,man/make.sh,
man/custom-man.xsl,BUILD,CONTRIBUTING,LEGACYandNOTES. The new tests ofmake check
that use the build machine's/dev/null,/dev/zero,/dev/full,/dev/random,/dev/urandom,
/dev/ttyand/dev/ptmxbind them read-only, so they do not change their timestamps, also when
they run as root (see "Build and configuration").
Init scripts and service supervisors
- udevd keeps its standard streams in the foreground: it connects
/dev/nullto stdin, stdout
and stderr only when it daemonizes and does not log at debug level (systemd 40e749b59b). Before, it
did so unless--debugwas given, also without--daemon. - Log level precedence of udevd is now, from lowest to highest: the default,
systemd.log_level=
on the kernel command line,$UDEV_LOG_LEVEL/$SYSTEMD_LOG_LEVEL,udev_log=in udev.conf, udevd
options (--debug),udev.log_level=on the kernel command line,udevadm control, as in systemd;
udevd(8) documents it. Before,--debugoverrodeudev.log-priority=on the kernel command line.
--debugstill logs to the console, now from the start (see "udevd"). - Kernel command line: udevd accepts systemd's spellings
udev.log_level=and
udev.log_priority=, and-and_are equivalent in all its options (udev.children_max=is
udev.children-max=); the old spellings keep working.rd.*options are honoured only in an initrd
(see "Rules"). Unknownudev.*options, and unknownrd.udev.*options in an initrd, are ignored
with systemd's warning "Unknown udev kernel command line option "…", ignoring." (before, without a
message). - systemd's log settings: udevd, udevadm and the helper programs read
$SYSTEMD_LOG_LEVEL,
$SYSTEMD_LOG_TARGET,$SYSTEMD_LOG_COLOR,$SYSTEMD_LOG_LOCATION,$SYSTEMD_LOG_TIME,
$SYSTEMD_LOG_TIDand$SYSTEMD_LOG_RATELIMIT_KMSG(each$UDEV_LOG_*variant first). Processes
without a controlling terminal (udevd, the programs it runs, the commands of init scripts) also read
systemd.log_level=,systemd.log_target=,systemd.log_color,systemd.log_location,
systemd.log_time,systemd.log_tidandsystemd.log_ratelimit_kmsgfrom the kernel command line;
the environment overrides them. A baredebugon the kernel command line counts as
systemd.log_level=debug, as in systemd (rd.debugonly in an initrd). So
systemd.log_level=debugordebugon the kernel command line now also makes
udevadm trigger/settlein init scripts and every helper verbose on the boot console, and every
helper run reads/proc/cmdline. Warnings about invalid log settings in the environment or on the
kernel command line go to stderr, as in systemd. Like in systemd, a process closes the console once
it logs to another target, e.g. /dev/kmsg. Withsystemd.log_target=console, a udevd started with
--daemonwrites to/dev/console, or to/dev/kmsgwhen that cannot be opened, e.g. in a
container (deviation: systemd writes to/dev/nullthen). Messages to/dev/kmsgare limited to
200 per 5 seconds per process, as in systemd; messages dropped by the limit are not written anywhere
else. - Changed log messages: log monitors and scripts that match udevd's messages must be adjusted. The
slow and timeout messages are now systemd's: "Spawned process '…' [PID] is taking longer than … to
complete.", "Spawned process '…' [PID] timed out after …, killing.", "Worker [PID] processing
SEQNUM=N is taking a long time." and "Worker [PID] processing SEQNUM=N killed." (before: "slow:",
"timeout: killing", "timeout; kill it", "seq N '…' killed"); "Delaying execution of "…" for …." was
"delay execution of"; socket failures read "Failed to initialize udev control socket: …", "Failed to
initialize device monitor: …", "Failed to bind udev control socket: …" and "Failed to listen udev
control socket: …". The messages of the workers and of the child that re-reads a partition table are
tagged "(udev-worker)" and "(udev-synth)" (see below). Programs are reported like in systemd:
"Process '…' succeeded." at debug level (was "'…' [PID] exit with return code 0"), "Process '…'
failed with exit code N." as a warning forRUNand at debug level forPROGRAMand
IMPORT{program}(was "exit with return code N" at debug level), "Process '…' terminated by signal
NAME." (was "terminated by signal N (Name)"), and a program that cannot be found or is not
executable is reported before it is started: "Failed to find and pin callout binary "…": …" (was
"failed to execute '…' '…': …"). Device names, paths and other values in messages are escaped (see
"Logging"). See "udevd" and "Logging". - Process names: workers rename themselves "(udev-worker)", the child that re-reads a partition
table "(udev-synth)" and the processes of the programs that rules run "(spawn)", as in systemd, so
they show under these names inps, and the kernel log and syslog tag the messages of the workers
"(udev-worker)" and those of the re-read child "(udev-synth)" instead of "udevd" (udevd's own
messages keep its name): log filters that match "udevd" miss the messages of the workers and of
the re-read child. The option errors of the builtins start with "(udev-worker):", and the uevents
that a worker triggers carrySYNTH_ARG_Comm=udevworker(see "Caller information in triggered
uevents"). The names are complete whatever the name udevd was started with. $<NAME>_PATH: like systemd-udevd, udevd honours$<NAME>_PATHfrom its environment, the file
name of a program in upper case with-replaced by_and_PATHappended, e.g.$SCSI_ID_PATH
forscsi_id: it names another file to run instead of thatRUN,PROGRAMorIMPORT{program}
program. Init scripts and supervisors that pass their environment to udevd should not set such
variables by accident.
Local rules
Run udevadm verify on local rules after upgrading: the parser now follows systemd, and lines that
older versions accepted silently may be dropped with an error.
-
Rules parser strictness:
- key names must be exact (
NAMEXis notNAME,TESTXis notTEST); - a key that takes no attribute must not have one ("Invalid attribute for X."), and
ATTR,ATTRS,
ENV,IMPORT,SECLABELandSYSCTLneed a non-empty one; an attribute is everything up to
}, soATTR{a b}works, and text between}and the operator is an error; ==and!=are errors forRUN,OWNER,GROUP,MODEandSECLABEL;LABELandGOTO
take only=;OPTIONSrefuses==,!=and-=, and+=acts as=;- a syntax error anywhere in a line drops the whole line (before, the keys parsed so far were kept);
the message is "Invalid key/value pair, ignoring." without a character position; a line of a
single character is such an error; a trailing comma is accepted; - an unknown builtin, an unknown
IMPORT{}orRUN{}type, orIMPORTwithout a type drops the
line (before, only that key); in builds without blkid or kmod, lines using them are dropped as in
systemd; in--disable-tpm2buildsIMPORT{builtin},IMPORT{program},RUN{builtin},
RUN{program}andPROGRAMnamingtpm2_idare dropped with "... is not supported by this build
of eudev (configured with --disable-tpm2), ignoring the rule."; - lines using what only systemd supports are dropped with a message saying so: the
CONST{}key and
thedissect_image,net_setup_linkanduaccessbuiltins; OPTIONSvalues must be exact known names (nowatchno longer also meanswatch); unknown
values get a warning; an invalidlink_priority=orlog_level=value drops the line, and
link_priority=takes systemd's number formats (before, "10x" meant 10 and "abc" meant 0);
several values separated by commas in oneOPTIONSkey are still accepted (deviation: systemd
takes one value per key; no systemd rule is affected);OWNER/GROUP: an empty or invalid value (leading zeros, leading whitespace or a minus sign in
a number, 65535, 4294967295, values that are too large) is an error and only that key is ignored,
also withOPTIONS+="static_node=..."(deviation: systemd drops the line; before, eudev used
root);udevadm verifyreports a line that is left without effect by it; a value starting with
+is looked up as a name; a numeric ID without an account is accepted only up to the highest
system ID, for 0, for 65534 ("nobody") and in systemd's foreign range, otherwise it counts as an
unknown user or group; see also "Packagers" above;MODE: an invalid mode without substitutions (empty,0999, a sign, more than 07777, also with
MODE:=) is an error when the rules are read, and only that key is ignored (deviation: systemd
keeps the key, which then fails at every event); a mode produced by a substitution that is invalid
is logged and leaves the mode unchanged (before, an empty result set mode 0000);NAME="%k"andNAME=""drop the line, with systemd's message;TEST{mode}with an invalid mode drops the line (before, it meant "no mode"), and so does
TEST{0}("Mode mask of TEST must not be zero, ignoring.") (deviation: in systemdTEST{0}never
matches); a mask matches when any of its bits is set, as documented now;WAIT_FORandWAIT_FOR_SYSFSare removed (systemd f2b8052fb6) and now drop the line as unknown
keys;- only the first
GOTOof a line counts; later ones get "Contains multiple GOTO keys, ignoring
GOTO=..." (before, a laterGOTOcould jump); - like in systemd, a line that cannot do anything for the event is not evaluated at all: one without
an assignment,GOTO,PROGRAMorIMPORT, or whose only assignments areNAMEon a device
that is not a network interface, orSYMLINK,OWNER,GROUPorMODEon a device without a
node or on a remove event; so a failingTESTorSYSCTL{}in such a line no longer stops the
event, andudevadm testdoes not show it; a line whoseGOTOhas noLABELand that has
nothing else to do is dropped with "The line has no effect any more, dropping."; - a rule may have any number of keys (before, more than 64 keys crashed udevd).
- key names must be exact (
-
Line continuation is read like systemd: the leading whitespace of continuation lines is
removed; comment lines inside a continued rule are skipped (before, they ended the rule, and the
remaining lines became a separate rule without the earlier matches); a rule continued at the end of
the file is ignored with "Unexpected EOF after line continuation, line ignored."; CRLF files work.
A physical line longer than 16383 characters drops only that rule, with an error naming the line
(deviation: systemd ignores the whole file). -
Program arguments:
RUN,PROGRAMandIMPORT{program}command lines are split like systemd
does, with the same splitter as the builtins: any whitespace (also tabs) separates arguments;
single and double quotes group characters anywhere in a word and are removed (a"b c"dis one
argumentab cd, and'a b'cisa bc; before:a bandc); a missing closing quote is
accepted; backslashes are not special; a command given as"prog"runsprog. Builtin commands
also skip leading whitespace and are no longer cut at 1024 bytes. None of the rules shipped by
eudev, systemd, Devuan or Debian are affected; local rules that pass quotes inside a word, or tabs,
must be adjusted. -
Rules directory precedence is now
/etc/udev/rules.d>/run/udev/rules.d>
/usr/local/lib/udev/rules.d>/usr/lib/udev/rules.d(and/lib/udev/rules.d), as in systemd.
Before,/libcame before/run, and/usr/localcame last. Each directory is read once, also
when it has several paths, e.g./liband/usr/libon a merged /usr, or a bind mount. A rules
file that is not a regular file (a dangling symlink, a symlink to a directory, a FIFO) no longer
hides the file of the same name in a lower-priority directory; this holds for udevd,udevadm test,
catandverify. -
Properties are validated wherever they come from (kernel events, rules, IMPORT, builtins, the
database), as in systemd: names may contain only ASCII letters, digits,_and.; values must be
valid UTF-8 without control characters. Invalid ones are ignored with a warning (rules) or a debug
message, and processing continues; so programs orIMPORT{cmdline}keys that use e.g.-in
property names lose those properties. An empty value removes the property, also from builtins
(e.g. an empty USB serial) andIMPORT(A=""). -
Errors stop the event as in systemd: an
IMPORT{file}that exists but cannot be opened, an
unreadable kernel command line, an unreadableSYSCTL{}(other than a missing one), an unreadable
directory for a*inTEST, failing to remove a property (e.g.ENV{a-b}=""), and running out of
memory (e.g. "Failed to clone sd_device object: …" for the copy of the device with its database
entry, before which eudev went on without that copy). No further rules are applied, the node,
symlinks and database are not updated,RUNis not executed, and the event is still sent to
listeners. A missingIMPORT{file}or a failing program is still only a false key. A database or
tag index that cannot be written also fails the event (see "udevd"). -
IMPORTmatches like systemd:IMPORT{parent}is true only when at least one property was
imported, andIMPORT{...}!=now matches only when the import failed (before, also when it
succeeded).IMPORT{db}also finds the properties of the event itself, e.g.PRODUCTof a USB
device whose database entry does not exist yet; when both have the property, the database value is
imported, as in systemd. -
rd.*options inIMPORT{cmdline}are honoured only in an initrd again, as in systemd: since
3.2.15,IMPORT{cmdline}="rd.foo"also matched on the real root. The initrd detection also
recognises initrds without/etc/initrd-release(e.g. initramfs-tools), see "udevd". -
Substitutions that do not fit make a match fail (debug message) and an assignment be skipped
(warning), instead of using a cut value. Invalid substitutions ($attr/$envwithout{...}, a
missing}) stop the substitution with a warning. In$result{N}/%c{N}the parts are separated
by any whitespace, leading whitespace is skipped, and a non-numeric N is an error, also in
udevadm verify. -
Private properties (names starting with
.) are now passed toRUN,PROGRAMand
IMPORT{program}programs and to udev monitor listeners, as systemd has done since v220; they are
still not stored in the database./bin/sh(dash) drops such variables from the environment of
the commands it runs. -
OWNER/GROUPresolved at event time (from substitutions) that cannot be resolved are logged
and leave the owner or group unchanged (before, root). WithOPTIONS+="static_node=..."an unknown
user or group drops only that key, too. -
/etc/scsi_id.configis read with systemd's parser: a line that cannot be parsed, e.g. with
options=and nothing after it, or one that is too long, makesscsi_idfail (exit status 1, no
output) with an error naming the file and the line, e.g. "Error parsing config file
/etc/scsi_id.config line 3 '…'" (deviation: systemd does not name the file), also when the line
comes after the globaloptions=line and is only found while the options of the device are looked
up, and so does an option that avendor=line may not set (see "scsi_id" under "Builtins and
helper programs"); an unterminated quote is accepted; options are split on runs of spaces and tabs;
the last line needs no newline; a NUL or CR ends a line. White space after a comma
(vendor="ATA", options=-g) is still accepted, as in 3.2.x (deviation: systemd refuses it). -
Protected properties in
IMPORTand hwdb:IMPORT{program},IMPORT{file},IMPORT{db},
IMPORT{cmdline},IMPORT{parent}and hwdb entries no longer set the properties thatENV{}
cannot set:ACTION,SEQNUM,SYNTH_UUID,SYNTH_ARG_*,DEVPATH,DEVPATH_OLD,SUBSYSTEM,
DEVTYPE,DRIVER,MODALIAS,DEVNAME,DEVMODE,DEVUID,DEVGID,MAJOR,MINOR,
DISKSEQ,PARTN,IFINDEX,INTERFACE,INTERFACE_OLD,DEVLINKS,TAGS,CURRENT_TAGS,
USEC_INITIALIZEDandUDEV_DATABASE_VERSION. They are skipped with a debug message ("Property "…"
cannot be set, ignoring.";IMPORT{parent}skips them silently). Before, a program or file could
make udevd send the event as another device, action or sequence number, and the database kept such
values. SoIMPORT{db}=="DEVNAME"andIMPORT{cmdline}with such a name are always false now, and
IMPORT{parent}is false for a parent that has only such properties. Loading the rules and
udevadm verifywarn about such a name inIMPORT{db}orIMPORT{cmdline}("IMPORT{db} property
'DEVNAME' cannot be set, it is never imported."), the line is kept, andudevadm verifyfails
(deviation: systemd a446e8ff2c imports these properties). udev(7) and hwdb(7) document it, and
udev(7) now says thatIMPORT{parent}imports all properties of the parent, from its uevent and its
database. -
IMPORT{program}output is split into lines like systemd: a line ends at every\nor\r,
and backslashes and quotes are not special; only spaces, tabs and line breaks are removed around
keys and values, also inIMPORT{file}(before, lines ended only at\n, and any white space, also
\vand\f, was removed); of output that does not fit, everything after the last line break is
dropped.
Network interface names
-
Naming schemes: the
net_idbuiltin implements systemd's network interface naming schemes,
v238 to v261, pluseudev, which generates exactly the names of eudev 3.2.15 and older, and
latest, the default, which is v261 (systemd a446e8ff2c defines no v262 scheme). The scheme is
exported asID_NET_NAMING_SCHEME. With the default, interfaces that80-net-name-slot.rules
renames get different names than with 3.2.15, for example:- virtio-net NICs:
ens<N>/enp0s<N>instead ofenx<MAC>; - NICs that report a port name (e.g. Intel X710/X722/E810, Mellanox mlx5, Broadcom bnxt): an
np<port>suffix, e.g.enp59s0f0np0,eno1np0; - SR-IOV virtual functions are named after their PF (
eno1v0), representors get...r<vf>; - firmware onboard indexes above 65535 (e.g. VMware's
eno16777736) are ignored, so such NICs get
slot or path names; anacpi_indexof 0 giveseno0; - servers with ACPI
_SUNgetens<slot>[f<fn>]; NPAR/ARI functions use the full function number; - IBM Z:
enc<busid>without leading zeros instead ofenccw0.0.xxxx, virtio-ccw gets
enc<busid>, PCI slots are named by function_id; - newly named: IBM PowerVM VIO (
env<N>), ARM64 ACPI platform NICs (ena...), DeviceTree boards
(end<N>, WLANwld<N>), USB NICs on SoC host controllers (enu...), InfiniBand (ib...),
netdevsim, Xen netfront (enX<N>), MCTP (mc...) and mlx5 sub-functions (...S<sfnum>); - Azure MANA NICs drop the PCI domain; the hwdb properties
ID_NET_NAME_ALLOW*and
ID_NET_NAME_INCLUDE_DOMAINare honoured.
- virtio-net NICs:
-
Selecting the scheme:
net.naming_scheme=on the kernel command line, the new
net_naming_scheme=key in udev.conf, or$NET_NAMING_SCHEME, which takes precedence unless it
starts with:, in which case it is used only when neither of the others selects a scheme. To keep
the names of 3.2.15, setnet_naming_scheme=eudevin udev.conf. An unknown name is skipped with
systemd's warning "Unknown interface naming scheme '…' requested, ignoring." and the next setting in
that order is used (deviation: systemd uses the default, so a typo on the kernel command line would
override the scheme pinned in udev.conf). -
Renaming policy of 80-net-name-slot.rules, for every scheme (the
eudevscheme pins only the
namesnet_idgenerates):- the name from the hwdb (
ID_NET_NAME_FROM_DATABASE) comes first, as in systemd; today this
renames only the Dell iDRAC virtual USB NIC, toidrac; - interfaces named by userspace, already renamed (e.g. in the initrd), or named predictably by the
kernel (name_assign_type2, 3 or 4) are not renamed, like systemd's "keep" and "kernel"
policies, also onudevadm trigger --action=add;NAME=in earlier rules still applies; - a candidate that is not a valid interface name (systemd's
ifname_valid(): longer than 15
characters, only digits,.,..,all,default,:,/,%, whitespace or non-ASCII, or an
interface index in another notation such as0x10,+5,0b1,0o7) is skipped and the next
one is used; a MAC based name of an all-zero address is never used. The rules file, like
80-net-altnames.rules, is generated bytools/gen-net-naming-rules.py(with--help).
- the name from the hwdb (
-
NAME=on network interfaces: a name longer than 15 characters is refused with an error
(before, it was silently cut). With schemes v249 and later, invalid characters are replaced by_
and a name that is still invalid is ignored with "Invalid network interface name, ignoring"; with
older schemes, includingeudev, such a rename fails.NAME=on any other device is ignored with
"Only network interfaces can be renamed, ignoring." (see "Rules"). -
Alternative interface names: on Linux 5.5 and later, udevd assigns the predictable names
(ID_NET_NAME_FROM_DATABASE,_ONBOARD,_SLOT,_PATH,_MAC, also those longer than 15
characters) as alternative names to new interfaces, like systemd's default
AlternativeNamesPolicy=;ip linkshows them and accepts them instead of the interface name. This
is done byOPTIONS+="net_altnames"in the new80-net-altnames.rules, installed also with
--enable-rule-generator, independent ofnet.ifnames=, unless eudev is built with
--with-net-ifnames-default=no(see below).net_altnames=noin udev.conf disables it; an invalid
or empty value is reported, with the value, by udevd andudevadm test. Existing interfaces get
them at their next add event. -
Default of
net.ifnames=: the new configure option--with-net-ifnames-default=yes|nosets
what happens withoutnet.ifnames=on the kernel command line. Withyes, the default, nothing
changes:80-net-name-slot.rulesrenames interfaces unless the kernel command line has
net.ifnames=0, and alternative names are assigned either way. Withno, interfaces keep the names
the kernel gave them and get no alternative names unless the kernel command line has
net.ifnames=1. The installed80-net-name-slot.rulesand80-net-altnames.rules, the configure
summary ("net.ifnames default:") and udev(7), udevd(8) and udev.conf(5) follow the option. With
--enable-rule-generatorandyes, the rule generator replaces80-net-name-slot.rules, which is
not installed, andnet.ifnames=changes nothing; withno,80-net-name-slot.rulesis installed
too, and withnet.ifnames=1the rule generator records no names (see "Rule generator" below). -
Rule generator (
--enable-rule-generator), with parts of Debian's generator, which Devuan
ships:75-persistent-net-generator.rulesrecords only interfaces that the kernel named by
enumeration (name_assign_type1, or unreadable as before Linux 3.17), not those of more virtual
machines (VirtualBox, Xen by its MAC prefix, more VMware prefixes, Microsoft Azure, Ravello, old
libvirt, Parallels, Oracle VM, Nutanix AHV, bhyve and Proxmox VE, as before for KVM, VMware and
Hyper-V; the Azure prefixes are Microsoft's, so Microsoft hardware gets no rule either), of
User-mode Linux and mac80211 monitor interfaces;dev_idis matched for every MAC address, not for
S/390 devices; the comment of a rule names the driver of the nearest device that has one, e.g.
"(r8152)" instead of "(usb)".write_net_ruleswrites no rule for an interface without a MAC
address or bus id, also withINTERFACE_NAME(before, a rule that matched every interface of its
type; an interface of KVM, VMware or Hyper-V now gets the warning below too when it has
INTERFACE_NAME, where its rules ended silently before), and logs "no MAC address or bus id to
match … with, writing no rule" and "Cannot lock …!" also to the kernel log, as warnings, when
/dev/kmsgcan be written. udevd renames an interface to a temporary name only when it gets a new
name of its own: one without, e.g. of a virtual machine, keeps its name also when a stale rule
gives that name to another interface (before, it became e.g.eth126); the other interface then
keeps its own name; it waits for the name, up to 90 s but not beyond the event timeout, only while
udevd has not handled the add event of the interface that has it (the handled ones are recorded in
/run/udev/net-added/). udev(7) describes the generator in a new section.
Persistent storage links
- by-path names change on these systems; update fstab, crypttab, LVM filters and scripts that use
them:- Hyper-V and Azure guests (VMBus as an ACPI device): SCSI disks and DVDs are named after the
controller's instance GUID and the LUN, e.g.acpi-VMBUS:00-scsi-0:0:0:0becomes
acpi-VMBUS:00-vmbus-f8b3781b1e824818a1c363d806ec15bb-lun-0; before, LUNs on different
controllers could share a name; - IBM Z: zfcp LUNs change from
ccw-<dev>-zfcp-<WWPN>:<LUN>toccw-<dev>-fc-<WWPN>-lun-<LUN>;
SCSI devices below a CCW device (e.g. virtio-scsi) gain the SCSI address (ccw-0.0.0005becomes
ccw-0.0.0005-scsi-0:0:0:0); qeth, AP and IUCV devices getccwgroup-...,ap-...and
iucv-...names; DASD and virtio-blk paths do not change; - devices behind an SPI controller get the chip select appended, e.g.
platform-fe204000.spi
becomesplatform-fe204000.spi-cs-1(for ACPI-enumerated devices the ACPI instance number, e.g.
-cs-00); - devices whose sysfs strings contain control characters or invalid UTF-8 get no
ID_PATHinstead
of one with escape sequences in it; - the default SCSI path (
...-scsi-H:B:T:L) prints numbers that do not fit a signed int as
negative numbers, as systemd does (e.g. LUN 4294967295 givesscsi-0:0:0:-1); - SCSI LUNs of 2^32 and more (third and fourth addressing level) get their full 8-byte LUN,
lun-0x<16 hex digits>, one link per LUN; 3.2.15 named them after their lower 32 bits (on 32-bit
systems all of themlun-0xffffffff00000000), so different LUNs could share a link (deviation:
systemd a446e8ff2c names them...(null)); - the old
...-ata-<port>link and theID_PATH_ATA_COMPATproperty are given only to the device
that owns the name alone: the one on bus 0, target 0 of the ATA port (a single SATA disk, a PATA
master, the disk on port 0 of a port multiplier) or the only device of the port (a lone PATA or
ATAPI slave, a lone disk behind a port multiplier); a slave next to a master and port-multiplier
disks next to others no longer get it, so the link no longer points to whichever came last
(deviation: systemd sets the property for every device). When the bus 0/target 0 device appears
after a lone device of its port got the link, that device and its partitions get a change event
and drop it (this can add change events during coldplug); when any device of the port is
removed (also a PATA slave or a disk behind a port multiplier) and one device is left on the
port, that device and its partitions get a change event and take the link, unless the device
has it already (a new rule in60-persistent-storage.rulesrunspath_idfor the remove event
of every SCSI target).
- Hyper-V and Azure guests (VMBus as an ACPI device): SCSI disks and DVDs are named after the
- by-id links: partitions of host-managed zoned (ZAC) ATA disks get their
scsi-<serial>-part<N>links again (deviation: systemd creates the link only for the whole disk).
Tapes whose serial number contains C1 control characters get theirtape/by-id/scsi-*links back,
and a serial with a TAB is now refused, exactly as in systemd.
Scripts that call udevadm
-
udevadm testno longer changes the system (systemd 089bef6631 and follow-ups): it renames no
interface, creates or changes no device node, permission, label or symlink, writes no database,
tag,ATTR{}orSYSCTL{}value, loads no module, remaps no keys and issues no btrfs ioctl (as
udevadm test-builtinalready did; the rules test runner ofmake checknow also skips the
keyboard and btrfs builtins). It runs no program except the helpers
ata_id,cdrom_id,dmi_memory_id,fido_id,mtd_probeandscsi_id, given by exact name or
by their path in udev's helper directory (deviation: systemd matches any command line that starts
with a helper name).cdrom_idgets the new--dry-runoption there and does not lock or eject the
media (deviation). So properties from other programs are missing,PROGRAMresults are empty, and
RESULT==,%candPROGRAM!=behave accordingly; a renamed interface keeps itsINTERFACE=. A
value thatATTR{}=would write is seen by a laterATTR{}==. -
udevadm testoutput format: stdout carries only a result block of labelled sections (device,
node owner/group/mode, symlinks, the would-be interface name and alternative names,ATTR/SYSCTL
writes, tags, current tags, indented properties, queued commands asRUN{program} : ...); the
banner and log messages go to stderr. Scripts that grep^KEY=orrun:break; use the new
--json=. -
chroot:
udevadm trigger,control,settleandmonitordo nothing in a chroot: they log
"Running in chroot, ignoring request." and exit 0 (systemd c494b739a4). It counts as a chroot when
the root directory is not the one of PID 1, or/procis not mounted;$UDEV_IN_CHROOT, then
$SYSTEMD_IN_CHROOT, override the detection, and the deprecated$SYSTEMD_IGNORE_CHROOTdisables
it. All four check their options, the option values and, fortrigger, the match options first, so
--helpand--versionwork in a chroot, and invalid options, values and matches fail there as
elsewhere; only a valid request is ignored (deviation: systemd'striggerandcontrollook for a
chroot before they parse their options; itssettleandmonitorparse them first, like eudev).
Maintainer scripts that run in debootstrap or sbuild chroots and call these commands now do nothing. -
Exit statuses:
udevadm triggerexits 1 when writing a uevent fails (it always exited 0), for
an invalid--action=("Invalid action 'x'."; was "unknown action" and 2) and for a device that
cannot be found ("Failed to open the device '…': No such device"; was "unable to open the device"
and 2);udevadm testexits 1 on every error (was 2 to 5);udevadm test-builtinprints only the
error and exits 1 (was the help text and 2 to 6);udevadm controlexits 1 on every failure and
stops at the first failing command (was 2, or the status of the last command);udevadm infowith a
missing or invalid device exits 1 ('Unknown device "…": No such device'; was 2);udevadm settleas
root exits 1 when the control socket cannot be created (was 0); invalid--timeout=values of
controlandsettleexit 1;udevadmwithout a command or with an unknown one exits 1 (was 2);
udevadm versionwith arguments exits 1 ("Too many arguments."; was 0);udevadm infoexits 1 for
a query or-awithout a device ("A device name or path is required"; was the help text and 2, or
4), for--query=nameon a device without a node ("No device node found: No such file or
directory"; was 5) and for an unknown query type ("Unknown query type 'x'"; was 3);udevadm settle
as root exits 1 when udevd cannot be pinged for another reason than not running, e.g. when it does
not answer within the ping timeout of at least 5 s ("Failed to connect to udev daemon: …", "Failed
to wait for daemon to reply: …"; was 0);udevadm triggerwith an unknown--type=("Unknown type
--type=x"; was 2) or an invalid match option (see "Match options" below) exits 1;udevadm test -D
exits 1 for a directory that does not exist ("Failed to access '…': No such file or directory") or a
file ("'…' is not a directory.");udevadm monitorexits 1 when a filter cannot be applied. -
Option parsing: invalid options are reported with systemd's texts, through the log at error
level: "udevadm: unrecognized option '-Z'", "option '-n' requires an argument", "option '--hel'
doesn't allow an argument" and "option '--exp' is ambiguous; possibilities: --export,
--export-prefix, --export-db" (before, glibc's texts with the command name). An abbreviation shared
by an option and its alias is ambiguous now, as in systemd and in musl builds:
udevadm control --log…(--log-level/--log-priority) and--relo…
(--reload/--reload-rules) must be spelled out. Without a command, udevadm says "Command verb
required (one of help, info, …).", and for an unknown one "Unknown command verb 'x', did you mean
'y'?".systemd-hwdb,udevdand the helper programs (ata_id,cdrom_id,collect,
dmi_memory_id,fido_id,mtd_probe,scsi_id,v4l_id) report invalid options with systemd's
texts too, through the log at error level (e.g. "ata_id: unrecognized option '-Z'"; before, glibc's
texts on stderr). So do theblkidandhwdbbuiltins, whoseIMPORT{builtin}then fails (before,
invalid options were skipped silently). The helpers print their help in systemd's layout;ata_id
andmtd_probetake exactly one device ("Need exactly one DEVICE argument.";ata_idaccepted
more), anddmi_memory_idno argument ("This program takes no arguments."). -
Property order: properties are listed in the order they were added, which is systemd's order,
instead of sorted by name: inudevadm info, its JSON output, program environments, monitor
messages andudev_device_get_properties_list_entry(); the databaseE:lines are not sorted
either, but their order can differ from systemd's. The values ofDEVLINKSandTAGSstay sorted
(deviation: systemd uses hash order, which changes between runs). -
Device arguments of
info,test,test-builtin,triggerandwaitare resolved like
systemd: a device ID (e.g.b8:0,n1,+net:lo), then the path (also relative, or through a
symlink), then the path below/devor/sys; a path outside/devand/sysis an unknown
device, and forinfo,test,test-builtinandtriggera path that is not a device gives "No
such device", also e.g./dev/null/x, as in systemd (waitwarns about it, see "udevadm");
/dev/block/MAJ:MINand/dev/char/MAJ:MINare looked up by the number, so they work without the
symlinks. Several--parent-match=/--name-match=oftriggernow all count (before, only the
last). -
Match options:
udevadm triggerchecks--attr-match=,--attr-nomatch=,--property-match=
and--tag-match=likeudevadm info --export-dband systemd: an invalid attribute or property
name ("a//b is not a valid key name"), a--property-match=without=("Missing '=' in key/value
pair FOO.") and an invalid tag name ("Failed to add tag match '../data': Invalid argument") fail
with exit status 1 (before, they were accepted, and arguments were cut at 4096 bytes), also in a
chroot (see above);udevadm infochecks them also without--export-db("'../data' is not a valid
tag name"). Both take attribute paths relative to the device, e.g.queue/rotationalor../size,
and refuse an empty name, a leading/, empty components and.components (deviation: systemd
refuses every name with a/). A tag name may contain only letters, digits,-and_and be at
most 255 bytes long, also inudev_enumerate_add_match_tag()(EINVAL); before, e.g.
--tag-match=../datalisted every device with a database entry. -
Terminal output: colors need both stdout and stderr on a terminal and
$TERMset, and use
256/24-bit colors ($SYSTEMD_COLORS); log messages to a terminal are colored by level by default
(see "Logging");udevadm infooutput and all help texts go through a pager on a terminal
(--no-pager,$SYSTEMD_PAGER). See "udevadm".
libudev users
- Several public functions changed behaviour, as in systemd: property order and validation, sticky
tags, syspath and attribute checks, device lookups and their error codes, parent devices, the device
IDs of drivers and of devices without a subsystem, the devices that enumerations list (e.g. the
/sys/bus/*/drivers directories, each device only under its own subsystem), the tag names that
udev_enumerate_add_match_tag()accepts, devices received from a monitor keeping the values of
their event, the errno ofudev_hwdb_new(), and udev.conf being read once per process. See
"libudev" for the list.
Since 3.2.14: changes that 3.2.15 made without a release note
SYMLINK=values are checked and normalized: a value with a..component or an absolute path
outside/dev/is refused; a/dev/prefix is accepted; a trailing slash is removed, so a value
that substitutes tofoo/creates/dev/foo(in 3.2.14 that made the worker loop until the event
timeout). New in this release: redundant slashes and.components are removed instead of refused
(a//bcreates/dev/a/b), components longer than NAME_MAX and control characters are refused (the
latter unlessOPTIONS+="string_escape=none"), invalid values are warnings, and devlinks read from
the database are checked and normalized the same way.- Tags may contain only letters, digits,
-and_. Invalid tags recorded in the database by
3.2.14 are ignored when it is read, so they vanish from the device (udevadm info,TAGS); their
/run/udev/tags/<tag>/entries stay until reboot, soudevadm trigger --tag-match=<tag>still
finds those devices. TAG=""only clears the tags; an empty tag cannot be added. With sticky tags (see "Rules") it
clears the current tags only.- Protected properties: an
ENV{}assignment to a property owned by the kernel or udevd
(DEVPATH,SEQNUM,MODALIAS, ...) drops the whole rule line, not only that key. - Host-managed zoned (ZAC) SATA drives on non-libata transports (mpt3sas, megaraid, smartpqi,
USB SAT) are identified byata_id: theirID_SERIAL,ID_BUSandID_MODELchange, and they get
disk/by-id/ata-*links. The whole-diskscsi-*link is kept by a rule, which also gives libata
ZAC disks an additionalscsi-*link; their partitions get theirscsi-*-part<N>links again with
this release (deviation: systemd's rule covers only whole disks). - ATA drives behind SCSI/ATA translation layers whose sense data has bit 7 of the response code
set (e.g. some SAS HBAs) are identified byata_id: they getID_BUS=ataand
disk/by-id/ata-<model>_<serial>links, and lose thedisk/by-id/scsi-<serial>links (disk and
partitions) that 3.2.14 created. eudev ships no compatibility rule for them. - Helper exit statuses and outputs:
ata_id,cdrom_id,mtd_probeandv4l_idexit 0
silently when the device node vanished (ENODEV, ENXIO, ENOENT;ata_id,mtd_probeandv4l_id
also on ENOMEDIUM);scsi_idexits 1 when it cannot open the device; zoned SCSI disks get
ID_TYPE=zbc.