- Package:
- initscripts
- Source:
- initscripts
- Submitter:
- Alex Volkov
- Date:
- 2024-04-18 12:54:03 UTC
- Severity:
- normal
- Tags:
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.
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
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
"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
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.
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.
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
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
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.
Well, looks like it's already fixed in lvm2 upstream recently. https://gitlab.com/lvmteam/lvm2/-/commit/eb4f744820832aff3d6da1bba14f12e91a5b3535
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