#1069182 initscripts: udev initscript SHOULD NOT clear the udev database at startup

Package:
initscripts
Source:
initscripts
Submitter:
Alex Volkov
Date:
2024-04-18 12:54:03 UTC
Severity:
normal
Tags:
#1069182#5
Date:
2024-04-17 12:25:08 UTC
From:
To:
Dear Maintainer,

I don't use systemd and for quite some time I struggled with strange udev
behaviour — it doesn't properly enumerate any LVM volumes, their records
looking like this (note "UDEV_DISABLE" properties):

P: /devices/virtual/block/dm-0
M: dm-0
R: 0
U: block
T: disk
D: b 254:0
N: dm-0
L: 0
Q: 16
E: DEVPATH=/devices/virtual/block/dm-0
E: DEVNAME=/dev/dm-0
E: DEVTYPE=disk
E: DISKSEQ=16
E: MAJOR=254
E: MINOR=0
E: SUBSYSTEM=block
E: USEC_INITIALIZED=5035098
E: DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG=1
E: DM_UDEV_DISABLE_DISK_RULES_FLAG=1
E: DM_UDEV_DISABLE_OTHER_RULES_FLAG=1

This, in turn, leads to problems with apps which rely onto udev for listing
disk devices, e. g. Dolphin doesn't show them in its "Devices" menu, e2scrub
can't find them as it takes the info about filesystems from udev, etc. (See,
for example, the bug #986231 I filed TWO years ago about lsblk being unable to
determine a filesystem type.)

Investigating the issue, I found that the culprit is the obscure procedure
which udev uses to enumerate device-mapper-controlled drives, see, for
example, discussions here:

https://lore.kernel.org/all/CANnVG6mMTcRkWQEEhZSEELfyGHqNkGPx2LmdR9NS+-wkAieGSw@mail.gmail.com/T/

or here:

https://bugs.gentoo.org/330651

In the latter a maintainer specifically notes that "we require the udev
database to be kept even from initrd stage" to avoid disabling drives by
the corresponding udev rule.

Now, /etc/init.d/udev for some reason does this in its start clause:

===
   135      # clean up parts of the database created by the initramfs udev
   136      udevadm info --cleanup-db
===

Commenting this line out makes things as they should be:

P: /devices/virtual/block/dm-0
M: dm-0
R: 0
U: block
T: disk
D: b 254:0
N: dm-0
L: 0
S: vg0/root
S: disk/by-label/ROOT
S: disk/by-id/dm-uuid-LVM-veczrDUWOJiXGZ3UJouWnb0VybkpMNR7UmTRamNQy5hTnaN6d5OK75lJwPX9DLYW
S: mapper/vg0-root
S: disk/by-id/dm-name-vg0-root
S: disk/by-uuid/74945b3e-925a-418e-92bd-6cd67e393144
Q: 16
E: DEVPATH=/devices/virtual/block/dm-0
E: DEVNAME=/dev/dm-0
E: DEVTYPE=disk
E: DISKSEQ=16
E: MAJOR=254
E: MINOR=0
E: SUBSYSTEM=block
E: USEC_INITIALIZED=3712867
E: DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG=1
E: DM_UDEV_PRIMARY_SOURCE_FLAG=1
E: DM_UDEV_RULES=1
E: DM_UDEV_RULES_VSN=2
E: DM_ACTIVATION=1
E: DM_NAME=vg0-root
E: DM_UUID=LVM-veczrDUWOJiXGZ3UJouWnb0VybkpMNR7UmTRamNQy5hTnaN6d5OK75lJwPX9DLYW
E: DM_SUSPENDED=0
E: DM_VG_NAME=vg0
E: DM_LV_NAME=root
E: ID_FS_LABEL=ROOT


Note that systemd-based systems are not affected, as they seemingly don't
relate to the initrd scripts for starting udev. (Which can raise certain
suspicions as for WHY this is done in the script *provided by systemd* for
non-systemd-based systems, but oh well.)

If there is a valid reason for cleaning the database, the issue needs to be
researched further, of course, but to me deleting the offending line fixes
everything.

#1069182#8
Date:
2024-04-17 13:53:08 UTC
From:
To:
Alex,

Many thanks for this and your detailed analysis.

 [...]

I suspect the original reason for this will be hard to track down. Git blaming
d/udev.init from systemd 254.1-3 shows those lines as being merged in 2013 from
udev 175-7[1].

Quite.

Dear systemd maintainers,

Do you have any insight into why clearing the initramfs udev db might have been
or might still be required? Or any unanticipated effects of not doing so?

Thanks

Mark

[1]  https://salsa.debian.org/systemd-team/systemd/-/commit/b56f8637a1e03ac6a45af7820287159df9b506b9

#1069182#13
Date:
2024-04-17 14:19:04 UTC
From:
To:
Boian,

I notice Devuan's eudev initscript contains the same[1], presumably with the
same origin. Do you have any thoughts on its purpose or necessity?

Thanks

Mark

[1]  https://git.devuan.org/devuan/eudev/src/branch/suites/unstable/debian/eudev.init#L160

#1069182#18
Date:
2024-04-17 16:14:58 UTC
From:
To:
"If udev is used in initrd, we require the udev init script to not remove
the existing udev database so we can reuse the information stored at the time
of device activation in the initrd."

https://salsa.debian.org/lvm-team/lvm2/-/blob/main/udev/10-dm.rules.in?ref_type=heads#L81

#1069182#23
Date:
2024-04-17 20:43:46 UTC
From:
To:
So, the issue was raised in 2010:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593625#25

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=590665#20

and the resolution was made that the udev script should NOT delete
the database, which was reflected in udev's ChangeLog (then it was a separate
package yet):

===
udev (167-1) unstable; urgency=medium

  * New upstream release.
  * Do not delete the database created by the initramfs udev, for the
    benefit of newer versions of lvm. This Breaks dmsetup << 2.02.84-1.
    See #590665 and #593625.
  * Switch to the gir 1.2 format, courtesy of Emilio Pozuelo Monfort.
    (Closes: #620335)
  * Actually enable support for persistent names of virtio block devices
    introduced in 166-1. (Closes: #617658)
  * Changed net.agent to invoke a systemd event instead of running
    ifup when systemd is active. (Closes: #610871)
  * Clarify in README.Debian that $NEED_PERSISTENT_NET must be exported
    there as well. (Closes: #618420)
  * The udev package becomes Multi-Arch: foreign.

#1069182#28
Date:
2024-04-17 21:17:59 UTC
From:
To:
So, in 166-1 the base was cleaned like this:

===
	# and clean up the database of the initramfs udev
	rm -rf /dev/.udev/
===
(https://snapshot.debian.org/archive/debian/20110213T031437Z/pool/main/u/udev/udev_166-1.diff.gz)

Later in 167-1 the effort was made to clean-up only the *failed* records:

===
	# and clean up part of the database of the initramfs udev
	rm -rf /dev/.udev/failed/ /run/udev/failed/
===
(https://snapshot.debian.org/archive/debian/20110404T153642Z/pool/main/u/udev/udev_167-1.diff.gz)

But with the next upstream release, which probably got rid of "failed"
directory, and introduced the --cleanup-db parameter, the clean-up was
reverted back to "kill-them-all" approach, forgetting why it had been fixed:

===
	# and clean up part of the database of the initramfs udev
	udevadm info --cleanup-db
===
(https://snapshot.debian.org/archive/debian/20110424T032258Z/pool/main/u/udev/udev_168-1.debian.tar.gz)

IDK, maybe in those times --cleanup-db really didn't erase the whole database,
but only the failed records? Who knows.

#1069182#31
Date:
2024-04-18 06:38:18 UTC
From:
To:
Alex,

Thanks for your continued research into this.

The upstream 168 changelog is informative (edited for relevant parts):

Summary of changes from v167 to v168
============================================

Kay Sievers (35):
      udevadm: info --cleanup-db
      "db_persist=" -> "db_persist"
      require explicit "db_persist" to exclude device info from --db-cleanup

It is somewaht opaque, but the relevant commits appear to be in the current
systemd git[1].

Does this mean that dm mapper should set db_persist in the initramfs?

Mark

[1]  https://github.com/search?q=repo%3Asystemd%2Fsystemd+db_persist&type=commits

#1069182#34
Date:
2024-04-18 06:49:07 UTC
From:
To:
Or the initramfs generator. AFAICS dracut already does this[1], but I don't
immediately see an equivalent for initramfs-tools.

Are you using initramfs-tools? Does switching to dracut improve the situation?

Mark

[1]  https://codesearch.debian.net/search?q=db_persist+package%3A%5CQdracut%5CE

#1069182#39
Date:
2024-04-18 09:24:06 UTC
From:
To:
Wow. I knew there's something in this transition to --db-cleanup.

More like it's actually needs to be set by the corresponding udev rule in lvm2
package (which does all that device-mapper devices detection). I tried adding
the corresponding OPTIONS+="db_persist" line into 55-dm.rules file and it
worked as intended. I will report the bug to lvm2.

#1069182#44
Date:
2024-04-18 09:35:01 UTC
From:
To:
Well, looks like it's already fixed in lvm2 upstream recently.

https://gitlab.com/lvmteam/lvm2/-/commit/eb4f744820832aff3d6da1bba14f12e91a5b3535

#1069182#49
Date:
2024-04-18 12:50:38 UTC
From:
To:
Control: reassign -1 lvm2

I think we can just reassign this one.

Dear lvm2 maintainers,

We have been investigating why devices discovered by the initramfs were being
cleaned by /etc/init.d/udev. The udev initscript runs

 udevadm info --cleanup-db.

It appears to be the responsibility of devices that should not be cleaned to set
db_persist in their setup rule.

There appears to be a recent upstream lvm2 commit to address this[1].

Thanks

Mark

[1]  https://gitlab.com/lvmteam/lvm2/-/commit/eb4f744820832aff3d6da1bba14f12e91a5b3535