Red Hat Bugzilla – Bug 1303157
fdisk does not wipe existing signatures before creating partition table
Last modified: 2017-01-17 09:26:38 EST
Description of problem:
If there is a leftover msdos label from an erroneous partition creation, the label prevents VG activation at boot. The VG can be manually activated with 'vgchange -ay'.
Version-Release number of selected component (if applicable):
How reproducible (commands taken from 'history'; data gathering commands omitted):
- Create initial lvm structure, format, add to fstab, reboot.
20 pvcreate /dev/sdb
21 vgcreate testvg /dev/sdb
22 lvcreate -n testlv -l +100%FREE testvg
23 mkfs.ext4 /dev/mapper/testvg-testlv
27 vi /etc/fstab
28 mkdir /test
- Create partition table, then remove.
31 fdisk /dev/sdb
- Remove partition table.
33 fdisk /dev/sdb
- Reboot. At this point the job will fail for testvg/testlv; drops to maintenance.
systemd: Job dev-mapper-testvg\x2dtestlv.device/start timed out
systemd:Timed out waiting for device dev-mapper-testvg\x2dtestlv.device
systemd:Dependency failed for File System Check on /dev/mapper/testvg-testlv
systemd:Job systemd-fsck@dev-mapper-testvg\x2dtestlv.service/start failed with result 'dependency'
systemd:Job dev-mapper-testvg\x2dtestlv.device/start failed with result 'timeout
System goes into maintenance mode at reboot if lvmetad is enabled.
In my opinion, we should not fail. The partition table is gone, so we should be able to pick up the PV and allow activation. At a minimum we should be consistent. Either the VG should activate or it shouldn't. If it doesn't, perhaps failed activation should be coupled with an alert that a label exists on the PV?
- add rd.lvm.lv=testvg/testlv to grub line
- comment filesystem from fstab, activate from runlevel 3
- set use_lvmetad to 0 in lvm.conf
I have a reproducer, so if any help is needed at all, please let me know. I'd be glad to help where I can.
The reason here is that blkid gives preference to partition table over LVM2 PV signature if both are found on disk.
When using lvmetad, LVM2 is in event-based autoactivation mode which means it runs "pvscan --cache -aay" (via lvm2-pvscan@major:minor.service) for each device which is identified by blkid as LVM2_member. The "pvscan --cache -aay" informs lvmetad about new PVs that are present in the system and if it finds that this is the last PVs which makes the VG complete, it activates the whole VG. If the device is not identified as LVM2_member by blkid, then there's no "pvscan" triggered and hence lvmetad doesn't know about such device at all and also it can't do any autoactivation.
The exact problem here is mixing two different signatures which should be always avoided. For example, lvm2 wipes all existing signatures before creating a its own PV signature on that device. I suppose fdisk should be doing the same and it should either reject creation of partition tables if it finds that there's already an existing signature or it should provide a way to wipe it. LVM2 uses libblkid to do this detection of existing signatures on device before it continues to create its own signature.
Simply, it's not correct to mix several signatures. You would need to remove partition table completely for this to work again (the sequence you reported "d 1 w" just removes the partition, not the partition table).
You can also check the output of:
blkid -o udev <path_to_device>
# blkid -o udev /dev/sda
# wipefs /dev/sda
0x1fe dos [partition table]
0x218 LVM2_member [raid]
You will see that blkid gives you only one signature - blkid needs to return only one type to identify the device deterministically. The wipefs will list all signatures found. If more signatures are found, most of the time it's a pure bug - you can't even be sure that one signature is not overlapping part of another signature and hence damaging it.
As said above, if we want to go the safe way, we either need:
A: fdisk to do signature detection and possible wiping before it creates its own signatures (or it should just call "wipefs -a <path_to_device>" before it creates its own signature)
B: blkid to return with an error if more signatures are found when using "blkid -o udev" which is used in udev to export information about device. Or if it finds partition table (without any partitions defined) and LVM2 signature, it should give preference to LVM2.
Parted is better here - when it creates partition tabel, it also wipes LVM2 PV signature, hence we end up with one signature and deterministic state of the device, not mixing the two signatures together.
Note: the reason this scenario works without lvmetad is because in this case, we do not rely on blkid to tell us whether this is a PV or not - LVM commands do the scan on their own and if it sees dos partition table *without any partitions* defined, it just ignores that and it gives preference to the LVM PV signature it finds next. If there was at least one partition defined, LVM would filter such device out and it would consider such device as not being able to hold PV signature at the same time. So that's for completeness why this doesn't work with lvmetad (where we rely on blkid result within udev rule execution) and why it works without it (where LVM2 scans for partition table itself).
If this were changed, would cfdisk be changed as well? I checked sfdisk and couldn't find any option to delete partitions.
Are there other partitioning tools that should be included?
(In reply to John Pittman from comment #5)
> If this were changed, would cfdisk be changed as well? I checked sfdisk and
> couldn't find any option to delete partitions.
Yes, if cfdisk doesn't do that already, it should as well...
The current fdisk upstream prints warning and recommends wipefs if the device already contains a filesystem/LVM/ signature. It does not delete foreign signatures automatically -- maybe we can enable it.
I don't plan to implement into libblkid any policies "if PT without partitions then prefer LVM" ... that's too complex and too crazy. It's better to force people to keep their disk without mess and wipe devices in partitioning tools and mkfs-like utils.
Note for comment #0, delete all partitions does not mean that whole partition table is gone. It's pretty valid use-case to have empty partition table without partitions.
Note that the current fdisk and cfdisk upstream wipe "bootbits" (area before the first sector).
Since v2.28 fdisks wipe all device when executed in interactive mode and a new command line option --wipe=auto|never|always controls this behaviour.
Unfortunately, this cannot be backported to RHEL7.
Closing. fdisk has been improved in upstream tree, but it change is too invasive to backport to RHEL7.